func SendBackwardValue(ctx context.Context, key, val string) (ok bool) {
	if p, ok := ctx.Value(bwCtxKeySend).(*bwCtxValue); ok {
		p.set(key, val)
		return true
	}
	return
}
SendBackwardValue sets a key-value pair into the context for sending to
a remote endpoint.
Note that the values can not be retrieved with `RecvBackwardValue` from
the same context.
package metainfo
import (
	"context"
	"sync"
)
type bwCtxKeyType int
const (
	bwCtxKeySend bwCtxKeyType = iota
	bwCtxKeyRecv
)
type bwCtxValue struct {
	sync.RWMutex
	kvs map[string]string
}
func newBackwardCtxValues() *bwCtxValue {
	return &bwCtxValue{
		kvs: make(map[string]string),
	}
}
func (p *bwCtxValue) get(k string) (v string, ok bool) {
	p.RLock()
	v, ok = p.kvs[k]
	p.RUnlock()
	return
}
func (p *bwCtxValue) getAll() (m map[string]string) {
	p.RLock()
	if cnt := len(p.kvs); cnt > 0 {
		m = make(map[string]string, cnt)
		for k, v := range p.kvs {
			m[k] = v
		}
	}
	p.RUnlock()
	return
}
func (p *bwCtxValue) set(k, v string) {
	p.Lock()
	p.kvs[k] = v
	p.Unlock()
}
func (p *bwCtxValue) setMany(kvs []string) {
	p.Lock()
	for i := 0; i < len(kvs); i += 2 {
		p.kvs[kvs[i]] = kvs[i+1]
	}
	p.Unlock()
}
func (p *bwCtxValue) setMap(kvs map[string]string) {
	p.Lock()
	for k, v := range kvs {
		p.kvs[k] = v
	}
	p.Unlock()
}
func WithBackwardValues(ctx context.Context) context.Context {
	if _, ok := ctx.Value(bwCtxKeyRecv).(*bwCtxValue); ok {
		return ctx
	}
	ctx = context.WithValue(ctx, bwCtxKeyRecv, newBackwardCtxValues())
	return ctx
}
func RecvBackwardValue(ctx context.Context, key string) (val string, ok bool) {
	if p, exist := ctx.Value(bwCtxKeyRecv).(*bwCtxValue); exist {
		val, ok = p.get(key)
	}
	return
}
func RecvAllBackwardValues(ctx context.Context) (m map[string]string) {
	if p, ok := ctx.Value(bwCtxKeyRecv).(*bwCtxValue); ok {
		return p.getAll()
	}
	return
}
func SetBackwardValue(ctx context.Context, key, val string) (ok bool) {
	if p, ok := ctx.Value(bwCtxKeyRecv).(*bwCtxValue); ok {
		p.set(key, val)
		return true
	}
	return false
}
func SetBackwardValues(ctx context.Context, kvs ...string) (ok bool) {
	if l := len(kvs); l > 0 && l%2 == 0 {
		if p, ok := ctx.Value(bwCtxKeyRecv).(*bwCtxValue); ok {
			p.setMany(kvs)
			return true
		}
	}
	return
}
func SetBackwardValuesFromMap(ctx context.Context, kvs map[string]string) (ok bool) {
	if l := len(kvs); l > 0 {
		if p, ok := ctx.Value(bwCtxKeyRecv).(*bwCtxValue); ok {
			p.setMap(kvs)
			return true
		}
	}
	return
}
func WithBackwardValuesToSend(ctx context.Context) context.Context {
	if _, ok := ctx.Value(bwCtxKeySend).(*bwCtxValue); ok {
		return ctx
	}
	ctx = context.WithValue(ctx, bwCtxKeySend, newBackwardCtxValues())
	return ctx
}