package micro import ( "context" "time" "github.com/micro/cli/v2" "github.com/micro/go-micro/v2/broker" "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/client/selector" "github.com/micro/go-micro/v2/config/cmd" "github.com/micro/go-micro/v2/debug/trace" "github.com/micro/go-micro/v2/registry" "github.com/micro/go-micro/v2/server" "github.com/micro/go-micro/v2/transport" ) type Options struct { Broker broker.Broker Cmd cmd.Cmd Client client.Client Server server.Server Registry registry.Registry Transport transport.Transport // Before and After funcs BeforeStart []func() error BeforeStop []func() error AfterStart []func() error AfterStop []func() error // Other options for implementations of the interface // can be stored in a context Context context.Context Signal bool } func newOptions(opts ...Option) Options { opt := Options{ Broker: broker.DefaultBroker, Cmd: cmd.DefaultCmd, Client: client.DefaultClient, Server: server.DefaultServer, Registry: registry.DefaultRegistry, Transport: transport.DefaultTransport, Context: context.Background(), Signal: true, } for _, o := range opts { o(&opt) } return opt } func Broker(b broker.Broker) Option { return func(o *Options) { o.Broker = b // Update Client and Server o.Client.Init(client.Broker(b)) o.Server.Init(server.Broker(b)) } } func Cmd(c cmd.Cmd) Option { return func(o *Options) { o.Cmd = c } } func Client(c client.Client) Option { return func(o *Options) { o.Client = c } } // Context specifies a context for the service. // Can be used to signal shutdown of the service. // Can be used for extra option values. func Context(ctx context.Context) Option { return func(o *Options) { o.Context = ctx } } // HandleSignal toggles automatic installation of the signal handler that // traps TERM, INT, and QUIT. Users of this feature to disable the signal // handler, should control liveness of the service through the context. func HandleSignal(b bool) Option { return func(o *Options) { o.Signal = b } } func Server(s server.Server) Option { return func(o *Options) { o.Server = s } } // Registry sets the registry for the service // and the underlying components func Registry(r registry.Registry) Option { return func(o *Options) { o.Registry = r // Update Client and Server o.Client.Init(client.Registry(r)) o.Server.Init(server.Registry(r)) // Update Broker o.Broker.Init(broker.Registry(r)) } } // Tracer sets the tracer for the service func Tracer(t trace.Tracer) Option { return func(o *Options) { o.Server.Init(server.Tracer(t)) } } // Selector sets the selector for the service client func Selector(s selector.Selector) Option { return func(o *Options) { o.Client.Init(client.Selector(s)) } } // Transport sets the transport for the service // and the underlying components func Transport(t transport.Transport) Option { return func(o *Options) { o.Transport = t // Update Client and Server o.Client.Init(client.Transport(t)) o.Server.Init(server.Transport(t)) } } // Convenience options // Address sets the address of the server func Address(addr string) Option { return func(o *Options) { o.Server.Init(server.Address(addr)) } } // Name of the service func Name(n string) Option { return func(o *Options) { o.Server.Init(server.Name(n)) } } // Version of the service func Version(v string) Option { return func(o *Options) { o.Server.Init(server.Version(v)) } } // Metadata associated with the service func Metadata(md map[string]string) Option { return func(o *Options) { o.Server.Init(server.Metadata(md)) } } func Flags(flags ...cli.Flag) Option { return func(o *Options) { o.Cmd.App().Flags = append(o.Cmd.App().Flags, flags...) } } func Action(a func(*cli.Context) error) Option { return func(o *Options) { o.Cmd.App().Action = a } } // RegisterTTL specifies the TTL to use when registering the service func RegisterTTL(t time.Duration) Option { return func(o *Options) { o.Server.Init(server.RegisterTTL(t)) } } // RegisterInterval specifies the interval on which to re-register func RegisterInterval(t time.Duration) Option { return func(o *Options) { o.Server.Init(server.RegisterInterval(t)) } } // WrapClient is a convenience method for wrapping a Client with // some middleware component. A list of wrappers can be provided. // Wrappers are applied in reverse order so the last is executed first. func WrapClient(w ...client.Wrapper) Option { return func(o *Options) { // apply in reverse for i := len(w); i > 0; i-- { o.Client = w[i-1](o.Client) } } } // WrapCall is a convenience method for wrapping a Client CallFunc func WrapCall(w ...client.CallWrapper) Option { return func(o *Options) { o.Client.Init(client.WrapCall(w...)) } } // WrapHandler adds a handler Wrapper to a list of options passed into the server func WrapHandler(w ...server.HandlerWrapper) Option { return func(o *Options) { var wrappers []server.Option for _, wrap := range w { wrappers = append(wrappers, server.WrapHandler(wrap)) } // Init once o.Server.Init(wrappers...) } } // WrapSubscriber adds a subscriber Wrapper to a list of options passed into the server func WrapSubscriber(w ...server.SubscriberWrapper) Option { return func(o *Options) { var wrappers []server.Option for _, wrap := range w { wrappers = append(wrappers, server.WrapSubscriber(wrap)) } // Init once o.Server.Init(wrappers...) } } // Before and Afters func BeforeStart(fn func() error) Option { return func(o *Options) { o.BeforeStart = append(o.BeforeStart, fn) } } func BeforeStop(fn func() error) Option { return func(o *Options) { o.BeforeStop = append(o.BeforeStop, fn) } } func AfterStart(fn func() error) Option { return func(o *Options) { o.AfterStart = append(o.AfterStart, fn) } } func AfterStop(fn func() error) Option { return func(o *Options) { o.AfterStop = append(o.AfterStop, fn) } }