WIP mrpc refactor to use Request/ResponseWriter/Response, not sure if I like it or not
This commit is contained in:
parent
dfa32aa6d9
commit
0460a7745c
@ -27,6 +27,9 @@ func (d Debug) Copy() Debug {
|
|||||||
// Set returns a copy of the Debug instance with the key set to the value within
|
// Set returns a copy of the Debug instance with the key set to the value within
|
||||||
// the given namespace.
|
// the given namespace.
|
||||||
func (d Debug) Set(ns, key string, val interface{}) Debug {
|
func (d Debug) Set(ns, key string, val interface{}) Debug {
|
||||||
|
if d == nil {
|
||||||
|
return Debug{ns: map[string]interface{}{key, val}}
|
||||||
|
}
|
||||||
d = d.Copy()
|
d = d.Copy()
|
||||||
if d[ns] == nil {
|
if d[ns] == nil {
|
||||||
d[ns] = map[string]interface{}{}
|
d[ns] = map[string]interface{}{}
|
||||||
|
110
mrpc/mrpc.go
110
mrpc/mrpc.go
@ -15,38 +15,51 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler is a type which serves RPC calls. For each incoming Call the ServeRPC
|
// Request TODO
|
||||||
// method is called, and the return from the method is used as the response. If
|
type Request struct {
|
||||||
// an error is returned the response return is ignored.
|
Context context.Context
|
||||||
|
|
||||||
|
// The name of the RPC method being called.
|
||||||
|
Method string
|
||||||
|
|
||||||
|
// Unmarshal takes in a pointer and unmarshals the RPC request's arguments
|
||||||
|
// into it. The properties of the unmarshaling are dependent on the
|
||||||
|
// underlying implementation of the protocol.
|
||||||
|
//
|
||||||
|
// This should only be called within ServeRPC.
|
||||||
|
Unmarshal func(interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResponseWriter TODO
|
||||||
|
type ResponseWriter struct {
|
||||||
|
Context context.Context
|
||||||
|
|
||||||
|
Respond func(interface{})
|
||||||
|
Err func(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reponse TODO
|
||||||
|
type Response struct {
|
||||||
|
Context context.Context
|
||||||
|
Unmarshal func(interface{}) error
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler is a type which serves RPC calls. For each incoming Requests the
|
||||||
|
// ServeRPC method is called with a ResponseWriter which will write the call's
|
||||||
|
// response back to the client.
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
ServeRPC(Call) (interface{}, error)
|
ServeRPC(Request, *ResponseWriter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandlerFunc can be used to wrap an individual function which fits the
|
// HandlerFunc can be used to wrap an individual function which fits the
|
||||||
// ServeRPC signature, and use that function as a Handler
|
// ServeRPC signature, and use that function as a Handler
|
||||||
type HandlerFunc func(Call) (interface{}, error)
|
type HandlerFunc func(Request, *ResponseWriter)
|
||||||
|
|
||||||
// ServeRPC implements the method for the Handler interface by calling the
|
// ServeRPC implements the method for the Handler interface by calling the
|
||||||
// underlying function
|
// underlying function
|
||||||
func (hf HandlerFunc) ServeRPC(c Call) (interface{}, error) {
|
func (hf HandlerFunc) ServeRPC(r Request, rw *ResponseWriter) {
|
||||||
return hf(c)
|
hf(r, rw)
|
||||||
}
|
|
||||||
|
|
||||||
// Call is passed into the ServeRPC method and contains all information about
|
|
||||||
// the incoming RPC call which is being made
|
|
||||||
type Call struct {
|
|
||||||
// Context relating to the call. May contain extra metadata/debug
|
|
||||||
// information, be used for further interaction with the underlying
|
|
||||||
// protocol, or be used for timeout/disconnect cancelation.
|
|
||||||
Context context.Context
|
|
||||||
|
|
||||||
// The name of the RPC method being called
|
|
||||||
Method string
|
|
||||||
|
|
||||||
// UnmarshalArgs takes in a pointer and unmarshals the RPC call's arguments
|
|
||||||
// into it. The properties of the unmarshaling are dependent on the
|
|
||||||
// underlying implementation of the codec.
|
|
||||||
UnmarshalArgs func(interface{}) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client is an entity which can perform RPC calls against a remote endpoint.
|
// Client is an entity which can perform RPC calls against a remote endpoint.
|
||||||
@ -55,29 +68,28 @@ type Call struct {
|
|||||||
// unmarshaled according to Client's implementation. args will be marshaled and
|
// unmarshaled according to Client's implementation. args will be marshaled and
|
||||||
// sent to the remote endpoint according to Client's implementation.
|
// sent to the remote endpoint according to Client's implementation.
|
||||||
type Client interface {
|
type Client interface {
|
||||||
CallRPC(ctx context.Context, res interface{}, method string, args interface{}) error
|
CallRPC(ctx context.Context, method string, args interface{}) Response
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientFunc can be used to wrap an individual function which fits the CallRPC
|
// ClientFunc can be used to wrap an individual function which fits the CallRPC
|
||||||
// signature, and use that function as a Client
|
// signature, and use that function as a Client
|
||||||
type ClientFunc func(context.Context, interface{}, string, interface{}) error
|
type ClientFunc func(context.Context, string, interface{}) Response
|
||||||
|
|
||||||
// CallRPC implements the method for the Client interface by calling the
|
// CallRPC implements the method for the Client interface by calling the
|
||||||
// underlying function
|
// underlying function
|
||||||
func (cf ClientFunc) CallRPC(
|
func (cf ClientFunc) CallRPC(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
res interface{},
|
|
||||||
method string,
|
method string,
|
||||||
args interface{},
|
args interface{},
|
||||||
) error {
|
) Response {
|
||||||
return cf(ctx, res, method, args)
|
return cf(ctx, method, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReflectClient returns a Client whose CallRPC method will use reflection to
|
// ReflectClient returns a Client whose CallRPC method will use reflection to
|
||||||
// call the given Handler's ServeRPC method directly, using reflect.Value's Set
|
// call the given Handler's ServeRPC method directly, using reflect.Value's Set
|
||||||
// method to copy CallRPC's args parameter into UnmarshalArgs' receiver
|
// method to copy CallRPC's args parameter into the Request's Unmarshal method's
|
||||||
// parameter, and similarly to copy the result from ServeRPC into CallRPC's
|
// receiver parameter, and similarly to copy the result from ServeRPC into
|
||||||
// receiver parameter.
|
// the Response's Unmarshal method's receiver parameter.
|
||||||
func ReflectClient(h Handler) Client {
|
func ReflectClient(h Handler) Client {
|
||||||
into := func(dst, src interface{}) error {
|
into := func(dst, src interface{}) error {
|
||||||
dstV, srcV := reflect.ValueOf(dst), reflect.ValueOf(src)
|
dstV, srcV := reflect.ValueOf(dst), reflect.ValueOf(src)
|
||||||
@ -91,21 +103,33 @@ func ReflectClient(h Handler) Client {
|
|||||||
|
|
||||||
return ClientFunc(func(
|
return ClientFunc(func(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
resInto interface{},
|
|
||||||
method string,
|
method string,
|
||||||
args interface{},
|
args interface{},
|
||||||
) error {
|
) Response {
|
||||||
c := Call{
|
req := Request{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Method: method,
|
Method: method,
|
||||||
UnmarshalArgs: func(i interface{}) error { return into(i, args) },
|
Unmarshal: func(i interface{}) error { return into(i, args) },
|
||||||
|
}
|
||||||
|
var res interface{}
|
||||||
|
var resErr error
|
||||||
|
rw := ResponseWriter{
|
||||||
|
Context: context.Background(),
|
||||||
|
Respond: func(i interface{}) { res = i },
|
||||||
|
Err: func(err error) { resErr = err },
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.ServeRPC(c)
|
h.ServeRPC(req, &rw)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return into(resInto, res)
|
return Response{
|
||||||
|
Context: rw.Context,
|
||||||
|
Unmarshal: func(i interface{}) error {
|
||||||
|
if resErr != nil {
|
||||||
|
return resErr
|
||||||
|
}
|
||||||
|
return into(i, res)
|
||||||
|
},
|
||||||
|
Err: resErr,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user