func Peer(p *peer.Peer) CallOption {
	return afterCall(func(c *callInfo) {
		if c.stream != nil {
			if x, ok := peer.FromContext(c.stream.Context()); ok {
				*p = *x
			}
		}
	})
}
Peer returns a CallOption that retrieves peer information for a
unary RPC.
package grpc
import (
	"bytes"
	"compress/gzip"
	"encoding/binary"
	"io"
	"io/ioutil"
	"math"
	"sync"
	"time"
	"golang.org/x/net/context"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/encoding"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/peer"
	"google.golang.org/grpc/stats"
	"google.golang.org/grpc/status"
	"google.golang.org/grpc/transport"
)
type Compressor interface {
	Do(w io.Writer, p []byte) error
	Type() string
}
type gzipCompressor struct {
	pool sync.Pool
}
func NewGZIPCompressor() Compressor {
	return &gzipCompressor{
		pool: sync.Pool{
			New: func() interface{} {
				return gzip.NewWriter(ioutil.Discard)
			},
		},
	}
}
func (c *gzipCompressor) Do(w io.Writer, p []byte) error {
	z := c.pool.Get().(*gzip.Writer)
	defer c.pool.Put(z)
	z.Reset(w)
	if _, err := z.Write(p); err != nil {
		return err
	}
	return z.Close()
}
func (c *gzipCompressor) Type() string {
	return "gzip"
}
type Decompressor interface {
	Do(r io.Reader) ([]byte, error)
	Type() string
}
type gzipDecompressor struct {
	pool sync.Pool
}
func NewGZIPDecompressor() Decompressor {
	return &gzipDecompressor{}
}
func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
	var z *gzip.Reader
	switch maybeZ := d.pool.Get().(type) {
	case nil:
		newZ, err := gzip.NewReader(r)
		if err != nil {
			return nil, err
		}
		z = newZ
	case *gzip.Reader:
		z = maybeZ
		if err := z.Reset(r); err != nil {
			d.pool.Put(z)
			return nil, err
		}
	}
	defer func() {
		z.Close()
		d.pool.Put(z)
	}()
	return ioutil.ReadAll(z)
}
func (d *gzipDecompressor) Type() string {
	return "gzip"
}
type callInfo struct {
	compressorType        string
	failFast              bool
	stream                *transport.Stream
	traceInfo             traceInfo  
	maxReceiveMessageSize *int
	maxSendMessageSize    *int
	creds                 credentials.PerRPCCredentials
}
func defaultCallInfo() *callInfo {
	return &callInfo{failFast: true}
}
type CallOption interface {
	before(*callInfo) error
	after(*callInfo)
}
type EmptyCallOption struct{}
func (EmptyCallOption) before(*callInfo) error { return nil }
func (EmptyCallOption) after(*callInfo)        {}
type beforeCall func(c *callInfo) error
func (o beforeCall) before(c *callInfo) error { return o(c) }
func (o beforeCall) after(c *callInfo)        {}
type afterCall func(c *callInfo)
func (o afterCall) before(c *callInfo) error { return nil }
func (o afterCall) after(c *callInfo)        { o(c) }
func Header(md *metadata.MD) CallOption {
	return afterCall(func(c *callInfo) {
		if c.stream != nil {
			*md, _ = c.stream.Header()
		}
	})
}
func Trailer(md *metadata.MD) CallOption {
	return afterCall(func(c *callInfo) {
		if c.stream != nil {
			*md = c.stream.Trailer()
		}
	})
}