replace wrappers with hooks
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
@@ -44,6 +44,17 @@ type Client interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
type (
|
||||
FuncCall func(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error
|
||||
HookCall func(next FuncCall) FuncCall
|
||||
FuncStream func(ctx context.Context, req Request, opts ...CallOption) (Stream, error)
|
||||
HookStream func(next FuncStream) FuncStream
|
||||
FuncPublish func(ctx context.Context, msg Message, opts ...PublishOption) error
|
||||
HookPublish func(next FuncPublish) FuncPublish
|
||||
FuncBatchPublish func(ctx context.Context, msg []Message, opts ...PublishOption) error
|
||||
HookBatchPublish func(next FuncBatchPublish) FuncBatchPublish
|
||||
)
|
||||
|
||||
// Message is the interface for publishing asynchronously
|
||||
type Message interface {
|
||||
Topic() string
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNewClientCallOptions(t *testing.T) {
|
||||
var flag bool
|
||||
w := func(fn CallFunc) CallFunc {
|
||||
flag = true
|
||||
return fn
|
||||
}
|
||||
c := NewClientCallOptions(NewClient(),
|
||||
WithAddress("127.0.0.1"),
|
||||
WithCallWrapper(w),
|
||||
WithRequestTimeout(1*time.Millisecond),
|
||||
WithRetries(0),
|
||||
WithBackoff(BackoffInterval(10*time.Millisecond, 100*time.Millisecond)),
|
||||
)
|
||||
_ = c.Call(context.TODO(), c.NewRequest("service", "endpoint", nil), nil)
|
||||
if !flag {
|
||||
t.Fatalf("NewClientCallOptions not works")
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"go.unistack.org/micro/v3/codec"
|
||||
"go.unistack.org/micro/v3/errors"
|
||||
"go.unistack.org/micro/v3/metadata"
|
||||
"go.unistack.org/micro/v3/options"
|
||||
"go.unistack.org/micro/v3/selector"
|
||||
)
|
||||
|
||||
@@ -19,7 +20,11 @@ var DefaultCodecs = map[string]codec.Codec{
|
||||
}
|
||||
|
||||
type noopClient struct {
|
||||
opts Options
|
||||
funcPublish FuncPublish
|
||||
funcBatchPublish FuncBatchPublish
|
||||
funcCall FuncCall
|
||||
funcStream FuncStream
|
||||
opts Options
|
||||
}
|
||||
|
||||
type noopMessage struct {
|
||||
@@ -40,16 +45,14 @@ type noopRequest struct {
|
||||
|
||||
// NewClient returns new noop client
|
||||
func NewClient(opts ...Option) Client {
|
||||
nc := &noopClient{opts: NewOptions(opts...)}
|
||||
// wrap in reverse
|
||||
n := &noopClient{opts: NewOptions(opts...)}
|
||||
|
||||
c := Client(nc)
|
||||
n.funcCall = n.fnCall
|
||||
n.funcStream = n.fnStream
|
||||
n.funcPublish = n.fnPublish
|
||||
n.funcBatchPublish = n.fnBatchPublish
|
||||
|
||||
for i := len(nc.opts.Wrappers); i > 0; i-- {
|
||||
c = nc.opts.Wrappers[i-1](c)
|
||||
}
|
||||
|
||||
return c
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *noopClient) Name() string {
|
||||
@@ -173,6 +176,25 @@ func (n *noopClient) Init(opts ...Option) error {
|
||||
for _, o := range opts {
|
||||
o(&n.opts)
|
||||
}
|
||||
|
||||
n.funcCall = n.fnCall
|
||||
n.funcStream = n.fnStream
|
||||
n.funcPublish = n.fnPublish
|
||||
n.funcBatchPublish = n.fnBatchPublish
|
||||
|
||||
n.opts.Hooks.EachNext(func(hook options.Hook) {
|
||||
switch h := hook.(type) {
|
||||
case HookCall:
|
||||
n.funcCall = h(n.funcCall)
|
||||
case HookStream:
|
||||
n.funcStream = h(n.funcStream)
|
||||
case HookPublish:
|
||||
n.funcPublish = h(n.funcPublish)
|
||||
case HookBatchPublish:
|
||||
n.funcBatchPublish = h(n.funcBatchPublish)
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -185,6 +207,10 @@ func (n *noopClient) String() string {
|
||||
}
|
||||
|
||||
func (n *noopClient) Call(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error {
|
||||
return n.funcCall(ctx, req, rsp, opts...)
|
||||
}
|
||||
|
||||
func (n *noopClient) fnCall(ctx context.Context, req Request, rsp interface{}, opts ...CallOption) error {
|
||||
// make a copy of call opts
|
||||
callOpts := n.opts.CallOptions
|
||||
for _, opt := range opts {
|
||||
@@ -213,11 +239,8 @@ func (n *noopClient) Call(ctx context.Context, req Request, rsp interface{}, opt
|
||||
}
|
||||
|
||||
// make copy of call method
|
||||
hcall := n.call
|
||||
|
||||
// wrap the call in reverse
|
||||
for i := len(callOpts.CallWrappers); i > 0; i-- {
|
||||
hcall = callOpts.CallWrappers[i-1](hcall)
|
||||
hcall := func(ctx context.Context, addr string, req Request, rsp interface{}, opts CallOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// use the router passed as a call option, or fallback to the rpc clients router
|
||||
@@ -316,10 +339,6 @@ func (n *noopClient) Call(ctx context.Context, req Request, rsp interface{}, opt
|
||||
return gerr
|
||||
}
|
||||
|
||||
func (n *noopClient) call(ctx context.Context, addr string, req Request, rsp interface{}, opts CallOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *noopClient) NewRequest(service, endpoint string, req interface{}, opts ...RequestOption) Request {
|
||||
return &noopRequest{service: service, endpoint: endpoint}
|
||||
}
|
||||
@@ -330,6 +349,10 @@ func (n *noopClient) NewMessage(topic string, msg interface{}, opts ...MessageOp
|
||||
}
|
||||
|
||||
func (n *noopClient) Stream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) {
|
||||
return n.funcStream(ctx, req, opts...)
|
||||
}
|
||||
|
||||
func (n *noopClient) fnStream(ctx context.Context, req Request, opts ...CallOption) (Stream, error) {
|
||||
var err error
|
||||
|
||||
// make a copy of call opts
|
||||
@@ -474,10 +497,18 @@ func (n *noopClient) stream(ctx context.Context, addr string, req Request, opts
|
||||
}
|
||||
|
||||
func (n *noopClient) BatchPublish(ctx context.Context, ps []Message, opts ...PublishOption) error {
|
||||
return n.funcBatchPublish(ctx, ps, opts...)
|
||||
}
|
||||
|
||||
func (n *noopClient) fnBatchPublish(ctx context.Context, ps []Message, opts ...PublishOption) error {
|
||||
return n.publish(ctx, ps, opts...)
|
||||
}
|
||||
|
||||
func (n *noopClient) Publish(ctx context.Context, p Message, opts ...PublishOption) error {
|
||||
return n.funcPublish(ctx, p, opts...)
|
||||
}
|
||||
|
||||
func (n *noopClient) fnPublish(ctx context.Context, p Message, opts ...PublishOption) error {
|
||||
return n.publish(ctx, []Message{p}, opts...)
|
||||
}
|
||||
|
||||
@@ -538,6 +569,13 @@ func (n *noopClient) publish(ctx context.Context, ps []Message, opts ...PublishO
|
||||
msgs = append(msgs, &broker.Message{Header: md, Body: body})
|
||||
}
|
||||
|
||||
if len(msgs) == 1 {
|
||||
return n.opts.Broker.Publish(ctx, msgs[0].Header[metadata.HeaderTopic], msgs[0],
|
||||
broker.PublishContext(options.Context),
|
||||
broker.PublishBodyOnly(options.BodyOnly),
|
||||
)
|
||||
}
|
||||
|
||||
return n.opts.Broker.BatchPublish(ctx, msgs,
|
||||
broker.PublishContext(options.Context),
|
||||
broker.PublishBodyOnly(options.BodyOnly),
|
||||
|
||||
35
client/noop_test.go
Normal file
35
client/noop_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testHook struct {
|
||||
f bool
|
||||
}
|
||||
|
||||
func (t *testHook) Publish(fn FuncPublish) FuncPublish {
|
||||
return func(ctx context.Context, msg Message, opts ...PublishOption) error {
|
||||
t.f = true
|
||||
return fn(ctx, msg, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoopHook(t *testing.T) {
|
||||
h := &testHook{}
|
||||
|
||||
c := NewClient(Hooks(HookPublish(h.Publish)))
|
||||
|
||||
if err := c.Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := c.Publish(context.TODO(), c.NewMessage("", nil, MessageContentType("application/octet-stream"))); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !h.f {
|
||||
t.Fatal("hook not works")
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"go.unistack.org/micro/v3/metadata"
|
||||
"go.unistack.org/micro/v3/meter"
|
||||
"go.unistack.org/micro/v3/network/transport"
|
||||
"go.unistack.org/micro/v3/options"
|
||||
"go.unistack.org/micro/v3/register"
|
||||
"go.unistack.org/micro/v3/router"
|
||||
"go.unistack.org/micro/v3/selector"
|
||||
@@ -59,6 +60,9 @@ type Options struct {
|
||||
PoolTTL time.Duration
|
||||
// ContextDialer used to connect
|
||||
ContextDialer func(context.Context, string) (net.Conn, error)
|
||||
// Hooks can be run before broker Publish/BatchPublish and
|
||||
// Subscribe/BatchSubscribe methods
|
||||
Hooks options.Hooks
|
||||
}
|
||||
|
||||
// NewCallOptions creates new call options struct
|
||||
@@ -92,8 +96,6 @@ type CallOptions struct {
|
||||
Address []string
|
||||
// SelectOptions selector options
|
||||
SelectOptions []selector.SelectOption
|
||||
// CallWrappers call wrappers
|
||||
CallWrappers []CallWrapper
|
||||
// StreamTimeout stream timeout
|
||||
StreamTimeout time.Duration
|
||||
// RequestTimeout request timeout
|
||||
@@ -185,7 +187,7 @@ func NewOptions(opts ...Option) Options {
|
||||
options := Options{
|
||||
Context: context.Background(),
|
||||
ContentType: DefaultContentType,
|
||||
Codecs: make(map[string]codec.Codec),
|
||||
Codecs: DefaultCodecs,
|
||||
CallOptions: CallOptions{
|
||||
Context: context.Background(),
|
||||
Backoff: DefaultBackoff,
|
||||
@@ -306,20 +308,6 @@ func Selector(s selector.Selector) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap adds a wrapper to the list of options passed into the client
|
||||
func Wrap(w Wrapper) Option {
|
||||
return func(o *Options) {
|
||||
o.Wrappers = append(o.Wrappers, w)
|
||||
}
|
||||
}
|
||||
|
||||
// WrapCall adds a wrapper to the list of CallFunc wrappers
|
||||
func WrapCall(cw ...CallWrapper) Option {
|
||||
return func(o *Options) {
|
||||
o.CallOptions.CallWrappers = append(o.CallOptions.CallWrappers, cw...)
|
||||
}
|
||||
}
|
||||
|
||||
// Backoff is used to set the backoff function used when retrying Calls
|
||||
func Backoff(fn BackoffFunc) Option {
|
||||
return func(o *Options) {
|
||||
@@ -450,13 +438,6 @@ func WithAddress(a ...string) CallOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithCallWrapper is a CallOption which adds to the existing CallFunc wrappers
|
||||
func WithCallWrapper(cw ...CallWrapper) CallOption {
|
||||
return func(o *CallOptions) {
|
||||
o.CallWrappers = append(o.CallWrappers, cw...)
|
||||
}
|
||||
}
|
||||
|
||||
// WithBackoff is a CallOption which overrides that which
|
||||
// set in Options.CallOptions
|
||||
func WithBackoff(fn BackoffFunc) CallOption {
|
||||
@@ -591,3 +572,10 @@ func RequestContentType(ct string) RequestOption {
|
||||
o.ContentType = ct
|
||||
}
|
||||
}
|
||||
|
||||
// Hooks sets hook runs before action
|
||||
func Hooks(h ...options.Hook) Option {
|
||||
return func(o *Options) {
|
||||
o.Hooks = append(o.Hooks, h...)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user