Update top level init
This commit is contained in:
parent
d705d3fe50
commit
0d50b2eb32
156
cmd/cmd.go
156
cmd/cmd.go
@ -3,15 +3,12 @@ package cmd
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/micro/cli"
|
||||
"github.com/micro/go-micro/broker"
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/registry"
|
||||
@ -20,10 +17,27 @@ import (
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
var (
|
||||
Actions = []func(*cli.Context){}
|
||||
type Cmd interface {
|
||||
// The cli app within this cmd
|
||||
App() *cli.App
|
||||
// Adds options, parses flags and initialise
|
||||
// exits on error
|
||||
Init(opts ...Option)
|
||||
// Options set within this command
|
||||
Options() Options
|
||||
}
|
||||
|
||||
Flags = []cli.Flag{
|
||||
type cmd struct {
|
||||
opts Options
|
||||
app *cli.App
|
||||
}
|
||||
|
||||
type Option func(o *Options)
|
||||
|
||||
var (
|
||||
DefaultCmd = newCmd()
|
||||
|
||||
DefaultFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "server_name",
|
||||
EnvVar: "MICRO_SERVER_NAME",
|
||||
@ -127,19 +141,19 @@ var (
|
||||
},
|
||||
}
|
||||
|
||||
Brokers = map[string]func([]string, ...broker.Option) broker.Broker{
|
||||
DefaultBrokers = map[string]func([]string, ...broker.Option) broker.Broker{
|
||||
"http": broker.NewBroker,
|
||||
}
|
||||
|
||||
Registries = map[string]func([]string, ...registry.Option) registry.Registry{
|
||||
DefaultRegistries = map[string]func([]string, ...registry.Option) registry.Registry{
|
||||
"consul": registry.NewRegistry,
|
||||
}
|
||||
|
||||
Selectors = map[string]func(...selector.Option) selector.Selector{
|
||||
DefaultSelectors = map[string]func(...selector.Option) selector.Selector{
|
||||
"random": selector.NewSelector,
|
||||
}
|
||||
|
||||
Transports = map[string]func([]string, ...transport.Option) transport.Transport{
|
||||
DefaultTransports = map[string]func([]string, ...transport.Option) transport.Transport{
|
||||
"http": transport.NewTransport,
|
||||
}
|
||||
)
|
||||
@ -148,37 +162,68 @@ func init() {
|
||||
rand.Seed(time.Now().Unix())
|
||||
}
|
||||
|
||||
func Setup(c *cli.Context) error {
|
||||
func newCmd(opts ...Option) Cmd {
|
||||
options := Options{
|
||||
Brokers: DefaultBrokers,
|
||||
Registries: DefaultRegistries,
|
||||
Selectors: DefaultSelectors,
|
||||
Transports: DefaultTransports,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
cmd := new(cmd)
|
||||
cmd.opts = options
|
||||
cmd.app = cli.NewApp()
|
||||
cmd.app.Name = cmd.opts.Name
|
||||
cmd.app.Version = cmd.opts.Version
|
||||
cmd.app.Usage = cmd.opts.Description
|
||||
cmd.app.Before = cmd.Before
|
||||
cmd.app.Flags = DefaultFlags
|
||||
cmd.app.Action = func(c *cli.Context) {}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *cmd) App() *cli.App {
|
||||
return c.app
|
||||
}
|
||||
|
||||
func (c *cmd) Options() Options {
|
||||
return c.opts
|
||||
}
|
||||
|
||||
func (c *cmd) Before(ctx *cli.Context) error {
|
||||
// Due to logger issues with glog, we need to do this
|
||||
os.Args = os.Args[:1]
|
||||
|
||||
flag.Set("logtostderr", fmt.Sprintf("%v", c.Bool("logtostderr")))
|
||||
flag.Set("alsologtostderr", fmt.Sprintf("%v", c.Bool("alsologtostderr")))
|
||||
flag.Set("stderrthreshold", c.String("stderrthreshold"))
|
||||
flag.Set("log_backtrace_at", c.String("log_backtrace_at"))
|
||||
flag.Set("log_dir", c.String("log_dir"))
|
||||
flag.Set("vmodule", c.String("vmodule"))
|
||||
flag.Set("v", c.String("v"))
|
||||
|
||||
flag.Set("logtostderr", fmt.Sprintf("%v", ctx.Bool("logtostderr")))
|
||||
flag.Set("alsologtostderr", fmt.Sprintf("%v", ctx.Bool("alsologtostderr")))
|
||||
flag.Set("stderrthreshold", ctx.String("stderrthreshold"))
|
||||
flag.Set("log_backtrace_at", ctx.String("log_backtrace_at"))
|
||||
flag.Set("log_dir", ctx.String("log_dir"))
|
||||
flag.Set("vmodule", ctx.String("vmodule"))
|
||||
flag.Set("v", ctx.String("v"))
|
||||
flag.Parse()
|
||||
|
||||
if b, ok := Brokers[c.String("broker")]; ok {
|
||||
broker.DefaultBroker = b(strings.Split(c.String("broker_address"), ","))
|
||||
if b, ok := c.opts.Brokers[ctx.String("broker")]; ok {
|
||||
broker.DefaultBroker = b(strings.Split(ctx.String("broker_address"), ","))
|
||||
}
|
||||
|
||||
if r, ok := Registries[c.String("registry")]; ok {
|
||||
registry.DefaultRegistry = r(strings.Split(c.String("registry_address"), ","))
|
||||
if r, ok := c.opts.Registries[ctx.String("registry")]; ok {
|
||||
registry.DefaultRegistry = r(strings.Split(ctx.String("registry_address"), ","))
|
||||
}
|
||||
|
||||
if s, ok := Selectors[c.String("selector")]; ok {
|
||||
if s, ok := c.opts.Selectors[ctx.String("selector")]; ok {
|
||||
selector.DefaultSelector = s(selector.Registry(registry.DefaultRegistry))
|
||||
}
|
||||
|
||||
if t, ok := Transports[c.String("transport")]; ok {
|
||||
transport.DefaultTransport = t(strings.Split(c.String("transport_address"), ","))
|
||||
if t, ok := c.opts.Transports[ctx.String("transport")]; ok {
|
||||
transport.DefaultTransport = t(strings.Split(ctx.String("transport_address"), ","))
|
||||
}
|
||||
|
||||
metadata := make(map[string]string)
|
||||
for _, d := range c.StringSlice("server_metadata") {
|
||||
for _, d := range ctx.StringSlice("server_metadata") {
|
||||
var key, val string
|
||||
parts := strings.Split(d, "=")
|
||||
key = parts[0]
|
||||
@ -189,11 +234,11 @@ func Setup(c *cli.Context) error {
|
||||
}
|
||||
|
||||
server.DefaultServer = server.NewServer(
|
||||
server.Name(c.String("server_name")),
|
||||
server.Version(c.String("server_version")),
|
||||
server.Id(c.String("server_id")),
|
||||
server.Address(c.String("server_address")),
|
||||
server.Advertise(c.String("server_advertise")),
|
||||
server.Name(ctx.String("server_name")),
|
||||
server.Version(ctx.String("server_version")),
|
||||
server.Id(ctx.String("server_id")),
|
||||
server.Address(ctx.String("server_address")),
|
||||
server.Advertise(ctx.String("server_advertise")),
|
||||
server.Metadata(metadata),
|
||||
)
|
||||
|
||||
@ -202,33 +247,20 @@ func Setup(c *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Init() {
|
||||
cli.AppHelpTemplate = `
|
||||
GLOBAL OPTIONS:
|
||||
{{range .Flags}}{{.}}
|
||||
{{end}}
|
||||
`
|
||||
|
||||
cli.HelpPrinter = func(writer io.Writer, templ string, data interface{}) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
|
||||
t := template.Must(template.New("help").Parse(templ))
|
||||
err := t.Execute(w, data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Flush()
|
||||
os.Exit(2)
|
||||
func (c *cmd) Init(opts ...Option) {
|
||||
for _, o := range opts {
|
||||
o(&c.opts)
|
||||
}
|
||||
|
||||
app := cli.NewApp()
|
||||
app.HideVersion = true
|
||||
app.Usage = "a go micro app"
|
||||
app.Action = func(c *cli.Context) {
|
||||
for _, action := range Actions {
|
||||
action(c)
|
||||
}
|
||||
}
|
||||
app.Before = Setup
|
||||
app.Flags = Flags
|
||||
app.RunAndExitOnError()
|
||||
c.app.Name = c.opts.Name
|
||||
c.app.Version = c.opts.Version
|
||||
c.app.Usage = c.opts.Description
|
||||
c.app.RunAndExitOnError()
|
||||
}
|
||||
|
||||
func Init(opts ...Option) {
|
||||
DefaultCmd.Init(opts...)
|
||||
}
|
||||
|
||||
func NewCmd(opts ...Option) Cmd {
|
||||
return newCmd(opts...)
|
||||
}
|
||||
|
61
cmd/options.go
Normal file
61
cmd/options.go
Normal file
@ -0,0 +1,61 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/broker"
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/selector"
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Name string
|
||||
Description string
|
||||
Version string
|
||||
|
||||
Brokers map[string]func([]string, ...broker.Option) broker.Broker
|
||||
Registries map[string]func([]string, ...registry.Option) registry.Registry
|
||||
Selectors map[string]func(...selector.Option) selector.Selector
|
||||
Transports map[string]func([]string, ...transport.Option) transport.Transport
|
||||
}
|
||||
|
||||
func Name(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = n
|
||||
}
|
||||
}
|
||||
|
||||
func Description(d string) Option {
|
||||
return func(o *Options) {
|
||||
o.Description = d
|
||||
}
|
||||
}
|
||||
|
||||
func Version(v string) Option {
|
||||
return func(o *Options) {
|
||||
o.Version = v
|
||||
}
|
||||
}
|
||||
|
||||
func Broker(name string, b func([]string, ...broker.Option) broker.Broker) Option {
|
||||
return func(o *Options) {
|
||||
o.Brokers[name] = b
|
||||
}
|
||||
}
|
||||
|
||||
func Registry(name string, r func([]string, ...registry.Option) registry.Registry) Option {
|
||||
return func(o *Options) {
|
||||
o.Registries[name] = r
|
||||
}
|
||||
}
|
||||
|
||||
func Selector(name string, s func(...selector.Option) selector.Selector) Option {
|
||||
return func(o *Options) {
|
||||
o.Selectors[name] = s
|
||||
}
|
||||
}
|
||||
|
||||
func Transport(name string, t func([]string, ...transport.Option) transport.Transport) Option {
|
||||
return func(o *Options) {
|
||||
o.Transports[name] = t
|
||||
}
|
||||
}
|
38
examples/service/README.md
Normal file
38
examples/service/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Service
|
||||
|
||||
This is an example of creating a micro service using the top level interface.
|
||||
|
||||
## Prereqs
|
||||
|
||||
Micro services need a discovery system so they can find each other. Micro uses consul by default but
|
||||
its easily swapped out with etcd, kubernetes, or various other systems. We'll run consul for convenience.
|
||||
|
||||
1. Follow the install instructions - [https://www.consul.io/intro/getting-started/install.html](https://www.consul.io/intro/getting-started/install.html)
|
||||
|
||||
2. Run Consul
|
||||
|
||||
```shell
|
||||
$ consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul
|
||||
```
|
||||
|
||||
## Run the example
|
||||
|
||||
1. Get the service
|
||||
|
||||
```shell
|
||||
go get github.com/micro/go-micro/examples/service
|
||||
```
|
||||
|
||||
2. Run the server
|
||||
|
||||
```shell
|
||||
$GOPATH/bin/service
|
||||
```
|
||||
|
||||
3. Run the client
|
||||
|
||||
```shell
|
||||
$GOPATH/bin/service --client
|
||||
```
|
||||
|
||||
And that's all there is to it.
|
93
examples/service/main.go
Normal file
93
examples/service/main.go
Normal file
@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/micro/cli"
|
||||
micro "github.com/micro/go-micro"
|
||||
proto "github.com/micro/go-micro/examples/service/proto"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
Example usage of top level service initialisation
|
||||
|
||||
*/
|
||||
|
||||
type Greeter struct{}
|
||||
|
||||
func (g *Greeter) Hello(ctx context.Context, req *proto.HelloRequest, rsp *proto.HelloResponse) error {
|
||||
rsp.Greeting = "Hello " + req.Name
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setup and the client
|
||||
func client(service micro.Service) {
|
||||
// Create new greeter client
|
||||
greeter := proto.NewGreeterClient("greeter", service.Client())
|
||||
|
||||
// Call the greeter
|
||||
rsp, err := greeter.Hello(context.TODO(), &proto.HelloRequest{Name: "John"})
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Print response
|
||||
fmt.Println(rsp.Greeting)
|
||||
}
|
||||
|
||||
// Setup some command line flags
|
||||
func flags(service micro.Service) {
|
||||
app := service.Cmd().App()
|
||||
app.Flags = append(app.Flags,
|
||||
&cli.BoolFlag{
|
||||
Name: "server",
|
||||
Usage: "Launch the server",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "client",
|
||||
Usage: "Launch the client",
|
||||
},
|
||||
)
|
||||
|
||||
// Let's launch the server or the client
|
||||
app.Action = func(c *cli.Context) {
|
||||
if c.Bool("client") {
|
||||
client(service)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Create a new service. Optionally include some options here.
|
||||
service := micro.NewService(
|
||||
micro.Name("greeter"),
|
||||
micro.Version("latest"),
|
||||
micro.Metadata(map[string]string{
|
||||
"type": "helloworld",
|
||||
}),
|
||||
)
|
||||
|
||||
// Setup some flags. Specify --client to run the client
|
||||
flags(service)
|
||||
|
||||
// Init will parse the command line flags. Any flags set will
|
||||
// override the above settings. Options defined here will
|
||||
// override anything set on the command line.
|
||||
service.Init()
|
||||
|
||||
// By default we'll run the server unless the flags catch us
|
||||
|
||||
// Setup the server
|
||||
|
||||
// Register handler
|
||||
proto.RegisterGreeterHandler(service.Server(), new(Greeter))
|
||||
|
||||
// Run the server
|
||||
if err := service.Run(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
124
examples/service/proto/greeter.pb.go
Normal file
124
examples/service/proto/greeter.pb.go
Normal file
@ -0,0 +1,124 @@
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: go-micro/examples/service/proto/greeter.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package greeter is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
go-micro/examples/service/proto/greeter.proto
|
||||
|
||||
It has these top-level messages:
|
||||
HelloRequest
|
||||
HelloResponse
|
||||
*/
|
||||
package greeter
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
import (
|
||||
client "github.com/micro/go-micro/client"
|
||||
server "github.com/micro/go-micro/server"
|
||||
context "golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
type HelloRequest struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
func (m *HelloRequest) Reset() { *m = HelloRequest{} }
|
||||
func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*HelloRequest) ProtoMessage() {}
|
||||
func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
type HelloResponse struct {
|
||||
Greeting string `protobuf:"bytes,2,opt,name=greeting" json:"greeting,omitempty"`
|
||||
}
|
||||
|
||||
func (m *HelloResponse) Reset() { *m = HelloResponse{} }
|
||||
func (m *HelloResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*HelloResponse) ProtoMessage() {}
|
||||
func (*HelloResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*HelloRequest)(nil), "HelloRequest")
|
||||
proto.RegisterType((*HelloResponse)(nil), "HelloResponse")
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Client API for Greeter service
|
||||
|
||||
type GreeterClient interface {
|
||||
Hello(ctx context.Context, in *HelloRequest, opts ...client.CallOption) (*HelloResponse, error)
|
||||
}
|
||||
|
||||
type greeterClient struct {
|
||||
c client.Client
|
||||
serviceName string
|
||||
}
|
||||
|
||||
func NewGreeterClient(serviceName string, c client.Client) GreeterClient {
|
||||
if c == nil {
|
||||
c = client.NewClient()
|
||||
}
|
||||
if len(serviceName) == 0 {
|
||||
serviceName = "greeter"
|
||||
}
|
||||
return &greeterClient{
|
||||
c: c,
|
||||
serviceName: serviceName,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *greeterClient) Hello(ctx context.Context, in *HelloRequest, opts ...client.CallOption) (*HelloResponse, error) {
|
||||
req := c.c.NewRequest(c.serviceName, "Greeter.Hello", in)
|
||||
out := new(HelloResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Greeter service
|
||||
|
||||
type GreeterHandler interface {
|
||||
Hello(context.Context, *HelloRequest, *HelloResponse) error
|
||||
}
|
||||
|
||||
func RegisterGreeterHandler(s server.Server, hdlr GreeterHandler) {
|
||||
s.Handle(s.NewHandler(&Greeter{hdlr}))
|
||||
}
|
||||
|
||||
type Greeter struct {
|
||||
GreeterHandler
|
||||
}
|
||||
|
||||
func (h *Greeter) Hello(ctx context.Context, in *HelloRequest, out *HelloResponse) error {
|
||||
return h.GreeterHandler.Hello(ctx, in, out)
|
||||
}
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 153 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xd2, 0x4d, 0xcf, 0xd7, 0xcd,
|
||||
0xcd, 0x4c, 0x2e, 0xca, 0xd7, 0x4f, 0xad, 0x48, 0xcc, 0x2d, 0xc8, 0x49, 0x2d, 0xd6, 0x2f, 0x4e,
|
||||
0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0xd7, 0x4f, 0x2f, 0x4a, 0x4d,
|
||||
0x2d, 0x49, 0x2d, 0xd2, 0x03, 0xf3, 0x94, 0x64, 0xb8, 0x78, 0x3c, 0x52, 0x73, 0x72, 0xf2, 0x83,
|
||||
0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x78, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18,
|
||||
0x15, 0x18, 0x35, 0x38, 0x95, 0x14, 0xb9, 0x78, 0xa1, 0xb2, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9,
|
||||
0x42, 0x02, 0x5c, 0x1c, 0x60, 0xfd, 0x99, 0x79, 0xe9, 0x12, 0x4c, 0x20, 0x25, 0x46, 0xc6, 0x5c,
|
||||
0xec, 0xee, 0x10, 0x13, 0x85, 0x34, 0xb8, 0x58, 0xc1, 0xaa, 0x85, 0x78, 0xf5, 0x90, 0xcd, 0x94,
|
||||
0xe2, 0xd3, 0x43, 0x31, 0x44, 0x89, 0x21, 0x89, 0x0d, 0x6c, 0xb9, 0x31, 0x20, 0x00, 0x00, 0xff,
|
||||
0xff, 0x0f, 0xa9, 0x59, 0xb3, 0xad, 0x00, 0x00, 0x00,
|
||||
}
|
13
examples/service/proto/greeter.proto
Normal file
13
examples/service/proto/greeter.proto
Normal file
@ -0,0 +1,13 @@
|
||||
syntax = "proto3";
|
||||
|
||||
service Greeter {
|
||||
rpc Hello(HelloRequest) returns (HelloResponse) {}
|
||||
}
|
||||
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message HelloResponse {
|
||||
string greeting = 2;
|
||||
}
|
@ -21,6 +21,7 @@ package gomicro
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/cmd"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
@ -28,6 +29,8 @@ import (
|
||||
// within go-micro. Its a convenience method for building
|
||||
// and initialising services.
|
||||
type Service interface {
|
||||
Init(...Option)
|
||||
Cmd() cmd.Cmd
|
||||
Client() client.Client
|
||||
Server() server.Server
|
||||
Run() error
|
||||
|
83
options.go
83
options.go
@ -3,6 +3,7 @@ package gomicro
|
||||
import (
|
||||
"github.com/micro/go-micro/broker"
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/cmd"
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/server"
|
||||
"github.com/micro/go-micro/transport"
|
||||
@ -10,38 +11,35 @@ import (
|
||||
|
||||
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
|
||||
AfterStop []func() error
|
||||
|
||||
// Alternative options for those implementing the interface
|
||||
Options map[string]string
|
||||
}
|
||||
|
||||
func newOptions(opts ...Option) Options {
|
||||
var opt Options
|
||||
opt := Options{
|
||||
Broker: broker.DefaultBroker,
|
||||
Cmd: cmd.DefaultCmd,
|
||||
Client: client.DefaultClient,
|
||||
Server: server.DefaultServer,
|
||||
Registry: registry.DefaultRegistry,
|
||||
Transport: transport.DefaultTransport,
|
||||
Options: map[string]string{},
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
if opt.Broker == nil {
|
||||
opt.Broker = broker.DefaultBroker
|
||||
}
|
||||
|
||||
if opt.Client == nil {
|
||||
opt.Client = client.DefaultClient
|
||||
}
|
||||
|
||||
if opt.Server == nil {
|
||||
opt.Server = server.DefaultServer
|
||||
}
|
||||
|
||||
if opt.Registry == nil {
|
||||
opt.Registry = registry.DefaultRegistry
|
||||
}
|
||||
|
||||
if opt.Transport == nil {
|
||||
opt.Transport = transport.DefaultTransport
|
||||
}
|
||||
|
||||
return opt
|
||||
}
|
||||
|
||||
@ -51,6 +49,12 @@ func Broker(b broker.Broker) Option {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -74,3 +78,40 @@ func Transport(t transport.Transport) Option {
|
||||
o.Transport = t
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience options
|
||||
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
|
||||
// Before and Afters
|
||||
|
||||
func BeforeStart(fn func() error) Option {
|
||||
return func(o *Options) {
|
||||
o.BeforeStart = append(o.BeforeStart, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func AfterStop(fn func() error) Option {
|
||||
return func(o *Options) {
|
||||
o.AfterStop = append(o.AfterStop, fn)
|
||||
}
|
||||
}
|
||||
|
29
service.go
29
service.go
@ -6,6 +6,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/cmd"
|
||||
"github.com/micro/go-micro/context"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
@ -20,7 +21,7 @@ func newService(opts ...Option) Service {
|
||||
options.Client = &clientWrapper{
|
||||
options.Client,
|
||||
context.Metadata{
|
||||
HeaderPrefix + "From-Service": options.Server.Config().Name(),
|
||||
HeaderPrefix + "From-Service": options.Server.Options().Name,
|
||||
},
|
||||
}
|
||||
|
||||
@ -29,6 +30,15 @@ func newService(opts ...Option) Service {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) Init(opts ...Option) {
|
||||
s.opts.Cmd.Init()
|
||||
s = newService(opts...).(*service)
|
||||
}
|
||||
|
||||
func (s *service) Cmd() cmd.Cmd {
|
||||
return s.opts.Cmd
|
||||
}
|
||||
|
||||
func (s *service) Client() client.Client {
|
||||
return s.opts.Client
|
||||
}
|
||||
@ -42,6 +52,12 @@ func (s *service) String() string {
|
||||
}
|
||||
|
||||
func (s *service) Start() error {
|
||||
for _, fn := range s.opts.BeforeStart {
|
||||
if err := fn(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.opts.Server.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -62,7 +78,16 @@ func (s *service) Stop() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
var gerr error
|
||||
for _, fn := range s.opts.AfterStop {
|
||||
if err := fn(); err != nil {
|
||||
// should we bail if it fails?
|
||||
// other funcs will not be executed
|
||||
// seems wrong
|
||||
gerr = err
|
||||
}
|
||||
}
|
||||
return gerr
|
||||
}
|
||||
|
||||
func (s *service) Run() error {
|
||||
|
Loading…
Reference in New Issue
Block a user