Compare commits
286 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6ec32805d0 | ||
|
3e3bbe3fd0 | ||
|
b5eea02f7a | ||
|
08c6f60b0f | ||
|
065c7d5616 | ||
|
a5ce3e32da | ||
|
3bfbcd5e6a | ||
|
b6c6b13277 | ||
|
04b31d374c | ||
|
e828a099c5 | ||
|
2c16c7e62f | ||
|
1f44d7a4a1 | ||
|
b076ef906a | ||
|
c669a2b155 | ||
|
48a3e51aca | ||
|
e8aaca27d3 | ||
|
5596407144 | ||
|
7971b1b7f9 | ||
|
dafbacbdcb | ||
|
df5657dcd1 | ||
|
bb595c85b2 | ||
|
bc6187ea89 | ||
|
ed1faa7a5c | ||
|
1d9298ae2b | ||
|
dddfb6f878 | ||
|
ec354934e3 | ||
|
b01c8e06e0 | ||
|
97b1071f7e | ||
|
1527a84297 | ||
|
5ddfd911ba | ||
|
2310ee424c | ||
|
2522d8cb96 | ||
|
d198765c6c | ||
|
1840b5bd74 | ||
|
9161b20d6b | ||
|
a1ba1482c5 | ||
|
d0761e0a1b | ||
|
4b1a7abb42 | ||
|
e33bd17894 | ||
|
cc5d811a83 | ||
|
e15389febb | ||
|
6d63c3777f | ||
|
d8a1b47954 | ||
|
b9a2f719a0 | ||
|
46a9767648 | ||
|
dd9f42e3b9 | ||
|
f2c8492c77 | ||
|
407381912b | ||
|
d559ce9da2 | ||
|
7ab3934eb7 | ||
|
0075477df0 | ||
|
d5be2136ad | ||
|
c718b8bf93 | ||
|
a24818ee54 | ||
|
66db0ac52c | ||
|
b9c437fbfe | ||
|
147899283c | ||
|
5b991cd2c2 | ||
|
bb64f94313 | ||
|
4f4b3d3bae | ||
|
eb4a709195 | ||
|
6c21b31226 | ||
|
6eb6d050ed | ||
|
6c7582a6be | ||
|
3ea4490d6c | ||
|
b50c44a758 | ||
|
ec6318befc | ||
|
5440325a18 | ||
|
fb13877904 | ||
|
2f5e3c66b9 | ||
|
a8d4299df9 | ||
|
90745c14f2 | ||
|
86665454e7 | ||
|
4f5a849211 | ||
|
bf53c16e4b | ||
|
6c3631728b | ||
|
2cdfed359f | ||
|
956be5c59d | ||
|
52d9d75dfa | ||
|
0d94784e72 | ||
|
65c2de5a79 | ||
|
6fa9d7270f | ||
|
140c830af1 | ||
|
b37837ad92 | ||
|
10b64af0b3 | ||
|
5d01284574 | ||
|
ff81e4b246 | ||
|
e955e3f798 | ||
|
a17a8b3372 | ||
|
e1d56fbf58 | ||
|
e7d8cdda44 | ||
|
690640eeeb | ||
|
4f788c6fc7 | ||
|
f50bd400f8 | ||
|
b457ec1990 | ||
|
ffa6b551f4 | ||
|
3d03fe4076 | ||
|
6eecb199e9 | ||
|
7479515099 | ||
|
6e3d53e1ee | ||
|
721c5e6857 | ||
|
7d033818cf | ||
|
00ab58f61b | ||
|
b3aef71fdb | ||
|
8606f1e143 | ||
|
927fac2cec | ||
|
6ab86c9e57 | ||
|
db8e2620cb | ||
|
d09b7dbbef | ||
|
a4f5772555 | ||
|
731f6f74dd | ||
|
5e7208119e | ||
|
470304ef87 | ||
|
a6ab4d7b4b | ||
|
87b56d46ac | ||
|
371b23d055 | ||
|
f97565ef0a | ||
|
0888d2fbbc | ||
|
443fc0ebde | ||
|
35e7b9551f | ||
|
6daf4fda72 | ||
|
36623bfe50 | ||
|
6128d18ee0 | ||
|
abadb2211e | ||
|
ca267f73de | ||
|
d8608b2343 | ||
|
ed8d28c9ab | ||
|
88e47b9b06 | ||
|
1b0295de0d | ||
|
9448d7c164 | ||
|
8c3eec9f2a | ||
|
e53484302c | ||
|
db89fc4efe | ||
|
e1599b0f17 | ||
|
a09d5d2e9a | ||
|
6c1f1d66f7 | ||
|
a6e1287b27 | ||
|
fcec6e8eae | ||
|
30dd3f54f0 | ||
|
6beae23afd | ||
|
718780367e | ||
|
ba99f037fb | ||
|
80dc0b97a9 | ||
|
1a32e3a11d | ||
|
955dc2a23d | ||
|
934b8eb86d | ||
|
b7f510ff64 | ||
|
353eade6c3 | ||
|
a133e61c2d | ||
|
99d39e743b | ||
|
0cdac2aa36 | ||
|
75871287a1 | ||
|
fb750a0bb1 | ||
|
c6e15ef2d1 | ||
|
f787cc0ee0 | ||
|
c2d85a6e1f | ||
|
86f0c06fac | ||
|
0aea8e3163 | ||
|
4ea27517b5 | ||
|
f8e68ae101 | ||
|
f848041c49 | ||
|
dfbd730b8c | ||
|
ac2a5a04a2 | ||
f1d08f251f | |||
|
718ae42808 | ||
|
2413cbcd80 | ||
|
9c820445a4 | ||
|
c44fd63301 | ||
|
d9a699ae6f | ||
|
4495ca3839 | ||
|
0b0eee41d0 | ||
|
e18f8defde | ||
|
7abdc68049 | ||
|
c90e1ccb99 | ||
|
991142cd57 | ||
|
5a5b1b8f6e | ||
|
58bc4c103f | ||
|
88817dc53f | ||
|
ef04331b86 | ||
|
67215ae5da | ||
|
f120452d28 | ||
|
740cfab8d0 | ||
|
f6b8045dd5 | ||
|
b776fbb766 | ||
|
a42de29f67 | ||
|
0f6d09af33 | ||
|
2dd5109eee | ||
|
e609095ba4 | ||
|
4843f09afa | ||
|
f9eddf1e6f | ||
|
f19308f1e6 | ||
|
8f0c2e0412 | ||
|
bf0e46dc0d | ||
|
15975d2903 | ||
|
9f2f0e3cea | ||
|
151bcf0ea1 | ||
|
dc0fbfc3c0 | ||
|
e607485c6b | ||
70d0029658 | |||
a606813fdf | |||
|
750267b308 | ||
|
7ce0305db4 | ||
|
c39591af0e | ||
|
fedc6be3e6 | ||
|
cb1679fd8d | ||
|
c0a676bfa9 | ||
|
cb4e376c64 | ||
|
c2c8182a5b | ||
|
01cb146e0d | ||
|
d0d729a789 | ||
|
113d87d855 | ||
|
56df10f68b | ||
|
3a5428fb36 | ||
|
178a3b3d8e | ||
|
de34f259ba | ||
|
81b68a1d7f | ||
|
1a600810a7 | ||
|
94127ae1aa | ||
|
cd2ac648ff | ||
|
e613b0c205 | ||
|
57dacf1831 | ||
|
8986b3135f | ||
|
6dd3ea1853 | ||
|
2c66e94045 | ||
|
c1ff3ceee4 | ||
|
b13604fb4b | ||
|
057adb2b2e | ||
|
7bd6d1b549 | ||
|
37988b596d | ||
|
9eb45dac82 | ||
|
59b13aef22 | ||
|
1e496938b7 | ||
|
fbc1d523d7 | ||
|
11795071fb | ||
|
c7e8a2aeb9 | ||
|
cb1c1afc84 | ||
|
3fc7d9ea50 | ||
|
abc2ace409 | ||
|
243d43df92 | ||
|
9c2b882008 | ||
|
4370f03e04 | ||
|
a3b962f37b | ||
|
a894b4f354 | ||
|
fc379f2d2c | ||
|
dcf4fed6a3 | ||
|
117376a922 | ||
|
380d9790e6 | ||
|
0baea58938 | ||
|
edb0fe4b16 | ||
|
eae32176c4 | ||
|
bc751c55fb | ||
|
91f2af91de | ||
|
3adce58eb2 | ||
|
bb01b3ed78 | ||
|
c3ea25225c | ||
|
beffa625f8 | ||
|
0d85e35da0 | ||
|
4074cce397 | ||
|
000431f489 | ||
|
e16420fdbd | ||
|
52d8d26018 | ||
|
6649012af3 | ||
|
6b5dcbf814 | ||
|
34381213e7 | ||
|
767292906a | ||
|
e1ecd728c5 | ||
|
f1b6709722 | ||
|
4030ccc27b | ||
|
2e67e23a23 | ||
|
be229438bc | ||
e1709026e4 | |||
|
d250ac736f | ||
|
6719f8d655 | ||
|
d7929ef8f3 | ||
|
04404441a4 | ||
|
b806e7bdf5 | ||
|
2720c6f28e | ||
|
cdf0f14d58 | ||
|
679c5f0ccd | ||
|
873bfcc73c | ||
|
7884e889f4 | ||
|
b1c49a0ddc | ||
|
318367cd71 | ||
|
2d09e74b0e | ||
|
3e90d32f29 | ||
|
fca89e06ef |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,7 @@
|
||||
# Develop tools
|
||||
/.vscode/
|
||||
/.idea/
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
|
@@ -1,9 +1,11 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
notifications:
|
||||
slack:
|
||||
secure: aEvhLbhujaGaKSrOokiG3//PaVHTIrc3fBpoRbCRqfZpyq6WREoapJJhF+tIpWWOwaC9GmChbD6aHo/jMUgwKXVyPSaNjiEL87YzUUpL8B2zslNp1rgfTg/LrzthOx3Q1TYwpaAl3to0fuHUVFX4yMeC2vuThq7WSXgMMxFCtbc=
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/pkg/mod
|
||||
|
@@ -32,5 +32,5 @@ Go Micro把分布式系统的各种细节抽象出来。下面是它的主要特
|
||||
|
||||
## 快速上手
|
||||
|
||||
更多关于架构、安装的资料可以查看[文档](https://micro.mu/docs/go-micro_cn.html)。
|
||||
更多关于架构、安装的资料可以查看[文档](https://micro.mu/docs/cn/)。
|
||||
|
||||
|
@@ -13,18 +13,19 @@ import (
|
||||
)
|
||||
|
||||
type natsBroker struct {
|
||||
sync.Once
|
||||
sync.RWMutex
|
||||
addrs []string
|
||||
conn *nats.Conn
|
||||
opts broker.Options
|
||||
nopts nats.Options
|
||||
drain bool
|
||||
addrs []string
|
||||
conn *nats.Conn
|
||||
opts broker.Options
|
||||
nopts nats.Options
|
||||
drain bool
|
||||
closeCh chan (error)
|
||||
}
|
||||
|
||||
type subscriber struct {
|
||||
s *nats.Subscription
|
||||
opts broker.SubscribeOptions
|
||||
drain bool
|
||||
s *nats.Subscription
|
||||
opts broker.SubscribeOptions
|
||||
}
|
||||
|
||||
type publication struct {
|
||||
@@ -54,9 +55,6 @@ func (s *subscriber) Topic() string {
|
||||
}
|
||||
|
||||
func (s *subscriber) Unsubscribe() error {
|
||||
if s.drain {
|
||||
return s.s.Drain()
|
||||
}
|
||||
return s.s.Unsubscribe()
|
||||
}
|
||||
|
||||
@@ -122,20 +120,17 @@ func (n *natsBroker) Connect() error {
|
||||
|
||||
func (n *natsBroker) Disconnect() error {
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
if n.drain {
|
||||
n.conn.Drain()
|
||||
} else {
|
||||
n.conn.Close()
|
||||
return <-n.closeCh
|
||||
}
|
||||
n.RUnlock()
|
||||
n.conn.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *natsBroker) Init(opts ...broker.Option) error {
|
||||
for _, o := range opts {
|
||||
o(&n.opts)
|
||||
}
|
||||
n.addrs = setAddrs(n.opts.Addrs)
|
||||
n.setOption(opts...)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -167,11 +162,6 @@ func (n *natsBroker) Subscribe(topic string, handler broker.Handler, opts ...bro
|
||||
o(&opt)
|
||||
}
|
||||
|
||||
var drain bool
|
||||
if _, ok := opt.Context.Value(drainSubscriptionKey{}).(bool); ok {
|
||||
drain = true
|
||||
}
|
||||
|
||||
fn := func(msg *nats.Msg) {
|
||||
var m broker.Message
|
||||
if err := n.opts.Codec.Unmarshal(msg.Data, &m); err != nil {
|
||||
@@ -193,7 +183,7 @@ func (n *natsBroker) Subscribe(topic string, handler broker.Handler, opts ...bro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &subscriber{s: sub, opts: opt, drain: drain}, nil
|
||||
return &subscriber{s: sub, opts: opt}, nil
|
||||
}
|
||||
|
||||
func (n *natsBroker) String() string {
|
||||
@@ -207,39 +197,59 @@ func NewBroker(opts ...broker.Option) broker.Broker {
|
||||
Context: context.Background(),
|
||||
}
|
||||
|
||||
n := &natsBroker{
|
||||
opts: options,
|
||||
}
|
||||
n.setOption(opts...)
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func (n *natsBroker) setOption(opts ...broker.Option) {
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
o(&n.opts)
|
||||
}
|
||||
|
||||
natsOpts := nats.GetDefaultOptions()
|
||||
if n, ok := options.Context.Value(optionsKey{}).(nats.Options); ok {
|
||||
natsOpts = n
|
||||
}
|
||||
n.Once.Do(func() {
|
||||
n.nopts = nats.GetDefaultOptions()
|
||||
})
|
||||
|
||||
var drain bool
|
||||
if _, ok := options.Context.Value(drainSubscriptionKey{}).(bool); ok {
|
||||
drain = true
|
||||
if nopts, ok := n.opts.Context.Value(optionsKey{}).(nats.Options); ok {
|
||||
n.nopts = nopts
|
||||
}
|
||||
|
||||
// broker.Options have higher priority than nats.Options
|
||||
// only if Addrs, Secure or TLSConfig were not set through a broker.Option
|
||||
// we read them from nats.Option
|
||||
if len(options.Addrs) == 0 {
|
||||
options.Addrs = natsOpts.Servers
|
||||
if len(n.opts.Addrs) == 0 {
|
||||
n.opts.Addrs = n.nopts.Servers
|
||||
}
|
||||
|
||||
if !options.Secure {
|
||||
options.Secure = natsOpts.Secure
|
||||
if !n.opts.Secure {
|
||||
n.opts.Secure = n.nopts.Secure
|
||||
}
|
||||
|
||||
if options.TLSConfig == nil {
|
||||
options.TLSConfig = natsOpts.TLSConfig
|
||||
if n.opts.TLSConfig == nil {
|
||||
n.opts.TLSConfig = n.nopts.TLSConfig
|
||||
}
|
||||
n.addrs = setAddrs(n.opts.Addrs)
|
||||
|
||||
return &natsBroker{
|
||||
opts: options,
|
||||
nopts: natsOpts,
|
||||
addrs: setAddrs(options.Addrs),
|
||||
drain: drain,
|
||||
if n.opts.Context.Value(drainConnectionKey{}) != nil {
|
||||
n.drain = true
|
||||
n.closeCh = make(chan error)
|
||||
n.nopts.ClosedCB = n.onClose
|
||||
n.nopts.AsyncErrorCB = n.onAsyncError
|
||||
}
|
||||
}
|
||||
|
||||
func (n *natsBroker) onClose(conn *nats.Conn) {
|
||||
n.closeCh <- nil
|
||||
}
|
||||
|
||||
func (n *natsBroker) onAsyncError(conn *nats.Conn, sub *nats.Subscription, err error) {
|
||||
// There are kinds of different async error nats might callback, but we are interested
|
||||
// in ErrDrainTimeout only here.
|
||||
if err == nats.ErrDrainTimeout {
|
||||
n.closeCh <- err
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
type optionsKey struct{}
|
||||
type drainConnectionKey struct{}
|
||||
type drainSubscriptionKey struct{}
|
||||
|
||||
// Options accepts nats.Options
|
||||
func Options(opts nats.Options) broker.Option {
|
||||
@@ -16,10 +15,5 @@ func Options(opts nats.Options) broker.Option {
|
||||
|
||||
// DrainConnection will drain subscription on close
|
||||
func DrainConnection() broker.Option {
|
||||
return setBrokerOption(drainConnectionKey{}, true)
|
||||
}
|
||||
|
||||
// DrainSubscription will drain pending messages when unsubscribe
|
||||
func DrainSubscription() broker.SubscribeOption {
|
||||
return setSubscribeOption(drainSubscriptionKey{}, true)
|
||||
return setBrokerOption(drainConnectionKey{}, struct{}{})
|
||||
}
|
||||
|
@@ -30,6 +30,7 @@ var (
|
||||
"application/proto": protoCodec{},
|
||||
"application/protobuf": protoCodec{},
|
||||
"application/octet-stream": protoCodec{},
|
||||
"application/grpc": protoCodec{},
|
||||
"application/grpc+json": jsonCodec{},
|
||||
"application/grpc+proto": protoCodec{},
|
||||
"application/grpc+bytes": bytesCodec{},
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/transport"
|
||||
|
||||
"github.com/micro/go-micro/util/buf"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/encoding"
|
||||
@@ -73,10 +72,11 @@ func (g *grpcClient) next(request client.Request, opts client.CallOptions) (sele
|
||||
|
||||
// get next nodes from the selector
|
||||
next, err := g.opts.Selector.Select(service, opts.SelectOptions...)
|
||||
if err != nil && err == selector.ErrNotFound {
|
||||
return nil, errors.NotFound("go.micro.client", err.Error())
|
||||
} else if err != nil {
|
||||
return nil, errors.InternalServerError("go.micro.client", err.Error())
|
||||
if err != nil {
|
||||
if err == selector.ErrNotFound {
|
||||
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())
|
||||
}
|
||||
return nil, errors.InternalServerError("go.micro.client", "error selecting %s node: %s", service, err.Error())
|
||||
}
|
||||
|
||||
return next, nil
|
||||
@@ -350,15 +350,17 @@ func (g *grpcClient) Call(ctx context.Context, req client.Request, rsp interface
|
||||
|
||||
// select next node
|
||||
node, err := next()
|
||||
if err != nil && err == selector.ErrNotFound {
|
||||
return errors.NotFound("go.micro.client", err.Error())
|
||||
} else if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", err.Error())
|
||||
service := req.Service()
|
||||
if err != nil {
|
||||
if err == selector.ErrNotFound {
|
||||
return errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())
|
||||
}
|
||||
return errors.InternalServerError("go.micro.client", "error selecting %s node: %s", service, err.Error())
|
||||
}
|
||||
|
||||
// make the call
|
||||
err = gcall(ctx, node, req, rsp, callOpts)
|
||||
g.opts.Selector.Mark(req.Service(), node, err)
|
||||
g.opts.Selector.Mark(service, node, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -429,14 +431,16 @@ func (g *grpcClient) Stream(ctx context.Context, req client.Request, opts ...cli
|
||||
}
|
||||
|
||||
node, err := next()
|
||||
if err != nil && err == selector.ErrNotFound {
|
||||
return nil, errors.NotFound("go.micro.client", err.Error())
|
||||
} else if err != nil {
|
||||
return nil, errors.InternalServerError("go.micro.client", err.Error())
|
||||
service := req.Service()
|
||||
if err != nil {
|
||||
if err == selector.ErrNotFound {
|
||||
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())
|
||||
}
|
||||
return nil, errors.InternalServerError("go.micro.client", "error selecting %s node: %s", service, err.Error())
|
||||
}
|
||||
|
||||
stream, err := g.stream(ctx, node, req, callOpts)
|
||||
g.opts.Selector.Mark(req.Service(), node, err)
|
||||
g.opts.Selector.Mark(service, node, err)
|
||||
return stream, err
|
||||
}
|
||||
|
||||
@@ -486,14 +490,13 @@ func (g *grpcClient) Publish(ctx context.Context, p client.Message, opts ...clie
|
||||
}
|
||||
md["Content-Type"] = p.ContentType()
|
||||
|
||||
cf, err := g.newCodec(p.ContentType())
|
||||
cf, err := g.newGRPCCodec(p.ContentType())
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", err.Error())
|
||||
}
|
||||
|
||||
b := buf.New(nil)
|
||||
|
||||
if err := cf(b).Write(&codec.Message{Type: codec.Event}, p.Payload()); err != nil {
|
||||
b, err := cf.Marshal(p.Payload())
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", err.Error())
|
||||
}
|
||||
|
||||
@@ -503,7 +506,7 @@ func (g *grpcClient) Publish(ctx context.Context, p client.Message, opts ...clie
|
||||
|
||||
return g.opts.Broker.Publish(p.Topic(), &broker.Message{
|
||||
Header: md,
|
||||
Body: b.Bytes(),
|
||||
Body: b,
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -31,37 +31,37 @@ var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Client API for Micro service
|
||||
// Client API for Client service
|
||||
|
||||
type MicroService interface {
|
||||
type ClientService interface {
|
||||
// Call allows a single request to be made
|
||||
Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
|
||||
// Stream is a bidirectional stream
|
||||
Stream(ctx context.Context, opts ...client.CallOption) (Micro_StreamService, error)
|
||||
Stream(ctx context.Context, opts ...client.CallOption) (Client_StreamService, error)
|
||||
// Publish publishes a message and returns an empty Message
|
||||
Publish(ctx context.Context, in *Message, opts ...client.CallOption) (*Message, error)
|
||||
}
|
||||
|
||||
type microService struct {
|
||||
type clientService struct {
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewMicroService(name string, c client.Client) MicroService {
|
||||
func NewClientService(name string, c client.Client) ClientService {
|
||||
if c == nil {
|
||||
c = client.NewClient()
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = "go.micro.client"
|
||||
}
|
||||
return µService{
|
||||
return &clientService{
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *microService) Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
|
||||
req := c.c.NewRequest(c.name, "Micro.Call", in)
|
||||
func (c *clientService) Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
|
||||
req := c.c.NewRequest(c.name, "Client.Call", in)
|
||||
out := new(Response)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
@@ -70,16 +70,16 @@ func (c *microService) Call(ctx context.Context, in *Request, opts ...client.Cal
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *microService) Stream(ctx context.Context, opts ...client.CallOption) (Micro_StreamService, error) {
|
||||
req := c.c.NewRequest(c.name, "Micro.Stream", &Request{})
|
||||
func (c *clientService) Stream(ctx context.Context, opts ...client.CallOption) (Client_StreamService, error) {
|
||||
req := c.c.NewRequest(c.name, "Client.Stream", &Request{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return µServiceStream{stream}, nil
|
||||
return &clientServiceStream{stream}, nil
|
||||
}
|
||||
|
||||
type Micro_StreamService interface {
|
||||
type Client_StreamService interface {
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
@@ -87,27 +87,27 @@ type Micro_StreamService interface {
|
||||
Recv() (*Response, error)
|
||||
}
|
||||
|
||||
type microServiceStream struct {
|
||||
type clientServiceStream struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *microServiceStream) Close() error {
|
||||
func (x *clientServiceStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *microServiceStream) SendMsg(m interface{}) error {
|
||||
func (x *clientServiceStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *microServiceStream) RecvMsg(m interface{}) error {
|
||||
func (x *clientServiceStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *microServiceStream) Send(m *Request) error {
|
||||
func (x *clientServiceStream) Send(m *Request) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *microServiceStream) Recv() (*Response, error) {
|
||||
func (x *clientServiceStream) Recv() (*Response, error) {
|
||||
m := new(Response)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
@@ -116,8 +116,8 @@ func (x *microServiceStream) Recv() (*Response, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *microService) Publish(ctx context.Context, in *Message, opts ...client.CallOption) (*Message, error) {
|
||||
req := c.c.NewRequest(c.name, "Micro.Publish", in)
|
||||
func (c *clientService) Publish(ctx context.Context, in *Message, opts ...client.CallOption) (*Message, error) {
|
||||
req := c.c.NewRequest(c.name, "Client.Publish", in)
|
||||
out := new(Message)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
@@ -126,43 +126,43 @@ func (c *microService) Publish(ctx context.Context, in *Message, opts ...client.
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Micro service
|
||||
// Server API for Client service
|
||||
|
||||
type MicroHandler interface {
|
||||
type ClientHandler interface {
|
||||
// Call allows a single request to be made
|
||||
Call(context.Context, *Request, *Response) error
|
||||
// Stream is a bidirectional stream
|
||||
Stream(context.Context, Micro_StreamStream) error
|
||||
Stream(context.Context, Client_StreamStream) error
|
||||
// Publish publishes a message and returns an empty Message
|
||||
Publish(context.Context, *Message, *Message) error
|
||||
}
|
||||
|
||||
func RegisterMicroHandler(s server.Server, hdlr MicroHandler, opts ...server.HandlerOption) error {
|
||||
type micro interface {
|
||||
func RegisterClientHandler(s server.Server, hdlr ClientHandler, opts ...server.HandlerOption) error {
|
||||
type client interface {
|
||||
Call(ctx context.Context, in *Request, out *Response) error
|
||||
Stream(ctx context.Context, stream server.Stream) error
|
||||
Publish(ctx context.Context, in *Message, out *Message) error
|
||||
}
|
||||
type Micro struct {
|
||||
micro
|
||||
type Client struct {
|
||||
client
|
||||
}
|
||||
h := µHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&Micro{h}, opts...))
|
||||
h := &clientHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&Client{h}, opts...))
|
||||
}
|
||||
|
||||
type microHandler struct {
|
||||
MicroHandler
|
||||
type clientHandler struct {
|
||||
ClientHandler
|
||||
}
|
||||
|
||||
func (h *microHandler) Call(ctx context.Context, in *Request, out *Response) error {
|
||||
return h.MicroHandler.Call(ctx, in, out)
|
||||
func (h *clientHandler) Call(ctx context.Context, in *Request, out *Response) error {
|
||||
return h.ClientHandler.Call(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *microHandler) Stream(ctx context.Context, stream server.Stream) error {
|
||||
return h.MicroHandler.Stream(ctx, µStreamStream{stream})
|
||||
func (h *clientHandler) Stream(ctx context.Context, stream server.Stream) error {
|
||||
return h.ClientHandler.Stream(ctx, &clientStreamStream{stream})
|
||||
}
|
||||
|
||||
type Micro_StreamStream interface {
|
||||
type Client_StreamStream interface {
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
@@ -170,27 +170,27 @@ type Micro_StreamStream interface {
|
||||
Recv() (*Request, error)
|
||||
}
|
||||
|
||||
type microStreamStream struct {
|
||||
type clientStreamStream struct {
|
||||
stream server.Stream
|
||||
}
|
||||
|
||||
func (x *microStreamStream) Close() error {
|
||||
func (x *clientStreamStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *microStreamStream) SendMsg(m interface{}) error {
|
||||
func (x *clientStreamStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *microStreamStream) RecvMsg(m interface{}) error {
|
||||
func (x *clientStreamStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *microStreamStream) Send(m *Response) error {
|
||||
func (x *clientStreamStream) Send(m *Response) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *microStreamStream) Recv() (*Request, error) {
|
||||
func (x *clientStreamStream) Recv() (*Request, error) {
|
||||
m := new(Request)
|
||||
if err := x.stream.Recv(m); err != nil {
|
||||
return nil, err
|
||||
@@ -198,6 +198,6 @@ func (x *microStreamStream) Recv() (*Request, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (h *microHandler) Publish(ctx context.Context, in *Message, out *Message) error {
|
||||
return h.MicroHandler.Publish(ctx, in, out)
|
||||
func (h *clientHandler) Publish(ctx context.Context, in *Message, out *Message) error {
|
||||
return h.ClientHandler.Publish(ctx, in, out)
|
||||
}
|
||||
|
@@ -191,23 +191,23 @@ func init() {
|
||||
|
||||
var fileDescriptor_7d733ae29171347b = []byte{
|
||||
// 270 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x91, 0x3f, 0x4f, 0xc3, 0x30,
|
||||
0x10, 0xc5, 0xeb, 0xfe, 0x4b, 0x39, 0x2a, 0x21, 0x9d, 0x18, 0x4c, 0x06, 0x54, 0x32, 0x65, 0xc1,
|
||||
0x45, 0x30, 0x23, 0x86, 0xce, 0x95, 0x50, 0x40, 0xac, 0x28, 0x71, 0x4f, 0xc1, 0x52, 0x6a, 0x9b,
|
||||
0xd8, 0xad, 0x94, 0xef, 0xc8, 0x87, 0x42, 0x38, 0x29, 0x45, 0xd0, 0x2e, 0x6c, 0xf7, 0xee, 0x67,
|
||||
0xbd, 0x3b, 0xbf, 0x83, 0x74, 0xad, 0x64, 0x6d, 0xe6, 0xa5, 0xb9, 0x6e, 0x0b, 0x59, 0x29, 0xd2,
|
||||
0x7e, 0x6e, 0x6b, 0xe3, 0x77, 0x42, 0x04, 0x81, 0x67, 0xa5, 0x11, 0xe1, 0x8d, 0x68, 0xdb, 0xc9,
|
||||
0x16, 0xa2, 0x8c, 0xde, 0x37, 0xe4, 0x3c, 0x72, 0x88, 0x1c, 0xd5, 0x5b, 0x25, 0x89, 0xb3, 0x19,
|
||||
0x4b, 0x4f, 0xb2, 0x9d, 0xc4, 0x18, 0x26, 0xa4, 0x57, 0xd6, 0x28, 0xed, 0x79, 0x3f, 0xa0, 0x6f,
|
||||
0x8d, 0x57, 0x30, 0x95, 0x46, 0x7b, 0xd2, 0xfe, 0xd5, 0x37, 0x96, 0xf8, 0x20, 0xf0, 0xd3, 0xae,
|
||||
0xf7, 0xdc, 0x58, 0x42, 0x84, 0x61, 0x61, 0x56, 0x0d, 0x1f, 0xce, 0x58, 0x3a, 0xcd, 0x42, 0x9d,
|
||||
0x5c, 0xc2, 0x24, 0x23, 0x67, 0x8d, 0x76, 0x7b, 0xce, 0x7e, 0xf0, 0x17, 0x88, 0x96, 0xe4, 0x5c,
|
||||
0x5e, 0x12, 0x9e, 0xc3, 0xc8, 0x1b, 0xab, 0x64, 0xb7, 0x55, 0x2b, 0xfe, 0xcc, 0xed, 0x1f, 0x9f,
|
||||
0x3b, 0xd8, 0xfb, 0xde, 0x7e, 0x30, 0x18, 0x2d, 0xbf, 0x02, 0xc0, 0x7b, 0x18, 0x2e, 0xf2, 0xaa,
|
||||
0x42, 0x2e, 0x7e, 0x65, 0x22, 0xba, 0x40, 0xe2, 0x8b, 0x03, 0xa4, 0x5d, 0x39, 0xe9, 0xe1, 0x02,
|
||||
0xc6, 0x4f, 0xbe, 0xa6, 0x7c, 0xfd, 0x4f, 0x83, 0x94, 0xdd, 0x30, 0x7c, 0x80, 0xe8, 0x71, 0x53,
|
||||
0x54, 0xca, 0xbd, 0x1d, 0x70, 0xe9, 0xfe, 0x1f, 0x1f, 0x25, 0x49, 0xaf, 0x18, 0x87, 0xb3, 0xde,
|
||||
0x7d, 0x06, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x63, 0x94, 0x1a, 0x02, 0x02, 0x00, 0x00,
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x91, 0x41, 0x4b, 0xc3, 0x40,
|
||||
0x10, 0x85, 0xbb, 0x6d, 0x4c, 0xea, 0x58, 0x10, 0x06, 0x0f, 0x6b, 0x0e, 0x52, 0x73, 0xca, 0xc5,
|
||||
0x54, 0xf4, 0x2c, 0x1e, 0x72, 0x16, 0x24, 0x8a, 0x57, 0x49, 0xb6, 0x43, 0x5c, 0x48, 0x77, 0xd7,
|
||||
0xec, 0xb6, 0x90, 0x1f, 0xe9, 0x7f, 0x12, 0x36, 0xa9, 0x15, 0x6d, 0x2f, 0xbd, 0xcd, 0x9b, 0x6f,
|
||||
0x79, 0x33, 0xfb, 0x06, 0xd2, 0x95, 0x14, 0xad, 0x5e, 0xd4, 0xfa, 0xa6, 0x2f, 0x44, 0x23, 0x49,
|
||||
0xb9, 0x85, 0x69, 0xb5, 0xdb, 0x8a, 0xcc, 0x0b, 0x3c, 0xaf, 0x75, 0xe6, 0xdf, 0x64, 0x7d, 0x3b,
|
||||
0xd9, 0x40, 0x54, 0xd0, 0xe7, 0x9a, 0xac, 0x43, 0x0e, 0x91, 0xa5, 0x76, 0x23, 0x05, 0x71, 0x36,
|
||||
0x67, 0xe9, 0x69, 0xb1, 0x95, 0x18, 0xc3, 0x94, 0xd4, 0xd2, 0x68, 0xa9, 0x1c, 0x1f, 0x7b, 0xf4,
|
||||
0xa3, 0xf1, 0x1a, 0x66, 0x42, 0x2b, 0x47, 0xca, 0xbd, 0xbb, 0xce, 0x10, 0x9f, 0x78, 0x7e, 0x36,
|
||||
0xf4, 0x5e, 0x3b, 0x43, 0x88, 0x10, 0x54, 0x7a, 0xd9, 0xf1, 0x60, 0xce, 0xd2, 0x59, 0xe1, 0xeb,
|
||||
0xe4, 0x0a, 0xa6, 0x05, 0x59, 0xa3, 0x95, 0xdd, 0x71, 0xf6, 0x8b, 0xbf, 0x41, 0xf4, 0x44, 0xd6,
|
||||
0x96, 0x35, 0xe1, 0x05, 0x9c, 0x38, 0x6d, 0xa4, 0x18, 0xb6, 0xea, 0xc5, 0xbf, 0xb9, 0xe3, 0xc3,
|
||||
0x73, 0x27, 0x3b, 0xdf, 0xbb, 0x2f, 0x06, 0x61, 0xee, 0xbf, 0x8e, 0x0f, 0x10, 0xe4, 0x65, 0xd3,
|
||||
0x20, 0xcf, 0xfe, 0x84, 0x92, 0x0d, 0x89, 0xc4, 0x97, 0x7b, 0x48, 0xbf, 0x73, 0x32, 0xc2, 0x1c,
|
||||
0xc2, 0x17, 0xd7, 0x52, 0xb9, 0x3a, 0xd2, 0x20, 0x65, 0xb7, 0x0c, 0x1f, 0x21, 0x7a, 0x5e, 0x57,
|
||||
0x8d, 0xb4, 0x1f, 0x7b, 0x5c, 0x86, 0x00, 0xe2, 0x83, 0x24, 0x19, 0x55, 0xa1, 0xbf, 0xeb, 0xfd,
|
||||
0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x76, 0x1f, 0x51, 0x03, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -218,59 +218,59 @@ var _ grpc.ClientConn
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// MicroClient is the client API for Micro service.
|
||||
// ClientClient is the client API for Client service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type MicroClient interface {
|
||||
type ClientClient interface {
|
||||
// Call allows a single request to be made
|
||||
Call(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
|
||||
// Stream is a bidirectional stream
|
||||
Stream(ctx context.Context, opts ...grpc.CallOption) (Micro_StreamClient, error)
|
||||
Stream(ctx context.Context, opts ...grpc.CallOption) (Client_StreamClient, error)
|
||||
// Publish publishes a message and returns an empty Message
|
||||
Publish(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error)
|
||||
}
|
||||
|
||||
type microClient struct {
|
||||
type clientClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewMicroClient(cc *grpc.ClientConn) MicroClient {
|
||||
return µClient{cc}
|
||||
func NewClientClient(cc *grpc.ClientConn) ClientClient {
|
||||
return &clientClient{cc}
|
||||
}
|
||||
|
||||
func (c *microClient) Call(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
|
||||
func (c *clientClient) Call(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.client.Micro/Call", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.client.Client/Call", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *microClient) Stream(ctx context.Context, opts ...grpc.CallOption) (Micro_StreamClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_Micro_serviceDesc.Streams[0], "/go.micro.client.Micro/Stream", opts...)
|
||||
func (c *clientClient) Stream(ctx context.Context, opts ...grpc.CallOption) (Client_StreamClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_Client_serviceDesc.Streams[0], "/go.micro.client.Client/Stream", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := µStreamClient{stream}
|
||||
x := &clientStreamClient{stream}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type Micro_StreamClient interface {
|
||||
type Client_StreamClient interface {
|
||||
Send(*Request) error
|
||||
Recv() (*Response, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type microStreamClient struct {
|
||||
type clientStreamClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *microStreamClient) Send(m *Request) error {
|
||||
func (x *clientStreamClient) Send(m *Request) error {
|
||||
return x.ClientStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *microStreamClient) Recv() (*Response, error) {
|
||||
func (x *clientStreamClient) Recv() (*Response, error) {
|
||||
m := new(Response)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
@@ -278,66 +278,66 @@ func (x *microStreamClient) Recv() (*Response, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *microClient) Publish(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) {
|
||||
func (c *clientClient) Publish(ctx context.Context, in *Message, opts ...grpc.CallOption) (*Message, error) {
|
||||
out := new(Message)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.client.Micro/Publish", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.client.Client/Publish", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// MicroServer is the server API for Micro service.
|
||||
type MicroServer interface {
|
||||
// ClientServer is the server API for Client service.
|
||||
type ClientServer interface {
|
||||
// Call allows a single request to be made
|
||||
Call(context.Context, *Request) (*Response, error)
|
||||
// Stream is a bidirectional stream
|
||||
Stream(Micro_StreamServer) error
|
||||
Stream(Client_StreamServer) error
|
||||
// Publish publishes a message and returns an empty Message
|
||||
Publish(context.Context, *Message) (*Message, error)
|
||||
}
|
||||
|
||||
func RegisterMicroServer(s *grpc.Server, srv MicroServer) {
|
||||
s.RegisterService(&_Micro_serviceDesc, srv)
|
||||
func RegisterClientServer(s *grpc.Server, srv ClientServer) {
|
||||
s.RegisterService(&_Client_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Micro_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Client_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MicroServer).Call(ctx, in)
|
||||
return srv.(ClientServer).Call(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.client.Micro/Call",
|
||||
FullMethod: "/go.micro.client.Client/Call",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MicroServer).Call(ctx, req.(*Request))
|
||||
return srv.(ClientServer).Call(ctx, req.(*Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Micro_Stream_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(MicroServer).Stream(µStreamServer{stream})
|
||||
func _Client_Stream_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
return srv.(ClientServer).Stream(&clientStreamServer{stream})
|
||||
}
|
||||
|
||||
type Micro_StreamServer interface {
|
||||
type Client_StreamServer interface {
|
||||
Send(*Response) error
|
||||
Recv() (*Request, error)
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type microStreamServer struct {
|
||||
type clientStreamServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *microStreamServer) Send(m *Response) error {
|
||||
func (x *clientStreamServer) Send(m *Response) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func (x *microStreamServer) Recv() (*Request, error) {
|
||||
func (x *clientStreamServer) Recv() (*Request, error) {
|
||||
m := new(Request)
|
||||
if err := x.ServerStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
@@ -345,41 +345,41 @@ func (x *microStreamServer) Recv() (*Request, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func _Micro_Publish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Client_Publish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Message)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MicroServer).Publish(ctx, in)
|
||||
return srv.(ClientServer).Publish(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.client.Micro/Publish",
|
||||
FullMethod: "/go.micro.client.Client/Publish",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MicroServer).Publish(ctx, req.(*Message))
|
||||
return srv.(ClientServer).Publish(ctx, req.(*Message))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Micro_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "go.micro.client.Micro",
|
||||
HandlerType: (*MicroServer)(nil),
|
||||
var _Client_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "go.micro.client.Client",
|
||||
HandlerType: (*ClientServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Call",
|
||||
Handler: _Micro_Call_Handler,
|
||||
Handler: _Client_Call_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Publish",
|
||||
Handler: _Micro_Publish_Handler,
|
||||
Handler: _Client_Publish_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Stream",
|
||||
Handler: _Micro_Stream_Handler,
|
||||
Handler: _Client_Stream_Handler,
|
||||
ServerStreams: true,
|
||||
ClientStreams: true,
|
||||
},
|
||||
|
@@ -2,8 +2,8 @@ syntax = "proto3";
|
||||
|
||||
package go.micro.client;
|
||||
|
||||
// Micro is the micro client interface
|
||||
service Micro {
|
||||
// Client is the micro client interface
|
||||
service Client {
|
||||
// Call allows a single request to be made
|
||||
rpc Call(Request) returns (Response) {};
|
||||
// Stream is a bidirectional stream
|
||||
|
@@ -96,19 +96,22 @@ func (r *rpcClient) call(ctx context.Context, node *registry.Node, req Request,
|
||||
}
|
||||
}
|
||||
|
||||
var grr error
|
||||
c, err := r.pool.Get(address, transport.WithTimeout(opts.DialTimeout))
|
||||
dOpts := []transport.DialOption{
|
||||
transport.WithStream(),
|
||||
}
|
||||
|
||||
if opts.DialTimeout >= 0 {
|
||||
dOpts = append(dOpts, transport.WithTimeout(opts.DialTimeout))
|
||||
}
|
||||
|
||||
c, err := r.pool.Get(address, dOpts...)
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", "connection error: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
// defer execution of release
|
||||
r.pool.Release(c, grr)
|
||||
}()
|
||||
|
||||
seq := atomic.LoadUint64(&r.seq)
|
||||
atomic.AddUint64(&r.seq, 1)
|
||||
codec := newRpcCodec(msg, c, cf)
|
||||
codec := newRpcCodec(msg, c, cf, "")
|
||||
|
||||
rsp := &rpcResponse{
|
||||
socket: c,
|
||||
@@ -116,15 +119,19 @@ func (r *rpcClient) call(ctx context.Context, node *registry.Node, req Request,
|
||||
}
|
||||
|
||||
stream := &rpcStream{
|
||||
id: fmt.Sprintf("%v", seq),
|
||||
context: ctx,
|
||||
request: req,
|
||||
response: rsp,
|
||||
codec: codec,
|
||||
closed: make(chan bool),
|
||||
id: fmt.Sprintf("%v", seq),
|
||||
release: func(err error) { r.pool.Release(c, err) },
|
||||
sendEOS: false,
|
||||
}
|
||||
// close the stream on exiting this function
|
||||
defer stream.Close()
|
||||
|
||||
// wait for error response
|
||||
ch := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
@@ -150,14 +157,26 @@ func (r *rpcClient) call(ctx context.Context, node *registry.Node, req Request,
|
||||
ch <- nil
|
||||
}()
|
||||
|
||||
var grr error
|
||||
|
||||
select {
|
||||
case err := <-ch:
|
||||
grr = err
|
||||
return err
|
||||
case <-ctx.Done():
|
||||
grr = ctx.Err()
|
||||
return errors.Timeout("go.micro.client", fmt.Sprintf("%v", ctx.Err()))
|
||||
grr = errors.Timeout("go.micro.client", fmt.Sprintf("%v", ctx.Err()))
|
||||
}
|
||||
|
||||
// set the stream error
|
||||
if grr != nil {
|
||||
stream.Lock()
|
||||
stream.err = grr
|
||||
stream.Unlock()
|
||||
|
||||
return grr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *rpcClient) stream(ctx context.Context, node *registry.Node, req Request, opts CallOptions) (Stream, error) {
|
||||
@@ -201,12 +220,18 @@ func (r *rpcClient) stream(ctx context.Context, node *registry.Node, req Request
|
||||
dOpts = append(dOpts, transport.WithTimeout(opts.DialTimeout))
|
||||
}
|
||||
|
||||
c, err := r.opts.Transport.Dial(address, dOpts...)
|
||||
c, err := r.pool.Get(address, dOpts...)
|
||||
if err != nil {
|
||||
return nil, errors.InternalServerError("go.micro.client", "connection error: %v", err)
|
||||
}
|
||||
|
||||
codec := newRpcCodec(msg, c, cf)
|
||||
// increment the sequence number
|
||||
seq := atomic.LoadUint64(&r.seq)
|
||||
atomic.AddUint64(&r.seq, 1)
|
||||
id := fmt.Sprintf("%v", seq)
|
||||
|
||||
// create codec with stream id
|
||||
codec := newRpcCodec(msg, c, cf, id)
|
||||
|
||||
rsp := &rpcResponse{
|
||||
socket: c,
|
||||
@@ -219,16 +244,24 @@ func (r *rpcClient) stream(ctx context.Context, node *registry.Node, req Request
|
||||
}
|
||||
|
||||
stream := &rpcStream{
|
||||
id: id,
|
||||
context: ctx,
|
||||
request: req,
|
||||
response: rsp,
|
||||
closed: make(chan bool),
|
||||
codec: codec,
|
||||
// used to close the stream
|
||||
closed: make(chan bool),
|
||||
// signal the end of stream,
|
||||
sendEOS: true,
|
||||
// release func
|
||||
release: func(err error) { r.pool.Release(c, err) },
|
||||
}
|
||||
|
||||
// wait for error response
|
||||
ch := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
// send the first message
|
||||
ch <- stream.Send(req.Body())
|
||||
}()
|
||||
|
||||
@@ -242,6 +275,12 @@ func (r *rpcClient) stream(ctx context.Context, node *registry.Node, req Request
|
||||
}
|
||||
|
||||
if grr != nil {
|
||||
// set the error
|
||||
stream.Lock()
|
||||
stream.err = grr
|
||||
stream.Unlock()
|
||||
|
||||
// close the stream
|
||||
stream.Close()
|
||||
return nil, grr
|
||||
}
|
||||
@@ -312,10 +351,11 @@ func (r *rpcClient) next(request Request, opts CallOptions) (selector.Next, erro
|
||||
|
||||
// get next nodes from the selector
|
||||
next, err := r.opts.Selector.Select(service, opts.SelectOptions...)
|
||||
if err != nil && err == selector.ErrNotFound {
|
||||
return nil, errors.NotFound("go.micro.client", "service %s: %v", service, err.Error())
|
||||
} else if err != nil {
|
||||
return nil, errors.InternalServerError("go.micro.client", "error selecting %s node: %v", service, err.Error())
|
||||
if err != nil {
|
||||
if err == selector.ErrNotFound {
|
||||
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())
|
||||
}
|
||||
return nil, errors.InternalServerError("go.micro.client", "error selecting %s node: %s", service, err.Error())
|
||||
}
|
||||
|
||||
return next, nil
|
||||
@@ -375,15 +415,17 @@ func (r *rpcClient) Call(ctx context.Context, request Request, response interfac
|
||||
|
||||
// select next node
|
||||
node, err := next()
|
||||
if err != nil && err == selector.ErrNotFound {
|
||||
return errors.NotFound("go.micro.client", "service %s: %v", request.Service(), err.Error())
|
||||
} else if err != nil {
|
||||
return errors.InternalServerError("go.micro.client", "error getting next %s node: %v", request.Service(), err.Error())
|
||||
service := request.Service()
|
||||
if err != nil {
|
||||
if err == selector.ErrNotFound {
|
||||
return errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())
|
||||
}
|
||||
return errors.InternalServerError("go.micro.client", "error getting next %s node: %s", service, err.Error())
|
||||
}
|
||||
|
||||
// make the call
|
||||
err = rcall(ctx, node, request, response, callOpts)
|
||||
r.opts.Selector.Mark(request.Service(), node, err)
|
||||
r.opts.Selector.Mark(service, node, err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -452,14 +494,16 @@ func (r *rpcClient) Stream(ctx context.Context, request Request, opts ...CallOpt
|
||||
}
|
||||
|
||||
node, err := next()
|
||||
if err != nil && err == selector.ErrNotFound {
|
||||
return nil, errors.NotFound("go.micro.client", "service %s: %v", request.Service(), err.Error())
|
||||
} else if err != nil {
|
||||
return nil, errors.InternalServerError("go.micro.client", "error getting next %s node: %v", request.Service(), err.Error())
|
||||
service := request.Service()
|
||||
if err != nil {
|
||||
if err == selector.ErrNotFound {
|
||||
return nil, errors.InternalServerError("go.micro.client", "service %s: %s", service, err.Error())
|
||||
}
|
||||
return nil, errors.InternalServerError("go.micro.client", "error getting next %s node: %s", service, err.Error())
|
||||
}
|
||||
|
||||
stream, err := r.stream(ctx, node, request, callOpts)
|
||||
r.opts.Selector.Mark(request.Service(), node, err)
|
||||
r.opts.Selector.Mark(service, node, err)
|
||||
return stream, err
|
||||
}
|
||||
|
||||
|
@@ -39,6 +39,9 @@ type rpcCodec struct {
|
||||
|
||||
req *transport.Message
|
||||
buf *readWriteCloser
|
||||
|
||||
// signify if its a stream
|
||||
stream string
|
||||
}
|
||||
|
||||
type readWriteCloser struct {
|
||||
@@ -113,7 +116,7 @@ func getHeaders(m *codec.Message) {
|
||||
}
|
||||
}
|
||||
|
||||
func setHeaders(m *codec.Message) {
|
||||
func setHeaders(m *codec.Message, stream string) {
|
||||
set := func(hdr, v string) {
|
||||
if len(v) == 0 {
|
||||
return
|
||||
@@ -126,6 +129,11 @@ func setHeaders(m *codec.Message) {
|
||||
set("Micro-Service", m.Target)
|
||||
set("Micro-Method", m.Method)
|
||||
set("Micro-Endpoint", m.Endpoint)
|
||||
set("Micro-Error", m.Error)
|
||||
|
||||
if len(stream) > 0 {
|
||||
set("Micro-Stream", stream)
|
||||
}
|
||||
}
|
||||
|
||||
// setupProtocol sets up the old protocol
|
||||
@@ -149,7 +157,7 @@ func setupProtocol(msg *transport.Message, node *registry.Node) codec.NewCodec {
|
||||
return defaultCodecs[msg.Header["Content-Type"]]
|
||||
}
|
||||
|
||||
func newRpcCodec(req *transport.Message, client transport.Client, c codec.NewCodec) codec.Codec {
|
||||
func newRpcCodec(req *transport.Message, client transport.Client, c codec.NewCodec, stream string) codec.Codec {
|
||||
rwc := &readWriteCloser{
|
||||
wbuf: bytes.NewBuffer(nil),
|
||||
rbuf: bytes.NewBuffer(nil),
|
||||
@@ -159,6 +167,7 @@ func newRpcCodec(req *transport.Message, client transport.Client, c codec.NewCod
|
||||
client: client,
|
||||
codec: c(rwc),
|
||||
req: req,
|
||||
stream: stream,
|
||||
}
|
||||
return r
|
||||
}
|
||||
@@ -177,7 +186,7 @@ func (c *rpcCodec) Write(m *codec.Message, body interface{}) error {
|
||||
}
|
||||
|
||||
// set the mucp headers
|
||||
setHeaders(m)
|
||||
setHeaders(m, c.stream)
|
||||
|
||||
// if body is bytes Frame don't encode
|
||||
if body != nil {
|
||||
@@ -240,6 +249,12 @@ func (c *rpcCodec) ReadHeader(m *codec.Message, r codec.MessageType) error {
|
||||
|
||||
func (c *rpcCodec) ReadBody(b interface{}) error {
|
||||
// read body
|
||||
// read raw data
|
||||
if v, ok := b.(*raw.Frame); ok {
|
||||
v.Data = c.buf.rbuf.Bytes()
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := c.codec.ReadBody(b); err != nil {
|
||||
return errors.InternalServerError("go.micro.client.codec", err.Error())
|
||||
}
|
||||
|
@@ -18,6 +18,12 @@ type rpcStream struct {
|
||||
response Response
|
||||
codec codec.Codec
|
||||
context context.Context
|
||||
|
||||
// signal whether we should send EOS
|
||||
sendEOS bool
|
||||
|
||||
// release releases the connection back to the pool
|
||||
release func(err error)
|
||||
}
|
||||
|
||||
func (r *rpcStream) isClosed() bool {
|
||||
@@ -120,6 +126,26 @@ func (r *rpcStream) Close() error {
|
||||
return nil
|
||||
default:
|
||||
close(r.closed)
|
||||
return r.codec.Close()
|
||||
|
||||
// send the end of stream message
|
||||
if r.sendEOS {
|
||||
// no need to check for error
|
||||
r.codec.Write(&codec.Message{
|
||||
Id: r.id,
|
||||
Target: r.request.Service(),
|
||||
Method: r.request.Method(),
|
||||
Endpoint: r.request.Endpoint(),
|
||||
Type: codec.Error,
|
||||
Error: lastStreamResponseError,
|
||||
}, nil)
|
||||
}
|
||||
|
||||
err := r.codec.Close()
|
||||
|
||||
// release the connection
|
||||
r.release(r.Error())
|
||||
|
||||
// return the codec error
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@@ -51,6 +51,9 @@ func (c *registrySelector) Select(service string, opts ...SelectOption) (Next, e
|
||||
// if that fails go directly to the registry
|
||||
services, err := c.rc.GetService(service)
|
||||
if err != nil {
|
||||
if err == registry.ErrNotFound {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@@ -9,9 +9,9 @@ import (
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/client/selector"
|
||||
"github.com/micro/go-micro/network/router"
|
||||
pb "github.com/micro/go-micro/network/router/proto"
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/router"
|
||||
pb "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
type routerSelector struct {
|
||||
|
@@ -89,9 +89,22 @@ func (c *Codec) Write(m *codec.Message, b interface{}) error {
|
||||
m.Header[":authority"] = m.Target
|
||||
m.Header["content-type"] = c.ContentType
|
||||
case codec.Response:
|
||||
m.Header["Trailer"] = "grpc-status, grpc-message"
|
||||
m.Header["Trailer"] = "grpc-status" //, grpc-message"
|
||||
m.Header["content-type"] = c.ContentType
|
||||
m.Header[":status"] = "200"
|
||||
m.Header["grpc-status"] = "0"
|
||||
m.Header["grpc-message"] = ""
|
||||
// m.Header["grpc-message"] = ""
|
||||
case codec.Error:
|
||||
m.Header["Trailer"] = "grpc-status, grpc-message"
|
||||
// micro end of stream
|
||||
if m.Error == "EOS" {
|
||||
m.Header["grpc-status"] = "0"
|
||||
} else {
|
||||
m.Header["grpc-message"] = m.Error
|
||||
m.Header["grpc-status"] = "13"
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// marshal content
|
||||
|
@@ -42,6 +42,7 @@ import (
|
||||
tgrpc "github.com/micro/go-micro/transport/grpc"
|
||||
thttp "github.com/micro/go-micro/transport/http"
|
||||
tmem "github.com/micro/go-micro/transport/memory"
|
||||
"github.com/micro/go-micro/transport/quic"
|
||||
)
|
||||
|
||||
type Cmd interface {
|
||||
@@ -211,6 +212,7 @@ var (
|
||||
"memory": tmem.NewTransport,
|
||||
"http": thttp.NewTransport,
|
||||
"grpc": tgrpc.NewTransport,
|
||||
"quic": quic.NewTransport,
|
||||
}
|
||||
|
||||
// used for default selection as the fall back
|
||||
|
@@ -12,6 +12,10 @@ import (
|
||||
"github.com/micro/go-micro/config/source/file"
|
||||
)
|
||||
|
||||
var (
|
||||
sep = string(os.PathSeparator)
|
||||
)
|
||||
|
||||
func createFileForIssue18(t *testing.T, content string) *os.File {
|
||||
data := []byte(content)
|
||||
path := filepath.Join(os.TempDir(), fmt.Sprintf("file.%d", time.Now().UnixNano()))
|
||||
|
@@ -44,6 +44,6 @@ Load the source into config
|
||||
// Create new config
|
||||
conf := config.NewConfig()
|
||||
|
||||
// Load file source
|
||||
// Load consul source
|
||||
conf.Load(consulSource)
|
||||
```
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package consul
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/consul/api"
|
||||
@@ -80,7 +79,7 @@ func (w *watcher) Next() (*source.ChangeSet, error) {
|
||||
case cs := <-w.ch:
|
||||
return cs, nil
|
||||
case <-w.exit:
|
||||
return nil, errors.New("watcher stopped")
|
||||
return nil, source.ErrWatcherStopped
|
||||
}
|
||||
}
|
||||
|
||||
|
2
config/source/env/README.md
vendored
2
config/source/env/README.md
vendored
@@ -91,6 +91,6 @@ Load the source into config
|
||||
// Create new config
|
||||
conf := config.NewConfig()
|
||||
|
||||
// Load file source
|
||||
// Load env source
|
||||
conf.Load(src)
|
||||
```
|
||||
|
6
config/source/env/env_test.go
vendored
6
config/source/env/env_test.go
vendored
@@ -86,8 +86,8 @@ func TestEnvvar_Prefixes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEnvvar_WatchNextNoOpsUntilStop(t *testing.T) {
|
||||
source := NewSource(WithStrippedPrefix("GOMICRO_"))
|
||||
w, err := source.Watch()
|
||||
src := NewSource(WithStrippedPrefix("GOMICRO_"))
|
||||
w, err := src.Watch()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func TestEnvvar_WatchNextNoOpsUntilStop(t *testing.T) {
|
||||
w.Stop()
|
||||
}()
|
||||
|
||||
if _, err := w.Next(); err.Error() != "watcher stopped" {
|
||||
if _, err := w.Next(); err != source.ErrWatcherStopped {
|
||||
t.Errorf("expected watcher stopped error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
4
config/source/env/watcher.go
vendored
4
config/source/env/watcher.go
vendored
@@ -1,8 +1,6 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/micro/go-micro/config/source"
|
||||
)
|
||||
|
||||
@@ -13,7 +11,7 @@ type watcher struct {
|
||||
func (w *watcher) Next() (*source.ChangeSet, error) {
|
||||
<-w.exit
|
||||
|
||||
return nil, errors.New("watcher stopped")
|
||||
return nil, source.ErrWatcherStopped
|
||||
}
|
||||
|
||||
func (w *watcher) Stop() error {
|
||||
|
@@ -1,7 +1,8 @@
|
||||
//+build !linux
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
@@ -34,7 +35,7 @@ func (w *watcher) Next() (*source.ChangeSet, error) {
|
||||
// is it closed?
|
||||
select {
|
||||
case <-w.exit:
|
||||
return nil, errors.New("watcher stopped")
|
||||
return nil, source.ErrWatcherStopped
|
||||
default:
|
||||
}
|
||||
|
||||
@@ -57,7 +58,7 @@ func (w *watcher) Next() (*source.ChangeSet, error) {
|
||||
case err := <-w.fw.Errors:
|
||||
return nil, err
|
||||
case <-w.exit:
|
||||
return nil, errors.New("watcher stopped")
|
||||
return nil, source.ErrWatcherStopped
|
||||
}
|
||||
}
|
||||
|
||||
|
71
config/source/file/watcher_linux.go
Normal file
71
config/source/file/watcher_linux.go
Normal file
@@ -0,0 +1,71 @@
|
||||
//+build linux
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/micro/go-micro/config/source"
|
||||
)
|
||||
|
||||
type watcher struct {
|
||||
f *file
|
||||
|
||||
fw *fsnotify.Watcher
|
||||
exit chan bool
|
||||
}
|
||||
|
||||
func newWatcher(f *file) (source.Watcher, error) {
|
||||
fw, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fw.Add(f.path)
|
||||
|
||||
return &watcher{
|
||||
f: f,
|
||||
fw: fw,
|
||||
exit: make(chan bool),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (w *watcher) Next() (*source.ChangeSet, error) {
|
||||
// is it closed?
|
||||
select {
|
||||
case <-w.exit:
|
||||
return nil, source.ErrWatcherStopped
|
||||
default:
|
||||
}
|
||||
|
||||
// try get the event
|
||||
select {
|
||||
case event, _ := <-w.fw.Events:
|
||||
if event.Op == fsnotify.Rename {
|
||||
// check existence of file, and add watch again
|
||||
_, err := os.Stat(event.Name)
|
||||
if err == nil || os.IsExist(err) {
|
||||
w.fw.Add(event.Name)
|
||||
}
|
||||
}
|
||||
|
||||
c, err := w.f.Read()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// add path again for the event bug of fsnotify
|
||||
w.fw.Add(w.f.path)
|
||||
|
||||
return c, nil
|
||||
case err := <-w.fw.Errors:
|
||||
return nil, err
|
||||
case <-w.exit:
|
||||
return nil, source.ErrWatcherStopped
|
||||
}
|
||||
}
|
||||
|
||||
func (w *watcher) Stop() error {
|
||||
return w.fw.Close()
|
||||
}
|
@@ -42,6 +42,6 @@ Load the source into config
|
||||
// Create new config
|
||||
conf := config.NewConfig()
|
||||
|
||||
// Load file source
|
||||
// Load flag source
|
||||
conf.Load(flagSource)
|
||||
```
|
||||
|
@@ -27,7 +27,7 @@ Specify source with data
|
||||
|
||||
```go
|
||||
memorySource := memory.NewSource(
|
||||
memory.WithData(data),
|
||||
memory.WithJSON(data),
|
||||
)
|
||||
```
|
||||
|
||||
@@ -39,6 +39,6 @@ Load the source into config
|
||||
// Create new config
|
||||
conf := config.NewConfig()
|
||||
|
||||
// Load file source
|
||||
// Load memory source
|
||||
conf.Load(memorySource)
|
||||
```
|
||||
|
@@ -18,6 +18,7 @@ type memory struct {
|
||||
func (s *memory) Read() (*source.ChangeSet, error) {
|
||||
s.RLock()
|
||||
cs := &source.ChangeSet{
|
||||
Format: s.ChangeSet.Format,
|
||||
Timestamp: s.ChangeSet.Timestamp,
|
||||
Data: s.ChangeSet.Data,
|
||||
Checksum: s.ChangeSet.Checksum,
|
||||
|
@@ -2,9 +2,15 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrWatcherStopped is returned when source watcher has been stopped
|
||||
ErrWatcherStopped = errors.New("watcher stopped")
|
||||
)
|
||||
|
||||
// Source is the source from which config is loaded
|
||||
type Source interface {
|
||||
Read() (*ChangeSet, error)
|
||||
|
41
debug/handler/debug.go
Normal file
41
debug/handler/debug.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
proto "github.com/micro/go-micro/debug/proto"
|
||||
)
|
||||
|
||||
type Debug struct {
|
||||
proto.DebugHandler
|
||||
started int64
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultHandler = newDebug()
|
||||
)
|
||||
|
||||
func newDebug() *Debug {
|
||||
return &Debug{
|
||||
started: time.Now().Unix(),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Debug) Health(ctx context.Context, req *proto.HealthRequest, rsp *proto.HealthResponse) error {
|
||||
rsp.Status = "ok"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Debug) Stats(ctx context.Context, req *proto.StatsRequest, rsp *proto.StatsResponse) error {
|
||||
var mstat runtime.MemStats
|
||||
runtime.ReadMemStats(&mstat)
|
||||
|
||||
rsp.Started = uint64(d.started)
|
||||
rsp.Uptime = uint64(time.Now().Unix() - d.started)
|
||||
rsp.Memory = mstat.Alloc
|
||||
rsp.Gc = mstat.PauseTotalNs
|
||||
rsp.Threads = uint64(runtime.NumGoroutine())
|
||||
return nil
|
||||
}
|
108
debug/proto/debug.micro.go
Normal file
108
debug/proto/debug.micro.go
Normal file
@@ -0,0 +1,108 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: micro/go-micro/debug/proto/debug.proto
|
||||
|
||||
package debug
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
import (
|
||||
context "context"
|
||||
client "github.com/micro/go-micro/client"
|
||||
server "github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Client API for Debug service
|
||||
|
||||
type DebugService interface {
|
||||
Health(ctx context.Context, in *HealthRequest, opts ...client.CallOption) (*HealthResponse, error)
|
||||
Stats(ctx context.Context, in *StatsRequest, opts ...client.CallOption) (*StatsResponse, error)
|
||||
}
|
||||
|
||||
type debugService struct {
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewDebugService(name string, c client.Client) DebugService {
|
||||
if c == nil {
|
||||
c = client.NewClient()
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = "debug"
|
||||
}
|
||||
return &debugService{
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *debugService) Health(ctx context.Context, in *HealthRequest, opts ...client.CallOption) (*HealthResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Debug.Health", in)
|
||||
out := new(HealthResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *debugService) Stats(ctx context.Context, in *StatsRequest, opts ...client.CallOption) (*StatsResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Debug.Stats", in)
|
||||
out := new(StatsResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Debug service
|
||||
|
||||
type DebugHandler interface {
|
||||
Health(context.Context, *HealthRequest, *HealthResponse) error
|
||||
Stats(context.Context, *StatsRequest, *StatsResponse) error
|
||||
}
|
||||
|
||||
func RegisterDebugHandler(s server.Server, hdlr DebugHandler, opts ...server.HandlerOption) error {
|
||||
type debug interface {
|
||||
Health(ctx context.Context, in *HealthRequest, out *HealthResponse) error
|
||||
Stats(ctx context.Context, in *StatsRequest, out *StatsResponse) error
|
||||
}
|
||||
type Debug struct {
|
||||
debug
|
||||
}
|
||||
h := &debugHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&Debug{h}, opts...))
|
||||
}
|
||||
|
||||
type debugHandler struct {
|
||||
DebugHandler
|
||||
}
|
||||
|
||||
func (h *debugHandler) Health(ctx context.Context, in *HealthRequest, out *HealthResponse) error {
|
||||
return h.DebugHandler.Health(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *debugHandler) Stats(ctx context.Context, in *StatsRequest, out *StatsResponse) error {
|
||||
return h.DebugHandler.Stats(ctx, in, out)
|
||||
}
|
336
debug/proto/debug.pb.go
Normal file
336
debug/proto/debug.pb.go
Normal file
@@ -0,0 +1,336 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: micro/go-micro/debug/proto/debug.proto
|
||||
|
||||
package debug
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type HealthRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HealthRequest) Reset() { *m = HealthRequest{} }
|
||||
func (m *HealthRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*HealthRequest) ProtoMessage() {}
|
||||
func (*HealthRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f25415e61bccfa1f, []int{0}
|
||||
}
|
||||
|
||||
func (m *HealthRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HealthRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HealthRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HealthRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *HealthRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HealthRequest.Merge(m, src)
|
||||
}
|
||||
func (m *HealthRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_HealthRequest.Size(m)
|
||||
}
|
||||
func (m *HealthRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HealthRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HealthRequest proto.InternalMessageInfo
|
||||
|
||||
type HealthResponse struct {
|
||||
// default: ok
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HealthResponse) Reset() { *m = HealthResponse{} }
|
||||
func (m *HealthResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*HealthResponse) ProtoMessage() {}
|
||||
func (*HealthResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f25415e61bccfa1f, []int{1}
|
||||
}
|
||||
|
||||
func (m *HealthResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HealthResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HealthResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HealthResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *HealthResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HealthResponse.Merge(m, src)
|
||||
}
|
||||
func (m *HealthResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_HealthResponse.Size(m)
|
||||
}
|
||||
func (m *HealthResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HealthResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HealthResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *HealthResponse) GetStatus() string {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type StatsRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *StatsRequest) Reset() { *m = StatsRequest{} }
|
||||
func (m *StatsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatsRequest) ProtoMessage() {}
|
||||
func (*StatsRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f25415e61bccfa1f, []int{2}
|
||||
}
|
||||
|
||||
func (m *StatsRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_StatsRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *StatsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_StatsRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *StatsRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_StatsRequest.Merge(m, src)
|
||||
}
|
||||
func (m *StatsRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_StatsRequest.Size(m)
|
||||
}
|
||||
func (m *StatsRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_StatsRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_StatsRequest proto.InternalMessageInfo
|
||||
|
||||
type StatsResponse struct {
|
||||
// unix timestamp
|
||||
Started uint64 `protobuf:"varint,1,opt,name=started,proto3" json:"started,omitempty"`
|
||||
// in seconds
|
||||
Uptime uint64 `protobuf:"varint,2,opt,name=uptime,proto3" json:"uptime,omitempty"`
|
||||
// in bytes
|
||||
Memory uint64 `protobuf:"varint,3,opt,name=memory,proto3" json:"memory,omitempty"`
|
||||
// num threads
|
||||
Threads uint64 `protobuf:"varint,4,opt,name=threads,proto3" json:"threads,omitempty"`
|
||||
// total gc in nanoseconds
|
||||
Gc uint64 `protobuf:"varint,5,opt,name=gc,proto3" json:"gc,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *StatsResponse) Reset() { *m = StatsResponse{} }
|
||||
func (m *StatsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatsResponse) ProtoMessage() {}
|
||||
func (*StatsResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f25415e61bccfa1f, []int{3}
|
||||
}
|
||||
|
||||
func (m *StatsResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_StatsResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *StatsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_StatsResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *StatsResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_StatsResponse.Merge(m, src)
|
||||
}
|
||||
func (m *StatsResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_StatsResponse.Size(m)
|
||||
}
|
||||
func (m *StatsResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_StatsResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_StatsResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *StatsResponse) GetStarted() uint64 {
|
||||
if m != nil {
|
||||
return m.Started
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetUptime() uint64 {
|
||||
if m != nil {
|
||||
return m.Uptime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetMemory() uint64 {
|
||||
if m != nil {
|
||||
return m.Memory
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetThreads() uint64 {
|
||||
if m != nil {
|
||||
return m.Threads
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *StatsResponse) GetGc() uint64 {
|
||||
if m != nil {
|
||||
return m.Gc
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*HealthRequest)(nil), "HealthRequest")
|
||||
proto.RegisterType((*HealthResponse)(nil), "HealthResponse")
|
||||
proto.RegisterType((*StatsRequest)(nil), "StatsRequest")
|
||||
proto.RegisterType((*StatsResponse)(nil), "StatsResponse")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("micro/go-micro/debug/proto/debug.proto", fileDescriptor_f25415e61bccfa1f)
|
||||
}
|
||||
|
||||
var fileDescriptor_f25415e61bccfa1f = []byte{
|
||||
// 230 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0x41, 0x4b, 0xc4, 0x30,
|
||||
0x10, 0x85, 0xb7, 0x75, 0x5b, 0x71, 0xb0, 0x59, 0xc8, 0x41, 0xc2, 0x9e, 0x24, 0x07, 0x29, 0x88,
|
||||
0x59, 0xd0, 0xbf, 0xe0, 0xc1, 0x73, 0xbd, 0x0b, 0xd9, 0x76, 0xe8, 0x16, 0xac, 0xa9, 0x99, 0xe9,
|
||||
0xc1, 0xb3, 0x7f, 0x5c, 0x9a, 0xa4, 0x60, 0x6f, 0xef, 0xbd, 0xf0, 0x1e, 0xf9, 0x06, 0x1e, 0xc6,
|
||||
0xa1, 0xf5, 0xee, 0xd4, 0xbb, 0xa7, 0x28, 0x3a, 0x3c, 0xcf, 0xfd, 0x69, 0xf2, 0x8e, 0x93, 0x36,
|
||||
0x41, 0xeb, 0x03, 0x54, 0x6f, 0x68, 0x3f, 0xf9, 0xd2, 0xe0, 0xf7, 0x8c, 0xc4, 0xba, 0x06, 0xb1,
|
||||
0x06, 0x34, 0xb9, 0x2f, 0x42, 0x79, 0x07, 0x25, 0xb1, 0xe5, 0x99, 0x54, 0x76, 0x9f, 0xd5, 0x37,
|
||||
0x4d, 0x72, 0x5a, 0xc0, 0xed, 0x3b, 0x5b, 0xa6, 0xb5, 0xf9, 0x9b, 0x41, 0x95, 0x82, 0xd4, 0x54,
|
||||
0x70, 0x4d, 0x6c, 0x3d, 0x63, 0x17, 0xaa, 0xfb, 0x66, 0xb5, 0xcb, 0xe6, 0x3c, 0xf1, 0x30, 0xa2,
|
||||
0xca, 0xc3, 0x43, 0x72, 0x4b, 0x3e, 0xe2, 0xe8, 0xfc, 0x8f, 0xba, 0x8a, 0x79, 0x74, 0xcb, 0x12,
|
||||
0x5f, 0x3c, 0xda, 0x8e, 0xd4, 0x3e, 0x2e, 0x25, 0x2b, 0x05, 0xe4, 0x7d, 0xab, 0x8a, 0x10, 0xe6,
|
||||
0x7d, 0xfb, 0xfc, 0x01, 0xc5, 0xeb, 0xc2, 0x27, 0x1f, 0xa1, 0x8c, 0x20, 0x52, 0x98, 0x0d, 0xe2,
|
||||
0xf1, 0x60, 0xb6, 0x84, 0x7a, 0x27, 0x6b, 0x28, 0xc2, 0xd7, 0x65, 0x65, 0xfe, 0x33, 0x1d, 0x85,
|
||||
0xd9, 0x10, 0xe9, 0xdd, 0xb9, 0x0c, 0x77, 0x7b, 0xf9, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xb9,
|
||||
0x5f, 0xf7, 0x61, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// DebugClient is the client API for Debug service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type DebugClient interface {
|
||||
Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error)
|
||||
Stats(ctx context.Context, in *StatsRequest, opts ...grpc.CallOption) (*StatsResponse, error)
|
||||
}
|
||||
|
||||
type debugClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewDebugClient(cc *grpc.ClientConn) DebugClient {
|
||||
return &debugClient{cc}
|
||||
}
|
||||
|
||||
func (c *debugClient) Health(ctx context.Context, in *HealthRequest, opts ...grpc.CallOption) (*HealthResponse, error) {
|
||||
out := new(HealthResponse)
|
||||
err := c.cc.Invoke(ctx, "/Debug/Health", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *debugClient) Stats(ctx context.Context, in *StatsRequest, opts ...grpc.CallOption) (*StatsResponse, error) {
|
||||
out := new(StatsResponse)
|
||||
err := c.cc.Invoke(ctx, "/Debug/Stats", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DebugServer is the server API for Debug service.
|
||||
type DebugServer interface {
|
||||
Health(context.Context, *HealthRequest) (*HealthResponse, error)
|
||||
Stats(context.Context, *StatsRequest) (*StatsResponse, error)
|
||||
}
|
||||
|
||||
func RegisterDebugServer(s *grpc.Server, srv DebugServer) {
|
||||
s.RegisterService(&_Debug_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Debug_Health_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(HealthRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DebugServer).Health(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/Debug/Health",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DebugServer).Health(ctx, req.(*HealthRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Debug_Stats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(StatsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(DebugServer).Stats(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/Debug/Stats",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(DebugServer).Stats(ctx, req.(*StatsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Debug_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "Debug",
|
||||
HandlerType: (*DebugServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Health",
|
||||
Handler: _Debug_Health_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Stats",
|
||||
Handler: _Debug_Stats_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "micro/go-micro/debug/proto/debug.proto",
|
||||
}
|
@@ -1,13 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// This is commented out due to import cycles.
|
||||
// But its what we expect the RPC service to
|
||||
// return.
|
||||
//
|
||||
// service Debug {
|
||||
// rpc Health(HealthRequest) returns (HealthResponse) {}
|
||||
// rpc Stats(StatsRequest) returns (StatsResponse) {}
|
||||
// }
|
||||
service Debug {
|
||||
rpc Health(HealthRequest) returns (HealthResponse) {}
|
||||
rpc Stats(StatsRequest) returns (StatsResponse) {}
|
||||
}
|
||||
|
||||
message HealthRequest {
|
||||
}
|
@@ -5,8 +5,8 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
proto "github.com/micro/go-micro/debug/proto"
|
||||
"github.com/micro/go-micro/registry/memory"
|
||||
proto "github.com/micro/go-micro/server/debug/proto"
|
||||
)
|
||||
|
||||
func TestFunction(t *testing.T) {
|
||||
|
48
go.mod
48
go.mod
@@ -3,8 +3,9 @@ module github.com/micro/go-micro
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.41.0 // indirect
|
||||
cloud.google.com/go v0.44.0 // indirect
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/Microsoft/go-winio v0.4.14 // indirect
|
||||
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect
|
||||
github.com/armon/go-radix v1.0.0 // indirect
|
||||
@@ -14,17 +15,17 @@ require (
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
|
||||
github.com/forestgiant/sliceutil v0.0.0-20160425183142-94783f95db6c
|
||||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/fsouza/go-dockerclient v1.4.1
|
||||
github.com/fsouza/go-dockerclient v1.4.2
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/gliderlabs/ssh v0.2.2 // indirect
|
||||
github.com/go-kit/kit v0.9.0 // indirect
|
||||
github.com/go-log/log v0.1.0
|
||||
github.com/go-playground/locales v0.12.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.16.0 // indirect
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/google/go-cmp v0.3.1 // indirect
|
||||
github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/gorilla/handlers v1.4.1
|
||||
github.com/gorilla/mux v1.7.3 // indirect
|
||||
github.com/gorilla/handlers v1.4.2
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/hashicorp/consul/api v1.1.0
|
||||
github.com/hashicorp/go-immutable-radix v1.1.0 // indirect
|
||||
@@ -33,26 +34,28 @@ require (
|
||||
github.com/hashicorp/go-rootcerts v1.0.1 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||
github.com/hashicorp/go-version v1.2.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.3 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0
|
||||
github.com/hashicorp/mdns v1.0.1 // indirect
|
||||
github.com/hashicorp/memberlist v0.1.4
|
||||
github.com/hashicorp/serf v0.8.3 // indirect
|
||||
github.com/imdario/mergo v0.3.7
|
||||
github.com/joncalhoun/qson v0.0.0-20170526102502-8a9cab3a62b1
|
||||
github.com/json-iterator/go v1.1.6
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c // indirect
|
||||
github.com/json-iterator/go v1.1.7
|
||||
github.com/kisielk/errcheck v1.2.0 // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/kr/pty v1.1.8 // indirect
|
||||
github.com/leodido/go-urn v1.1.0 // indirect
|
||||
github.com/lucas-clemente/quic-go v0.7.1-0.20190710050138-1441923ab031
|
||||
github.com/lucas-clemente/quic-go v0.12.0
|
||||
github.com/mattn/go-colorable v0.1.2 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
||||
github.com/micro/cli v0.2.0
|
||||
github.com/micro/mdns v0.2.0
|
||||
github.com/micro/mdns v0.3.0
|
||||
github.com/miekg/dns v1.1.15 // indirect
|
||||
github.com/mitchellh/gox v1.0.1 // indirect
|
||||
github.com/mitchellh/hashstructure v1.0.0
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/nats-io/nats.go v1.8.1
|
||||
github.com/nats-io/nkeys v0.1.0 // indirect
|
||||
github.com/nlopes/slack v0.5.0
|
||||
@@ -61,24 +64,17 @@ require (
|
||||
github.com/onsi/gomega v1.5.0 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/posener/complete v1.2.1 // indirect
|
||||
github.com/prometheus/common v0.6.0 // indirect
|
||||
github.com/prometheus/procfs v0.0.3 // indirect
|
||||
github.com/prometheus/client_golang v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
|
||||
golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f // indirect
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9 // indirect
|
||||
golang.org/x/mobile v0.0.0-20190711165009-e47acb2ca7f9 // indirect
|
||||
golang.org/x/mod v0.1.0 // indirect
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7
|
||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 // indirect
|
||||
golang.org/x/tools v0.0.0-20190711191110-9a621aea19f8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532 // indirect
|
||||
google.golang.org/grpc v1.22.0
|
||||
gopkg.in/go-playground/validator.v9 v9.29.0
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.1 // indirect
|
||||
gopkg.in/src-d/go-git.v4 v4.12.0
|
||||
golang.org/x/mobile v0.0.0-20190806162312-597adff16ade // indirect
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80
|
||||
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e // indirect
|
||||
golang.org/x/tools v0.0.0-20190809145639-6d4652c779c4 // indirect
|
||||
google.golang.org/grpc v1.22.1
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1
|
||||
gopkg.in/telegram-bot-api.v4 v4.6.4
|
||||
honnef.co/go/tools v0.0.0-20190614002413-cb51c254f01b // indirect
|
||||
honnef.co/go/tools v0.0.1-2019.2.2 // indirect
|
||||
)
|
||||
|
66
go.sum
66
go.sum
@@ -3,15 +3,22 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.40.0/go.mod h1:Tk58MuI9rbLMKlAjeO/bDnteAx7tX2gJIXw4T5Jwlro=
|
||||
cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg=
|
||||
cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg=
|
||||
cloud.google.com/go v0.44.0/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.13/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
@@ -26,6 +33,7 @@ github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
@@ -43,8 +51,12 @@ github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v0.7.3-0.20190309235953-33c3200e0d16 h1:dmUn0SuGx7unKFwxyeQ/oLUHhEfZosEDrpmYM+6MTuc=
|
||||
github.com/docker/docker v0.7.3-0.20190309235953-33c3200e0d16/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b h1:+Ga+YpCDpcY1fln6GI0fiiirpqHGcob5/Vk3oKNuGdU=
|
||||
github.com/docker/docker v1.4.2-0.20190710153559-aa8249ae1b8b/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
@@ -61,6 +73,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsouza/go-dockerclient v1.4.1 h1:W7wuJ3IB48WYZv/UBk9dCTIb9oX805+L9KIm65HcUYs=
|
||||
github.com/fsouza/go-dockerclient v1.4.1/go.mod h1:PUNHxbowDqRXfRgZqMz1OeGtbWC6VKyZvJ99hDjB0qs=
|
||||
github.com/fsouza/go-dockerclient v1.4.2 h1:dl6GfIWS5Qn4C6OfSnnoe6YuOV8lvKAE8W/YD1Q7udo=
|
||||
github.com/fsouza/go-dockerclient v1.4.2/go.mod h1:COunfLZrsdwX/j3YVDAG8gIw3KutrI0x1+vGEJ5zxdI=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
@@ -96,9 +110,12 @@ github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190723021845-34ac40c74b70/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -108,6 +125,8 @@ github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZs
|
||||
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.4.1 h1:BHvcRGJe/TrL+OqFxoKQGddTgeibiOjaBssV5a/N9sw=
|
||||
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
@@ -150,6 +169,8 @@ github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCO
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
@@ -174,12 +195,16 @@ github.com/joncalhoun/qson v0.0.0-20170526102502-8a9cab3a62b1 h1:lnrOS18wZBYrzdD
|
||||
github.com/joncalhoun/qson v0.0.0-20170526102502-8a9cab3a62b1/go.mod h1:DFXrEwSRX0p/aSvxE21319menCBFeQO0jXpRj7LEZUA=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c h1:VAx3LRNjVNvjtgO7KFRuT/3aye/0zJvwn01rHSfoolo=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@@ -197,6 +222,8 @@ github.com/lucas-clemente/quic-go v0.7.1-0.20190710050138-1441923ab031 h1:wjcGvg
|
||||
github.com/lucas-clemente/quic-go v0.7.1-0.20190710050138-1441923ab031/go.mod h1:lb5aAxL68VvhZ00e7yYuQVK/9FLggtYy4qo7oI5qzqA=
|
||||
github.com/lucas-clemente/quic-go v0.11.2 h1:Mop0ac3zALaBR3wGs6j8OYe/tcFvFsxTUFMkE/7yUOI=
|
||||
github.com/lucas-clemente/quic-go v0.11.2/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
|
||||
github.com/lucas-clemente/quic-go v0.12.0 h1:dYHUyB50gEQlK3KqytmNySzuyzAcaQ3iuI2ZReAfVrE=
|
||||
github.com/lucas-clemente/quic-go v0.12.0/go.mod h1:UXJJPE4RfFef/xPO5wQm0tITK8gNfqwTxjbE7s3Vb8s=
|
||||
github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI=
|
||||
github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA=
|
||||
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
@@ -204,6 +231,8 @@ github.com/marten-seemann/qtls v0.2.4 h1:mCJ6i1jAqcsm9XODrSGvXECodoAb1STta+TkxJC
|
||||
github.com/marten-seemann/qtls v0.2.4/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
github.com/marten-seemann/qtls v0.3.1 h1:ySYIvhFjFY2JsNHY6VACvomMEDy3EvdPA6yciUFAiHw=
|
||||
github.com/marten-seemann/qtls v0.3.1/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
github.com/marten-seemann/qtls v0.3.2 h1:O7awy4bHEzSX/K3h+fZig3/Vo03s/RxlxgsAk9sYamI=
|
||||
github.com/marten-seemann/qtls v0.3.2/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
@@ -219,6 +248,8 @@ github.com/micro/mdns v0.1.1-0.20190729112526-ef68c9635478 h1:L6jnZZ763dMLlvst8P
|
||||
github.com/micro/mdns v0.1.1-0.20190729112526-ef68c9635478/go.mod h1:KJ0dW7KmicXU2BV++qkLlmHYcVv7/hHnbtguSWt9Aoc=
|
||||
github.com/micro/mdns v0.2.0 h1:/+/n2PSiJURrXsBIGtfCz0hex/XYKqVsn51GAGdFrOE=
|
||||
github.com/micro/mdns v0.2.0/go.mod h1:KJ0dW7KmicXU2BV++qkLlmHYcVv7/hHnbtguSWt9Aoc=
|
||||
github.com/micro/mdns v0.3.0 h1:bYycYe+98AXR3s8Nq5qvt6C573uFTDPIYzJemWON0QE=
|
||||
github.com/micro/mdns v0.3.0/go.mod h1:KJ0dW7KmicXU2BV++qkLlmHYcVv7/hHnbtguSWt9Aoc=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
|
||||
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
@@ -241,11 +272,14 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/nats.go v1.8.1 h1:6lF/f1/NN6kzUDBz6pyvQDEXO39jqXcWRLu/tKjtOUQ=
|
||||
github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM=
|
||||
github.com/nats-io/nkeys v0.0.2 h1:+qM7QpgXnvDDixitZtQUBDY9w/s9mu1ghS+JIbsrx6M=
|
||||
@@ -282,6 +316,7 @@ github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DK
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
@@ -301,6 +336,7 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
|
||||
@@ -339,9 +375,11 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190618124811-92942e4437e2/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -350,6 +388,7 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20190711165009-e47acb2ca7f9/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20190806162312-597adff16ade/go.mod h1:AlhUtkH4DA4asiFC5RgK7ZKmauvtkAVcy9L0epCzlWo=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -375,6 +414,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwL
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -408,6 +449,12 @@ golang.org/x/sys v0.0.0-20190621062556-bf70e4678053/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ=
|
||||
golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa h1:KIDDMLT1O0Nr7TSxp8xM5tJcdn8tgyAONntO829og1M=
|
||||
golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e h1:TsjK5I7fXk8f2FQrgu6NS7i5Qih3knl2FL1htyguLRE=
|
||||
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -429,12 +476,19 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20190530171427-2b03ca6e44eb/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190620191750-1fa568393b23/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190710184609-286818132824/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190711191110-9a621aea19f8/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190807201305-8be58fba6352/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190809145639-6d4652c779c4/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -452,12 +506,17 @@ google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dT
|
||||
google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532 h1:5pOB7se0B2+IssELuQUs6uoBgYJenkU2AQlvopc2sRw=
|
||||
google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@@ -465,18 +524,24 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.0 h1:5ofssLNYgAA/inWn6rTZ4juWpRJUwEnXc1LG2IeXwgQ=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo=
|
||||
gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.0 h1:KtlZ4c1OWbIs4jCv5ZXrTqG8EQocr0g/d4DjNg70aek=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.1 h1:OkK1DmefDy1Z6Veu82wdNj/cLpYORhdX4qdaYCPwc7s=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||
gopkg.in/src-d/go-git.v4 v4.11.0 h1:cJwWgJ0DXifrNrXM6RGN1Y2yR60Rr1zQ9Q5DX5S9qgU=
|
||||
gopkg.in/src-d/go-git.v4 v4.11.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk=
|
||||
gopkg.in/src-d/go-git.v4 v4.12.0 h1:CKgvBCJCcdfNnyXPYI4Cp8PaDDAmAPEN0CtfEdEAbd8=
|
||||
gopkg.in/src-d/go-git.v4 v4.12.0/go.mod h1:zjlNnzc1Wjn43v3Mtii7RVxiReNP0fIu9npcXKzuNp4=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
|
||||
gopkg.in/telegram-bot-api.v4 v4.6.4 h1:hpHWhzn4jTCsAJZZ2loNKfy2QWyPDRJVl3aTFXeMW8g=
|
||||
gopkg.in/telegram-bot-api.v4 v4.6.4/go.mod h1:5DpGO5dbumb40px+dXcwCpcjmeHNYLpk0bp3XRNvWDM=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
@@ -491,4 +556,5 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190614002413-cb51c254f01b/go.mod h1:JlmFZigtG9vBVR3QGIQ9g/Usz4BzH+Xm6Z8iHQWRYUw=
|
||||
honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
|
318
monitor/default.go
Normal file
318
monitor/default.go
Normal file
@@ -0,0 +1,318 @@
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
pb "github.com/micro/go-micro/debug/proto"
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/registry/cache"
|
||||
)
|
||||
|
||||
type monitor struct {
|
||||
options Options
|
||||
|
||||
exit chan bool
|
||||
registry cache.Cache
|
||||
client client.Client
|
||||
|
||||
sync.RWMutex
|
||||
running bool
|
||||
services map[string]*Status
|
||||
}
|
||||
|
||||
// check provides binary running/failed status.
|
||||
// In the event Debug.Health cannot be called on a service we reap the node.
|
||||
func (m *monitor) check(service string) (*Status, error) {
|
||||
services, err := m.registry.GetService(service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create debug client
|
||||
debug := pb.NewDebugService(service, m.client)
|
||||
|
||||
var status *Status
|
||||
var gerr error
|
||||
|
||||
// iterate through multiple versions of a service
|
||||
for _, service := range services {
|
||||
for _, node := range service.Nodes {
|
||||
// TODO: checks that are not just RPC based
|
||||
// TODO: better matching of the protocol
|
||||
// TODO: maybe everything has to be a go-micro service?
|
||||
if node.Metadata["server"] != m.client.String() {
|
||||
continue
|
||||
}
|
||||
|
||||
rsp, err := debug.Health(
|
||||
context.Background(),
|
||||
// empty health request
|
||||
&pb.HealthRequest{},
|
||||
// call this specific node
|
||||
client.WithAddress(node.Address),
|
||||
// retry in the event of failure
|
||||
client.WithRetries(3),
|
||||
)
|
||||
if err != nil {
|
||||
// reap the dead node
|
||||
m.registry.Deregister(®istry.Service{
|
||||
Name: service.Name,
|
||||
Version: service.Version,
|
||||
Nodes: []*registry.Node{node},
|
||||
})
|
||||
|
||||
// save the error
|
||||
gerr = err
|
||||
continue
|
||||
}
|
||||
|
||||
// expecting ok response status
|
||||
if rsp.Status != "ok" {
|
||||
gerr = errors.New(rsp.Status)
|
||||
continue
|
||||
}
|
||||
|
||||
// no error set status
|
||||
status = &Status{
|
||||
Code: StatusRunning,
|
||||
Info: "running",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we got the success case return it
|
||||
if status != nil {
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// if gerr is not nil return it
|
||||
if gerr != nil {
|
||||
return &Status{
|
||||
Code: StatusFailed,
|
||||
Info: "not running",
|
||||
Error: gerr.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// otherwise unknown status
|
||||
return &Status{
|
||||
Code: StatusUnknown,
|
||||
Info: "unknown status",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *monitor) reap() {
|
||||
services, err := m.registry.ListServices()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
serviceMap := make(map[string]bool)
|
||||
for _, service := range services {
|
||||
serviceMap[service.Name] = true
|
||||
}
|
||||
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
// range over our watched services
|
||||
for service, _ := range m.services {
|
||||
// check if the service exists in the registry
|
||||
if !serviceMap[service] {
|
||||
// if not, delete it in our status map
|
||||
delete(m.services, service)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *monitor) run() {
|
||||
// check the status every tick
|
||||
t := time.NewTicker(time.Minute)
|
||||
defer t.Stop()
|
||||
|
||||
// reap dead services
|
||||
t2 := time.NewTicker(time.Hour)
|
||||
defer t2.Stop()
|
||||
|
||||
// list the known services
|
||||
services, _ := m.registry.ListServices()
|
||||
|
||||
// create a check chan of same length
|
||||
check := make(chan string, len(services))
|
||||
|
||||
// front-load the services to watch
|
||||
for _, service := range services {
|
||||
check <- service.Name
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
// exit if we're told to
|
||||
case <-m.exit:
|
||||
return
|
||||
// check a service when told to
|
||||
case service := <-check:
|
||||
// check the status
|
||||
status, err := m.check(service)
|
||||
if err != nil {
|
||||
status = &Status{
|
||||
Code: StatusUnknown,
|
||||
Info: "unknown status",
|
||||
}
|
||||
}
|
||||
|
||||
// save the status
|
||||
m.Lock()
|
||||
m.services[service] = status
|
||||
m.Unlock()
|
||||
// on the tick interval get all services and issue a check
|
||||
case <-t.C:
|
||||
// create a list of services
|
||||
serviceMap := make(map[string]bool)
|
||||
|
||||
m.RLock()
|
||||
for service, _ := range m.services {
|
||||
serviceMap[service] = true
|
||||
}
|
||||
m.RUnlock()
|
||||
|
||||
go func() {
|
||||
// check the status of all watched services
|
||||
for service, _ := range serviceMap {
|
||||
select {
|
||||
case <-m.exit:
|
||||
return
|
||||
case check <- service:
|
||||
default:
|
||||
// barf if we block
|
||||
}
|
||||
}
|
||||
|
||||
// list services
|
||||
services, _ := m.registry.ListServices()
|
||||
|
||||
for _, service := range services {
|
||||
// start watching the service
|
||||
if ok := serviceMap[service.Name]; !ok {
|
||||
m.Watch(service.Name)
|
||||
}
|
||||
}
|
||||
}()
|
||||
case <-t2.C:
|
||||
// reap any dead/non-existent services
|
||||
m.reap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *monitor) Reap(service string) error {
|
||||
services, err := m.registry.GetService(service)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
delete(m.services, service)
|
||||
for _, service := range services {
|
||||
m.registry.Deregister(service)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *monitor) Status(service string) (Status, error) {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
if status, ok := m.services[service]; ok {
|
||||
return *status, nil
|
||||
}
|
||||
return Status{}, ErrNotWatching
|
||||
}
|
||||
|
||||
func (m *monitor) Watch(service string) error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
// check if we're watching
|
||||
if _, ok := m.services[service]; ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// get the status
|
||||
status, err := m.check(service)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set the status
|
||||
m.services[service] = status
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *monitor) Run() error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
if m.running {
|
||||
return nil
|
||||
}
|
||||
|
||||
// reset the exit channel
|
||||
m.exit = make(chan bool)
|
||||
// setup a new cache
|
||||
m.registry = cache.New(m.options.Registry)
|
||||
|
||||
// start running
|
||||
go m.run()
|
||||
|
||||
// set to running
|
||||
m.running = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *monitor) Stop() error {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
if !m.running {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-m.exit:
|
||||
return nil
|
||||
default:
|
||||
close(m.exit)
|
||||
for s, _ := range m.services {
|
||||
delete(m.services, s)
|
||||
}
|
||||
m.registry.Stop()
|
||||
m.running = false
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newMonitor(opts ...Option) Monitor {
|
||||
options := Options{
|
||||
Client: client.DefaultClient,
|
||||
Registry: registry.DefaultRegistry,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
return &monitor{
|
||||
options: options,
|
||||
exit: make(chan bool),
|
||||
client: options.Client,
|
||||
registry: cache.New(options.Registry),
|
||||
services: make(map[string]*Status),
|
||||
}
|
||||
}
|
37
monitor/default_test.go
Normal file
37
monitor/default_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMonitor(t *testing.T) {
|
||||
// create new monitor
|
||||
m := NewMonitor()
|
||||
|
||||
if err := m.Run(); err != nil {
|
||||
t.Fatalf("failed to stop monitor: %v", err)
|
||||
}
|
||||
|
||||
services := []string{"foo", "bar", "baz"}
|
||||
|
||||
for _, service := range services {
|
||||
_, err := m.Status(service)
|
||||
if err == nil {
|
||||
t.Fatal("expected status error for unknown service")
|
||||
}
|
||||
|
||||
if err := m.Watch(service); err == nil {
|
||||
t.Fatal("expected watch error for unknown service")
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// 1. start a service
|
||||
// 2. watch service
|
||||
// 3. get service status
|
||||
}
|
||||
|
||||
// stop monitor
|
||||
if err := m.Stop(); err != nil {
|
||||
t.Fatalf("failed to stop monitor: %v", err)
|
||||
}
|
||||
}
|
43
monitor/monitor.go
Normal file
43
monitor/monitor.go
Normal file
@@ -0,0 +1,43 @@
|
||||
// Package monitor monitors service health
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
const (
|
||||
StatusUnknown StatusCode = iota
|
||||
StatusRunning
|
||||
StatusFailed
|
||||
)
|
||||
|
||||
type StatusCode int
|
||||
|
||||
// Monitor monitors a service and reaps dead instances
|
||||
type Monitor interface {
|
||||
// Reap a service and stop monitoring
|
||||
Reap(service string) error
|
||||
// Status of the service
|
||||
Status(service string) (Status, error)
|
||||
// Watch starts watching the service
|
||||
Watch(service string) error
|
||||
// Run the monitor to watch all services
|
||||
Run() error
|
||||
// Stop monitoring
|
||||
Stop() error
|
||||
}
|
||||
|
||||
type Status struct {
|
||||
Code StatusCode
|
||||
Info string
|
||||
Error string
|
||||
}
|
||||
|
||||
var (
|
||||
ErrNotWatching = errors.New("not watching")
|
||||
)
|
||||
|
||||
// NewMonitor returns a new monitor
|
||||
func NewMonitor(opts ...Option) Monitor {
|
||||
return newMonitor(opts...)
|
||||
}
|
25
monitor/options.go
Normal file
25
monitor/options.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/registry"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Client client.Client
|
||||
Registry registry.Registry
|
||||
}
|
||||
|
||||
type Option func(*Options)
|
||||
|
||||
func Client(c client.Client) Option {
|
||||
return func(o *Options) {
|
||||
o.Client = c
|
||||
}
|
||||
}
|
||||
|
||||
func Registry(r registry.Registry) Option {
|
||||
return func(o *Options) {
|
||||
o.Registry = r
|
||||
}
|
||||
}
|
1005
network/default.go
Normal file
1005
network/default.go
Normal file
File diff suppressed because it is too large
Load Diff
111
network/handler/handler.go
Normal file
111
network/handler/handler.go
Normal file
@@ -0,0 +1,111 @@
|
||||
// Package handler implements network RPC handler
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/network"
|
||||
pbNet "github.com/micro/go-micro/network/proto"
|
||||
pbRtr "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
// Network implements network handler
|
||||
type Network struct {
|
||||
Network network.Network
|
||||
}
|
||||
|
||||
// ListRoutes returns a list of routing table routes
|
||||
func (n *Network) ListRoutes(ctx context.Context, req *pbRtr.Request, resp *pbRtr.ListResponse) error {
|
||||
routes, err := n.Network.Options().Router.Table().List()
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.network", "failed to list routes: %s", err)
|
||||
}
|
||||
|
||||
var respRoutes []*pbRtr.Route
|
||||
for _, route := range routes {
|
||||
respRoute := &pbRtr.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int64(route.Metric),
|
||||
}
|
||||
respRoutes = append(respRoutes, respRoute)
|
||||
}
|
||||
|
||||
resp.Routes = respRoutes
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListNodes returns a list of all accessible nodes in the network
|
||||
func (n *Network) ListNodes(ctx context.Context, req *pbNet.ListRequest, resp *pbNet.ListResponse) error {
|
||||
nodes := n.Network.Nodes()
|
||||
|
||||
var respNodes []*pbNet.Node
|
||||
for _, node := range nodes {
|
||||
respNode := &pbNet.Node{
|
||||
Id: node.Id(),
|
||||
Address: node.Address(),
|
||||
}
|
||||
respNodes = append(respNodes, respNode)
|
||||
}
|
||||
|
||||
resp.Nodes = respNodes
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Neighbourhood returns a list of immediate neighbours
|
||||
func (n *Network) Neighbourhood(ctx context.Context, req *pbNet.NeighbourhoodRequest, resp *pbNet.NeighbourhoodResponse) error {
|
||||
// extract the id of the node to query
|
||||
id := req.Id
|
||||
// if no id is passed, we assume local node
|
||||
if id == "" {
|
||||
id = n.Network.Id()
|
||||
}
|
||||
|
||||
// get all the nodes in the network
|
||||
nodes := n.Network.Nodes()
|
||||
|
||||
// sort the slice of nodes
|
||||
sort.Slice(nodes, func(i, j int) bool { return nodes[i].Id() <= nodes[j].Id() })
|
||||
// find a node with a given id
|
||||
i := sort.Search(len(nodes), func(j int) bool { return nodes[j].Id() >= id })
|
||||
|
||||
var neighbours []*pbNet.Node
|
||||
// collect all the nodes in the neighbourhood of the found node
|
||||
if i < len(nodes) && nodes[i].Id() == id {
|
||||
for _, neighbour := range nodes[i].Neighbourhood() {
|
||||
// don't return yourself in response
|
||||
if neighbour.Id() == n.Network.Id() {
|
||||
continue
|
||||
}
|
||||
pbNeighbour := &pbNet.Node{
|
||||
Id: neighbour.Id(),
|
||||
Address: neighbour.Address(),
|
||||
}
|
||||
neighbours = append(neighbours, pbNeighbour)
|
||||
}
|
||||
}
|
||||
|
||||
// requested neighbourhood node
|
||||
node := &pbNet.Node{
|
||||
Id: nodes[i].Id(),
|
||||
Address: nodes[i].Address(),
|
||||
}
|
||||
|
||||
// creaate neighbourhood answer
|
||||
neighbourhood := &pbNet.Neighbour{
|
||||
Node: node,
|
||||
Neighbours: neighbours,
|
||||
}
|
||||
|
||||
resp.Neighbourhood = neighbourhood
|
||||
|
||||
return nil
|
||||
}
|
60
network/network.go
Normal file
60
network/network.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Package network is for creating internetworks
|
||||
package network
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultName is default network name
|
||||
DefaultName = "go.micro"
|
||||
// DefaultAddress is default network address
|
||||
DefaultAddress = ":0"
|
||||
// ResolveTime defines time interval to periodically resolve network nodes
|
||||
ResolveTime = 1 * time.Minute
|
||||
// AnnounceTime defines time interval to periodically announce node neighbours
|
||||
AnnounceTime = 30 * time.Second
|
||||
// PruneTime defines time interval to periodically check nodes that need to be pruned
|
||||
// due to their not announcing their presence within this time interval
|
||||
PruneTime = 90 * time.Second
|
||||
)
|
||||
|
||||
// Node is network node
|
||||
type Node interface {
|
||||
// Id is node id
|
||||
Id() string
|
||||
// Address is node bind address
|
||||
Address() string
|
||||
// Neighbourhood is node neighbourhood
|
||||
Neighbourhood() []Node
|
||||
// Network is the network node is in
|
||||
Network() Network
|
||||
}
|
||||
|
||||
// Network is micro network
|
||||
type Network interface {
|
||||
// Node is network node
|
||||
Node
|
||||
// Options returns the network options
|
||||
Options() Options
|
||||
// Name of the network
|
||||
Name() string
|
||||
// Connect starts the resolver and tunnel server
|
||||
Connect() error
|
||||
// Nodes returns list of network nodes
|
||||
Nodes() []Node
|
||||
// Close stops the tunnel and resolving
|
||||
Close() error
|
||||
// Client is micro client
|
||||
Client() client.Client
|
||||
// Server is micro server
|
||||
Server() server.Server
|
||||
}
|
||||
|
||||
// NewNetwork returns a new network interface
|
||||
func NewNetwork(opts ...Option) Network {
|
||||
return newNetwork(opts...)
|
||||
}
|
103
network/options.go
Normal file
103
network/options.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/micro/go-micro/network/resolver"
|
||||
"github.com/micro/go-micro/network/resolver/registry"
|
||||
"github.com/micro/go-micro/proxy"
|
||||
"github.com/micro/go-micro/proxy/mucp"
|
||||
"github.com/micro/go-micro/router"
|
||||
"github.com/micro/go-micro/tunnel"
|
||||
)
|
||||
|
||||
type Option func(*Options)
|
||||
|
||||
// Options configure network
|
||||
type Options struct {
|
||||
// Id of the node
|
||||
Id string
|
||||
// Name of the network
|
||||
Name string
|
||||
// Address to bind to
|
||||
Address string
|
||||
// Nodes is a list of seed nodes
|
||||
Nodes []string
|
||||
// Tunnel is network tunnel
|
||||
Tunnel tunnel.Tunnel
|
||||
// Router is network router
|
||||
Router router.Router
|
||||
// Proxy is network proxy
|
||||
Proxy proxy.Proxy
|
||||
// Resolver is network resolver
|
||||
Resolver resolver.Resolver
|
||||
}
|
||||
|
||||
// Id sets the id of the network node
|
||||
func Id(id string) Option {
|
||||
return func(o *Options) {
|
||||
o.Id = id
|
||||
}
|
||||
}
|
||||
|
||||
// Name sets the network name
|
||||
func Name(n string) Option {
|
||||
return func(o *Options) {
|
||||
o.Name = n
|
||||
}
|
||||
}
|
||||
|
||||
// Address sets the network address
|
||||
func Address(a string) Option {
|
||||
return func(o *Options) {
|
||||
o.Address = a
|
||||
}
|
||||
}
|
||||
|
||||
// Nodes is a list of seed nodes used along
|
||||
// with resolved node
|
||||
func Nodes(n ...string) Option {
|
||||
return func(o *Options) {
|
||||
o.Nodes = n
|
||||
}
|
||||
}
|
||||
|
||||
// Tunnel sets the network tunnel
|
||||
func Tunnel(t tunnel.Tunnel) Option {
|
||||
return func(o *Options) {
|
||||
o.Tunnel = t
|
||||
}
|
||||
}
|
||||
|
||||
// Router sets the network router
|
||||
func Router(r router.Router) Option {
|
||||
return func(o *Options) {
|
||||
o.Router = r
|
||||
}
|
||||
}
|
||||
|
||||
// Proxy sets the network proxy
|
||||
func Proxy(p proxy.Proxy) Option {
|
||||
return func(o *Options) {
|
||||
o.Proxy = p
|
||||
}
|
||||
}
|
||||
|
||||
// Resolver is the network resolver
|
||||
func Resolver(r resolver.Resolver) Option {
|
||||
return func(o *Options) {
|
||||
o.Resolver = r
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultOptions returns network default options
|
||||
func DefaultOptions() Options {
|
||||
return Options{
|
||||
Id: uuid.New().String(),
|
||||
Name: DefaultName,
|
||||
Address: DefaultAddress,
|
||||
Tunnel: tunnel.NewTunnel(),
|
||||
Router: router.DefaultRouter,
|
||||
Proxy: mucp.NewProxy(),
|
||||
Resolver: ®istry.Resolver{},
|
||||
}
|
||||
}
|
126
network/proto/network.micro.go
Normal file
126
network/proto/network.micro.go
Normal file
@@ -0,0 +1,126 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: network.proto
|
||||
|
||||
package go_micro_network
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
proto1 "github.com/micro/go-micro/router/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
import (
|
||||
context "context"
|
||||
client "github.com/micro/go-micro/client"
|
||||
server "github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Client API for Network service
|
||||
|
||||
type NetworkService interface {
|
||||
ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error)
|
||||
ListNodes(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
|
||||
Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, opts ...client.CallOption) (*NeighbourhoodResponse, error)
|
||||
}
|
||||
|
||||
type networkService struct {
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewNetworkService(name string, c client.Client) NetworkService {
|
||||
if c == nil {
|
||||
c = client.NewClient()
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = "go.micro.network"
|
||||
}
|
||||
return &networkService{
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *networkService) ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Network.ListRoutes", in)
|
||||
out := new(proto1.ListResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *networkService) ListNodes(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Network.ListNodes", in)
|
||||
out := new(ListResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *networkService) Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, opts ...client.CallOption) (*NeighbourhoodResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Network.Neighbourhood", in)
|
||||
out := new(NeighbourhoodResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for Network service
|
||||
|
||||
type NetworkHandler interface {
|
||||
ListRoutes(context.Context, *proto1.Request, *proto1.ListResponse) error
|
||||
ListNodes(context.Context, *ListRequest, *ListResponse) error
|
||||
Neighbourhood(context.Context, *NeighbourhoodRequest, *NeighbourhoodResponse) error
|
||||
}
|
||||
|
||||
func RegisterNetworkHandler(s server.Server, hdlr NetworkHandler, opts ...server.HandlerOption) error {
|
||||
type network interface {
|
||||
ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error
|
||||
ListNodes(ctx context.Context, in *ListRequest, out *ListResponse) error
|
||||
Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, out *NeighbourhoodResponse) error
|
||||
}
|
||||
type Network struct {
|
||||
network
|
||||
}
|
||||
h := &networkHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&Network{h}, opts...))
|
||||
}
|
||||
|
||||
type networkHandler struct {
|
||||
NetworkHandler
|
||||
}
|
||||
|
||||
func (h *networkHandler) ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error {
|
||||
return h.NetworkHandler.ListRoutes(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *networkHandler) ListNodes(ctx context.Context, in *ListRequest, out *ListResponse) error {
|
||||
return h.NetworkHandler.ListNodes(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *networkHandler) Neighbourhood(ctx context.Context, in *NeighbourhoodRequest, out *NeighbourhoodResponse) error {
|
||||
return h.NetworkHandler.Neighbourhood(ctx, in, out)
|
||||
}
|
438
network/proto/network.pb.go
Normal file
438
network/proto/network.pb.go
Normal file
@@ -0,0 +1,438 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: network.proto
|
||||
|
||||
package go_micro_network
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
_ "github.com/micro/go-micro/router/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// Empty request
|
||||
type ListRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListRequest) Reset() { *m = ListRequest{} }
|
||||
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListRequest) ProtoMessage() {}
|
||||
func (*ListRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{0}
|
||||
}
|
||||
|
||||
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ListRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ListRequest.Size(m)
|
||||
}
|
||||
func (m *ListRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListRequest proto.InternalMessageInfo
|
||||
|
||||
// ListResponse is returned by ListNodes and ListNeighbours
|
||||
type ListResponse struct {
|
||||
Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListResponse) Reset() { *m = ListResponse{} }
|
||||
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListResponse) ProtoMessage() {}
|
||||
func (*ListResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{1}
|
||||
}
|
||||
|
||||
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ListResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ListResponse.Size(m)
|
||||
}
|
||||
func (m *ListResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ListResponse) GetNodes() []*Node {
|
||||
if m != nil {
|
||||
return m.Nodes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NeighbourhoodRequest is sent to query node neighbourhood
|
||||
type NeighbourhoodRequest struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *NeighbourhoodRequest) Reset() { *m = NeighbourhoodRequest{} }
|
||||
func (m *NeighbourhoodRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*NeighbourhoodRequest) ProtoMessage() {}
|
||||
func (*NeighbourhoodRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{2}
|
||||
}
|
||||
|
||||
func (m *NeighbourhoodRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_NeighbourhoodRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *NeighbourhoodRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_NeighbourhoodRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *NeighbourhoodRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_NeighbourhoodRequest.Merge(m, src)
|
||||
}
|
||||
func (m *NeighbourhoodRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_NeighbourhoodRequest.Size(m)
|
||||
}
|
||||
func (m *NeighbourhoodRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_NeighbourhoodRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_NeighbourhoodRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *NeighbourhoodRequest) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// NeighbourhoodResponse contains node neighbourhood hierarchy
|
||||
type NeighbourhoodResponse struct {
|
||||
Neighbourhood *Neighbour `protobuf:"bytes,1,opt,name=neighbourhood,proto3" json:"neighbourhood,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *NeighbourhoodResponse) Reset() { *m = NeighbourhoodResponse{} }
|
||||
func (m *NeighbourhoodResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*NeighbourhoodResponse) ProtoMessage() {}
|
||||
func (*NeighbourhoodResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{3}
|
||||
}
|
||||
|
||||
func (m *NeighbourhoodResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_NeighbourhoodResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *NeighbourhoodResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_NeighbourhoodResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *NeighbourhoodResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_NeighbourhoodResponse.Merge(m, src)
|
||||
}
|
||||
func (m *NeighbourhoodResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_NeighbourhoodResponse.Size(m)
|
||||
}
|
||||
func (m *NeighbourhoodResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_NeighbourhoodResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_NeighbourhoodResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *NeighbourhoodResponse) GetNeighbourhood() *Neighbour {
|
||||
if m != nil {
|
||||
return m.Neighbourhood
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Node is network node
|
||||
type Node struct {
|
||||
// node ide
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
// node address
|
||||
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Node) Reset() { *m = Node{} }
|
||||
func (m *Node) String() string { return proto.CompactTextString(m) }
|
||||
func (*Node) ProtoMessage() {}
|
||||
func (*Node) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{4}
|
||||
}
|
||||
|
||||
func (m *Node) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Node.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Node.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Node) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Node.Merge(m, src)
|
||||
}
|
||||
func (m *Node) XXX_Size() int {
|
||||
return xxx_messageInfo_Node.Size(m)
|
||||
}
|
||||
func (m *Node) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Node.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Node proto.InternalMessageInfo
|
||||
|
||||
func (m *Node) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Node) GetAddress() string {
|
||||
if m != nil {
|
||||
return m.Address
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Connect is sent when the node connects to the network
|
||||
type Connect struct {
|
||||
// network mode
|
||||
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Connect) Reset() { *m = Connect{} }
|
||||
func (m *Connect) String() string { return proto.CompactTextString(m) }
|
||||
func (*Connect) ProtoMessage() {}
|
||||
func (*Connect) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{5}
|
||||
}
|
||||
|
||||
func (m *Connect) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Connect.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Connect) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Connect.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Connect) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Connect.Merge(m, src)
|
||||
}
|
||||
func (m *Connect) XXX_Size() int {
|
||||
return xxx_messageInfo_Connect.Size(m)
|
||||
}
|
||||
func (m *Connect) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Connect.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Connect proto.InternalMessageInfo
|
||||
|
||||
func (m *Connect) GetNode() *Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close is sent when the node disconnects from the network
|
||||
type Close struct {
|
||||
// network node
|
||||
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Close) Reset() { *m = Close{} }
|
||||
func (m *Close) String() string { return proto.CompactTextString(m) }
|
||||
func (*Close) ProtoMessage() {}
|
||||
func (*Close) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{6}
|
||||
}
|
||||
|
||||
func (m *Close) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Close.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Close) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Close.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Close) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Close.Merge(m, src)
|
||||
}
|
||||
func (m *Close) XXX_Size() int {
|
||||
return xxx_messageInfo_Close.Size(m)
|
||||
}
|
||||
func (m *Close) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Close.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Close proto.InternalMessageInfo
|
||||
|
||||
func (m *Close) GetNode() *Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Solicit is sent when requesting route advertisement from the network nodes
|
||||
type Solicit struct {
|
||||
// network node
|
||||
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Solicit) Reset() { *m = Solicit{} }
|
||||
func (m *Solicit) String() string { return proto.CompactTextString(m) }
|
||||
func (*Solicit) ProtoMessage() {}
|
||||
func (*Solicit) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{7}
|
||||
}
|
||||
|
||||
func (m *Solicit) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Solicit.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Solicit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Solicit.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Solicit) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Solicit.Merge(m, src)
|
||||
}
|
||||
func (m *Solicit) XXX_Size() int {
|
||||
return xxx_messageInfo_Solicit.Size(m)
|
||||
}
|
||||
func (m *Solicit) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Solicit.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Solicit proto.InternalMessageInfo
|
||||
|
||||
func (m *Solicit) GetNode() *Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Neighbour is used to nnounce node neighbourhood
|
||||
type Neighbour struct {
|
||||
// network node
|
||||
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
|
||||
// neighbours
|
||||
Neighbours []*Node `protobuf:"bytes,3,rep,name=neighbours,proto3" json:"neighbours,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Neighbour) Reset() { *m = Neighbour{} }
|
||||
func (m *Neighbour) String() string { return proto.CompactTextString(m) }
|
||||
func (*Neighbour) ProtoMessage() {}
|
||||
func (*Neighbour) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_8571034d60397816, []int{8}
|
||||
}
|
||||
|
||||
func (m *Neighbour) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Neighbour.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Neighbour) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Neighbour.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Neighbour) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Neighbour.Merge(m, src)
|
||||
}
|
||||
func (m *Neighbour) XXX_Size() int {
|
||||
return xxx_messageInfo_Neighbour.Size(m)
|
||||
}
|
||||
func (m *Neighbour) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Neighbour.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Neighbour proto.InternalMessageInfo
|
||||
|
||||
func (m *Neighbour) GetNode() *Node {
|
||||
if m != nil {
|
||||
return m.Node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Neighbour) GetNeighbours() []*Node {
|
||||
if m != nil {
|
||||
return m.Neighbours
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ListRequest)(nil), "go.micro.network.ListRequest")
|
||||
proto.RegisterType((*ListResponse)(nil), "go.micro.network.ListResponse")
|
||||
proto.RegisterType((*NeighbourhoodRequest)(nil), "go.micro.network.NeighbourhoodRequest")
|
||||
proto.RegisterType((*NeighbourhoodResponse)(nil), "go.micro.network.NeighbourhoodResponse")
|
||||
proto.RegisterType((*Node)(nil), "go.micro.network.Node")
|
||||
proto.RegisterType((*Connect)(nil), "go.micro.network.Connect")
|
||||
proto.RegisterType((*Close)(nil), "go.micro.network.Close")
|
||||
proto.RegisterType((*Solicit)(nil), "go.micro.network.Solicit")
|
||||
proto.RegisterType((*Neighbour)(nil), "go.micro.network.Neighbour")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("network.proto", fileDescriptor_8571034d60397816) }
|
||||
|
||||
var fileDescriptor_8571034d60397816 = []byte{
|
||||
// 360 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x41, 0x4f, 0xf2, 0x40,
|
||||
0x10, 0xfd, 0x28, 0xf0, 0x35, 0x0c, 0x1f, 0x5f, 0xcc, 0x46, 0x4d, 0x53, 0x83, 0x21, 0x7b, 0x40,
|
||||
0x62, 0xb4, 0x18, 0x08, 0x9e, 0xbc, 0x18, 0x0e, 0x5e, 0x08, 0x87, 0x7a, 0xf3, 0x66, 0xbb, 0x9b,
|
||||
0xb2, 0x11, 0x3a, 0xb8, 0xbb, 0x8d, 0x7f, 0xc0, 0x1f, 0x6e, 0xba, 0x5d, 0xb0, 0x80, 0x60, 0xb8,
|
||||
0x75, 0xe6, 0xbd, 0x37, 0x6f, 0xa7, 0xfb, 0x16, 0x5a, 0x29, 0xd7, 0x1f, 0x28, 0xdf, 0x82, 0xa5,
|
||||
0x44, 0x8d, 0xe4, 0x24, 0xc1, 0x60, 0x21, 0x62, 0x89, 0x81, 0xed, 0xfb, 0xc3, 0x44, 0xe8, 0x59,
|
||||
0x16, 0x05, 0x31, 0x2e, 0xfa, 0x06, 0xe9, 0x27, 0x78, 0x5b, 0x7c, 0x48, 0xcc, 0x34, 0x97, 0x7d,
|
||||
0xa3, 0xb4, 0x45, 0x31, 0x86, 0xb6, 0xa0, 0x39, 0x11, 0x4a, 0x87, 0xfc, 0x3d, 0xe3, 0x4a, 0xd3,
|
||||
0x07, 0xf8, 0x57, 0x94, 0x6a, 0x89, 0xa9, 0xe2, 0xe4, 0x06, 0xea, 0x29, 0x32, 0xae, 0xbc, 0x4a,
|
||||
0xa7, 0xda, 0x6b, 0x0e, 0xce, 0x83, 0x6d, 0xd7, 0x60, 0x8a, 0x8c, 0x87, 0x05, 0x89, 0x76, 0xe1,
|
||||
0x74, 0xca, 0x45, 0x32, 0x8b, 0x30, 0x93, 0x33, 0x44, 0x66, 0xa7, 0x92, 0xff, 0xe0, 0x08, 0xe6,
|
||||
0x55, 0x3a, 0x95, 0x5e, 0x23, 0x74, 0x04, 0xa3, 0x2f, 0x70, 0xb6, 0xc5, 0xb3, 0x76, 0x8f, 0xf9,
|
||||
0x96, 0x25, 0xc0, 0x68, 0x9a, 0x83, 0x8b, 0x1f, 0x6c, 0x57, 0xb4, 0x70, 0x53, 0x41, 0xef, 0xa0,
|
||||
0x96, 0x1f, 0x69, 0xdb, 0x93, 0x78, 0xe0, 0xbe, 0x32, 0x26, 0xb9, 0x52, 0x9e, 0x63, 0x9a, 0xab,
|
||||
0x92, 0x8e, 0xc0, 0x1d, 0x63, 0x9a, 0xf2, 0x58, 0x93, 0x6b, 0xa8, 0xe5, 0x9b, 0x58, 0xdb, 0x7d,
|
||||
0xdb, 0x1a, 0x0e, 0x1d, 0x42, 0x7d, 0x3c, 0x47, 0xc5, 0x8f, 0x12, 0x8d, 0xc0, 0x7d, 0xc6, 0xb9,
|
||||
0x88, 0xc5, 0x71, 0x5e, 0x08, 0x8d, 0xf5, 0xc2, 0xc7, 0x08, 0xc9, 0x3d, 0xc0, 0xfa, 0xf7, 0x28,
|
||||
0xaf, 0x7a, 0xf0, 0x12, 0x4b, 0xcc, 0xc1, 0xa7, 0x03, 0xee, 0xb4, 0x00, 0xc9, 0x13, 0x80, 0xc9,
|
||||
0x44, 0x1e, 0x1b, 0x45, 0xbc, 0x6f, 0xb5, 0x0d, 0x92, 0xbd, 0x65, 0xbf, 0xbd, 0x83, 0x94, 0xa3,
|
||||
0x44, 0xff, 0x90, 0x09, 0x34, 0xf2, 0x4e, 0x6e, 0xa6, 0x48, 0x7b, 0xf7, 0x14, 0xa5, 0x20, 0xfa,
|
||||
0x97, 0xfb, 0xe0, 0xf5, 0xb4, 0x08, 0x5a, 0x1b, 0x21, 0x22, 0xdd, 0x03, 0x29, 0x29, 0xa5, 0xd1,
|
||||
0xbf, 0xfa, 0x95, 0xb7, 0xf2, 0x88, 0xfe, 0x9a, 0x47, 0x32, 0xfc, 0x0a, 0x00, 0x00, 0xff, 0xff,
|
||||
0x59, 0xcf, 0xab, 0xb5, 0x7c, 0x03, 0x00, 0x00,
|
||||
}
|
64
network/proto/network.proto
Normal file
64
network/proto/network.proto
Normal file
@@ -0,0 +1,64 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package go.micro.network;
|
||||
|
||||
import "github.com/micro/go-micro/router/proto/router.proto";
|
||||
|
||||
// Network service is usesd to gain visibility into networks
|
||||
service Network {
|
||||
rpc ListRoutes(go.micro.router.Request) returns (go.micro.router.ListResponse) {};
|
||||
rpc ListNodes(ListRequest) returns (ListResponse) {};
|
||||
rpc Neighbourhood(NeighbourhoodRequest) returns (NeighbourhoodResponse) {};
|
||||
}
|
||||
|
||||
// Empty request
|
||||
message ListRequest {}
|
||||
|
||||
// ListResponse is returned by ListNodes and ListNeighbours
|
||||
message ListResponse {
|
||||
repeated Node nodes = 1;
|
||||
}
|
||||
|
||||
// NeighbourhoodRequest is sent to query node neighbourhood
|
||||
message NeighbourhoodRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
// NeighbourhoodResponse contains node neighbourhood hierarchy
|
||||
message NeighbourhoodResponse {
|
||||
Neighbour neighbourhood = 1;
|
||||
}
|
||||
|
||||
// Node is network node
|
||||
message Node {
|
||||
// node ide
|
||||
string id = 1;
|
||||
// node address
|
||||
string address = 2;
|
||||
}
|
||||
|
||||
// Connect is sent when the node connects to the network
|
||||
message Connect {
|
||||
// network mode
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
// Close is sent when the node disconnects from the network
|
||||
message Close {
|
||||
// network node
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
// Solicit is sent when requesting route advertisement from the network nodes
|
||||
message Solicit {
|
||||
// network node
|
||||
Node node = 1;
|
||||
}
|
||||
|
||||
// Neighbour is used to nnounce node neighbourhood
|
||||
message Neighbour {
|
||||
// network node
|
||||
Node node = 1;
|
||||
// neighbours
|
||||
repeated Node neighbours = 3;
|
||||
}
|
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/micro/go-micro/network/resolver"
|
||||
)
|
||||
|
||||
// Resolver is a DNS network resolve
|
||||
type Resolver struct{}
|
||||
|
||||
// Resolve assumes ID is a domain name e.g micro.mu
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/micro/go-micro/network/resolver"
|
||||
)
|
||||
|
||||
// Resolver is a HTTP network resolver
|
||||
type Resolver struct {
|
||||
// If not set, defaults to http
|
||||
Proto string
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/micro/go-micro/registry"
|
||||
)
|
||||
|
||||
// Resolver is a registry network resolver
|
||||
type Resolver struct {
|
||||
// Registry is the registry to use otherwise we use the defaul
|
||||
Registry registry.Registry
|
||||
|
@@ -5,7 +5,7 @@ package resolver
|
||||
// via the name to connect to. This is done based on Network.Name().
|
||||
// Before we can be part of any network, we have to connect to it.
|
||||
type Resolver interface {
|
||||
// Resolve returns a list of addresses for an name
|
||||
// Resolve returns a list of addresses for a name
|
||||
Resolve(name string) ([]*Record, error)
|
||||
}
|
||||
|
||||
|
33
network/resolver/static/static.go
Normal file
33
network/resolver/static/static.go
Normal file
@@ -0,0 +1,33 @@
|
||||
// Package static is a static resolver
|
||||
package registry
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/network/resolver"
|
||||
)
|
||||
|
||||
// Resolver returns a static list of nodes. In the event the node list
|
||||
// is not present it will return the name of the network passed in.
|
||||
type Resolver struct {
|
||||
// A static list of nodes
|
||||
Nodes []string
|
||||
}
|
||||
|
||||
// Resolve returns the list of nodes
|
||||
func (r *Resolver) Resolve(name string) ([]*resolver.Record, error) {
|
||||
// if there are no nodes just return the name
|
||||
if len(r.Nodes) == 0 {
|
||||
return []*resolver.Record{
|
||||
{Address: name},
|
||||
}, nil
|
||||
}
|
||||
|
||||
var records []*resolver.Record
|
||||
|
||||
for _, node := range r.Nodes {
|
||||
records = append(records, &resolver.Record{
|
||||
Address: node,
|
||||
})
|
||||
}
|
||||
|
||||
return records, nil
|
||||
}
|
@@ -1,337 +0,0 @@
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/micro/go-micro/network/link"
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
// tun represents a network tunnel
|
||||
type tun struct {
|
||||
// the link on top of which we build a tunnel
|
||||
link link.Link
|
||||
|
||||
sync.RWMutex
|
||||
|
||||
// to indicate if we're connected or not
|
||||
connected bool
|
||||
|
||||
// the send channel for all messages
|
||||
send chan *message
|
||||
|
||||
// close channel
|
||||
closed chan bool
|
||||
|
||||
// a map of sockets based on Micro-Tunnel-Id
|
||||
sockets map[string]*socket
|
||||
}
|
||||
|
||||
// create new tunnel on top of a link
|
||||
func newTunnel(link link.Link) *tun {
|
||||
return &tun{
|
||||
link: link,
|
||||
send: make(chan *message, 128),
|
||||
closed: make(chan bool),
|
||||
sockets: make(map[string]*socket),
|
||||
}
|
||||
}
|
||||
|
||||
// getSocket returns a socket from the internal socket map.
|
||||
// It does this based on the Micro-Tunnel-Id and Micro-Tunnel-Session
|
||||
func (t *tun) getSocket(id, session string) (*socket, bool) {
|
||||
// get the socket
|
||||
t.RLock()
|
||||
s, ok := t.sockets[id+session]
|
||||
t.RUnlock()
|
||||
return s, ok
|
||||
}
|
||||
|
||||
// newSocket creates a new socket and saves it
|
||||
func (t *tun) newSocket(id, session string) (*socket, bool) {
|
||||
// hash the id
|
||||
h := sha256.New()
|
||||
h.Write([]byte(id))
|
||||
id = fmt.Sprintf("%x", h.Sum(nil))
|
||||
|
||||
// new socket
|
||||
s := &socket{
|
||||
id: id,
|
||||
session: session,
|
||||
closed: make(chan bool),
|
||||
recv: make(chan *message, 128),
|
||||
send: t.send,
|
||||
wait: make(chan bool),
|
||||
}
|
||||
|
||||
// save socket
|
||||
t.Lock()
|
||||
_, ok := t.sockets[id+session]
|
||||
if ok {
|
||||
// socket already exists
|
||||
t.Unlock()
|
||||
return nil, false
|
||||
}
|
||||
t.sockets[id+session] = s
|
||||
t.Unlock()
|
||||
|
||||
// return socket
|
||||
return s, true
|
||||
}
|
||||
|
||||
// TODO: use tunnel id as part of the session
|
||||
func (t *tun) newSession() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
||||
// process outgoing messages sent by all local sockets
|
||||
func (t *tun) process() {
|
||||
// manage the send buffer
|
||||
// all pseudo sockets throw everything down this
|
||||
for {
|
||||
select {
|
||||
case msg := <-t.send:
|
||||
nmsg := &transport.Message{
|
||||
Header: msg.data.Header,
|
||||
Body: msg.data.Body,
|
||||
}
|
||||
|
||||
// set the tunnel id on the outgoing message
|
||||
nmsg.Header["Micro-Tunnel-Id"] = msg.id
|
||||
|
||||
// set the session id
|
||||
nmsg.Header["Micro-Tunnel-Session"] = msg.session
|
||||
|
||||
// send the message via the interface
|
||||
if err := t.link.Send(nmsg); err != nil {
|
||||
// no op
|
||||
// TODO: do something
|
||||
}
|
||||
case <-t.closed:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process incoming messages
|
||||
func (t *tun) listen() {
|
||||
for {
|
||||
// process anything via the net interface
|
||||
msg := new(transport.Message)
|
||||
err := t.link.Recv(msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// first check Micro-Tunnel
|
||||
switch msg.Header["Micro-Tunnel"] {
|
||||
case "connect":
|
||||
// assuming new connection
|
||||
// TODO: do something with this
|
||||
continue
|
||||
case "close":
|
||||
// assuming connection closed
|
||||
// TODO: do something with this
|
||||
continue
|
||||
}
|
||||
|
||||
// the tunnel id
|
||||
id := msg.Header["Micro-Tunnel-Id"]
|
||||
|
||||
// the session id
|
||||
session := msg.Header["Micro-Tunnel-Session"]
|
||||
|
||||
// if the session id is blank there's nothing we can do
|
||||
// TODO: check this is the case, is there any reason
|
||||
// why we'd have a blank session? Is the tunnel
|
||||
// used for some other purpose?
|
||||
if len(id) == 0 || len(session) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// get the socket based on the tunnel id and session
|
||||
// this could be something we dialed in which case
|
||||
// we have a session for it otherwise its a listener
|
||||
s, exists := t.getSocket(id, session)
|
||||
if !exists {
|
||||
// try get it based on just the tunnel id
|
||||
// the assumption here is that a listener
|
||||
// has no session but its set a listener session
|
||||
s, exists = t.getSocket(id, "listener")
|
||||
if !exists {
|
||||
// drop it, we don't care about
|
||||
// messages we don't know about
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// is the socket closed?
|
||||
select {
|
||||
case <-s.closed:
|
||||
// closed
|
||||
delete(t.sockets, id)
|
||||
continue
|
||||
default:
|
||||
// process
|
||||
}
|
||||
|
||||
// is the socket new?
|
||||
select {
|
||||
// if its new the socket is actually blocked waiting
|
||||
// for a connection. so we check if its waiting.
|
||||
case <-s.wait:
|
||||
// if its waiting e.g its new then we close it
|
||||
default:
|
||||
// set remote address of the socket
|
||||
s.remote = msg.Header["Remote"]
|
||||
close(s.wait)
|
||||
}
|
||||
|
||||
// construct a new transport message
|
||||
tmsg := &transport.Message{
|
||||
Header: msg.Header,
|
||||
Body: msg.Body,
|
||||
}
|
||||
|
||||
// construct the internal message
|
||||
imsg := &message{
|
||||
id: id,
|
||||
session: session,
|
||||
data: tmsg,
|
||||
}
|
||||
|
||||
// append to recv backlog
|
||||
// we don't block if we can't pass it on
|
||||
select {
|
||||
case s.recv <- imsg:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tun) connect() error {
|
||||
return t.link.Send(&transport.Message{
|
||||
Header: map[string]string{
|
||||
"Micro-Tunnel": "connect",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (t *tun) close() error {
|
||||
return t.link.Send(&transport.Message{
|
||||
Header: map[string]string{
|
||||
"Micro-Tunnel": "close",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Close the tunnel
|
||||
func (t *tun) Close() error {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
|
||||
if !t.connected {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-t.closed:
|
||||
return nil
|
||||
default:
|
||||
// close all the sockets
|
||||
for _, s := range t.sockets {
|
||||
s.Close()
|
||||
}
|
||||
// close the connection
|
||||
close(t.closed)
|
||||
t.connected = false
|
||||
|
||||
// send a close message
|
||||
// we don't close the link
|
||||
// just the tunnel
|
||||
return t.close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Connect the tunnel
|
||||
func (t *tun) Connect() error {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
|
||||
// already connected
|
||||
if t.connected {
|
||||
return nil
|
||||
}
|
||||
|
||||
// send the connect message
|
||||
if err := t.connect(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set as connected
|
||||
t.connected = true
|
||||
// create new close channel
|
||||
t.closed = make(chan bool)
|
||||
|
||||
// process messages to be sent
|
||||
go t.process()
|
||||
// process incoming messages
|
||||
go t.listen()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Dial an address
|
||||
func (t *tun) Dial(addr string) (Conn, error) {
|
||||
c, ok := t.newSocket(addr, t.newSession())
|
||||
if !ok {
|
||||
return nil, errors.New("error dialing " + addr)
|
||||
}
|
||||
// set remote
|
||||
c.remote = addr
|
||||
// set local
|
||||
c.local = t.link.Local()
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Accept a connection on the address
|
||||
func (t *tun) Listen(addr string) (Listener, error) {
|
||||
// create a new socket by hashing the address
|
||||
c, ok := t.newSocket(addr, "listener")
|
||||
if !ok {
|
||||
return nil, errors.New("already listening on " + addr)
|
||||
}
|
||||
|
||||
// set remote. it will be replaced by the first message received
|
||||
c.remote = t.link.Remote()
|
||||
// set local
|
||||
c.local = addr
|
||||
|
||||
tl := &tunListener{
|
||||
addr: addr,
|
||||
// the accept channel
|
||||
accept: make(chan *socket, 128),
|
||||
// the channel to close
|
||||
closed: make(chan bool),
|
||||
// the connection
|
||||
conn: c,
|
||||
// the listener socket
|
||||
socket: c,
|
||||
}
|
||||
|
||||
// this kicks off the internal message processor
|
||||
// for the listener so it can create pseudo sockets
|
||||
// per session if they do not exist or pass messages
|
||||
// to the existign sessions
|
||||
go tl.process()
|
||||
|
||||
// return the listener
|
||||
return tl, nil
|
||||
}
|
@@ -1,101 +0,0 @@
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type tunListener struct {
|
||||
// address of the listener
|
||||
addr string
|
||||
// the accept channel
|
||||
accept chan *socket
|
||||
// the channel to close
|
||||
closed chan bool
|
||||
// the connection
|
||||
conn Conn
|
||||
// the listener socket
|
||||
socket *socket
|
||||
}
|
||||
|
||||
func (t *tunListener) process() {
|
||||
// our connection map for session
|
||||
conns := make(map[string]*socket)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-t.closed:
|
||||
return
|
||||
// receive a new message
|
||||
case m := <-t.socket.recv:
|
||||
// get a socket
|
||||
sock, ok := conns[m.session]
|
||||
if !ok {
|
||||
// create a new socket session
|
||||
sock = &socket{
|
||||
// our tunnel id
|
||||
id: m.id,
|
||||
// the session id
|
||||
session: m.session,
|
||||
// close chan
|
||||
closed: make(chan bool),
|
||||
// recv called by the acceptor
|
||||
recv: make(chan *message, 128),
|
||||
// use the internal send buffer
|
||||
send: t.socket.send,
|
||||
// wait
|
||||
wait: make(chan bool),
|
||||
}
|
||||
|
||||
// first message
|
||||
sock.recv <- m
|
||||
|
||||
// save the socket
|
||||
conns[m.session] = sock
|
||||
|
||||
// send to accept chan
|
||||
select {
|
||||
case <-t.closed:
|
||||
return
|
||||
case t.accept <- sock:
|
||||
}
|
||||
}
|
||||
|
||||
// send this to the accept chan
|
||||
select {
|
||||
case <-sock.closed:
|
||||
delete(conns, m.session)
|
||||
case sock.recv <- m:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tunListener) Addr() string {
|
||||
return t.addr
|
||||
}
|
||||
|
||||
func (t *tunListener) Close() error {
|
||||
select {
|
||||
case <-t.closed:
|
||||
return nil
|
||||
default:
|
||||
close(t.closed)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Everytime accept is called we essentially block till we get a new connection
|
||||
func (t *tunListener) Accept() (Conn, error) {
|
||||
select {
|
||||
// if the socket is closed return
|
||||
case <-t.closed:
|
||||
return nil, io.EOF
|
||||
// wait for a new connection
|
||||
case c, ok := <-t.accept:
|
||||
if !ok {
|
||||
return nil, io.EOF
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
@@ -1,90 +0,0 @@
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
// socket is our pseudo socket for transport.Socket
|
||||
type socket struct {
|
||||
// socket id based on Micro-Tunnel
|
||||
id string
|
||||
// the session id based on Micro.Tunnel-Session
|
||||
session string
|
||||
// closed
|
||||
closed chan bool
|
||||
// remote addr
|
||||
remote string
|
||||
// local addr
|
||||
local string
|
||||
// send chan
|
||||
send chan *message
|
||||
// recv chan
|
||||
recv chan *message
|
||||
// wait until we have a connection
|
||||
wait chan bool
|
||||
}
|
||||
|
||||
// message is sent over the send channel
|
||||
type message struct {
|
||||
// tunnel id
|
||||
id string
|
||||
// the session id
|
||||
session string
|
||||
// transport data
|
||||
data *transport.Message
|
||||
}
|
||||
|
||||
func (s *socket) Remote() string {
|
||||
return s.remote
|
||||
}
|
||||
|
||||
func (s *socket) Local() string {
|
||||
return s.local
|
||||
}
|
||||
|
||||
func (s *socket) Id() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *socket) Session() string {
|
||||
return s.session
|
||||
}
|
||||
|
||||
func (s *socket) Send(m *transport.Message) error {
|
||||
select {
|
||||
case <-s.closed:
|
||||
return errors.New("socket is closed")
|
||||
default:
|
||||
// no op
|
||||
}
|
||||
// append to backlog
|
||||
s.send <- &message{id: s.id, session: s.session, data: m}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *socket) Recv(m *transport.Message) error {
|
||||
select {
|
||||
case <-s.closed:
|
||||
return errors.New("socket is closed")
|
||||
default:
|
||||
// no op
|
||||
}
|
||||
// recv from backlog
|
||||
msg := <-s.recv
|
||||
// set message
|
||||
*m = *msg.data
|
||||
// return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *socket) Close() error {
|
||||
select {
|
||||
case <-s.closed:
|
||||
// no op
|
||||
default:
|
||||
close(s.closed)
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
// Package tunnel provides gre network tunnelling
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/network/link"
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
// Tunnel creates a gre network tunnel on top of a link.
|
||||
// It establishes multiple streams using the Micro-Tunnel-Id header
|
||||
// and Micro-Tunnel-Session header. The tunnel id is a hash of
|
||||
// the address being requested.
|
||||
type Tunnel interface {
|
||||
// Connect connects the tunnel
|
||||
Connect() error
|
||||
// Close closes the tunnel
|
||||
Close() error
|
||||
// Dial an endpoint
|
||||
Dial(addr string) (Conn, error)
|
||||
// Accept connections
|
||||
Listen(addr string) (Listener, error)
|
||||
}
|
||||
|
||||
// The listener provides similar constructs to the transport.Listener
|
||||
type Listener interface {
|
||||
Addr() string
|
||||
Close() error
|
||||
Accept() (Conn, error)
|
||||
}
|
||||
|
||||
// Conn is a connection dialed or accepted which includes the tunnel id and session
|
||||
type Conn interface {
|
||||
// Specifies the tunnel id
|
||||
Id() string
|
||||
// The session
|
||||
Session() string
|
||||
// a transport socket
|
||||
transport.Socket
|
||||
}
|
||||
|
||||
// NewTunnel creates a new tunnel on top of a link
|
||||
func NewTunnel(l link.Link) Tunnel {
|
||||
return newTunnel(l)
|
||||
}
|
@@ -1,113 +0,0 @@
|
||||
package tunnel
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/micro/go-micro/network/link"
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
// testAccept will accept connections on the transport, create a new link and tunnel on top
|
||||
func testAccept(t *testing.T, l transport.Listener, wait chan bool) error {
|
||||
// accept new connections on the transport
|
||||
// establish a link and tunnel
|
||||
return l.Accept(func(s transport.Socket) {
|
||||
// convert the socket into a link
|
||||
li := link.NewLink(
|
||||
link.Socket(s),
|
||||
)
|
||||
|
||||
// connect the link e.g start internal buffers
|
||||
if err := li.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// create a new tunnel
|
||||
tun := NewTunnel(li)
|
||||
|
||||
// connect the tunnel
|
||||
if err := tun.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// listen on some virtual address
|
||||
tl, err := tun.Listen("test-tunnel")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
return
|
||||
}
|
||||
|
||||
// accept a connection
|
||||
c, err := tl.Accept()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// get a message
|
||||
for {
|
||||
m := new(transport.Message)
|
||||
if err := c.Recv(m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
close(wait)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// testSend will create a new link to an address and then a tunnel on top
|
||||
func testSend(t *testing.T, addr string) {
|
||||
// create a new link
|
||||
l := link.NewLink(
|
||||
link.Address(addr),
|
||||
)
|
||||
|
||||
// connect the link, this includes dialing
|
||||
if err := l.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// create a tunnel on the link
|
||||
tun := NewTunnel(l)
|
||||
|
||||
// connect the tunnel with the remote side
|
||||
if err := tun.Connect(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// dial a new session
|
||||
c, err := tun.Dial("test-tunnel")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m := transport.Message{
|
||||
Header: map[string]string{
|
||||
"test": "header",
|
||||
},
|
||||
}
|
||||
if err := c.Send(&m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTunnel(t *testing.T) {
|
||||
// create a new listener
|
||||
tr := transport.NewTransport()
|
||||
l, err := tr.Listen(":0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
wait := make(chan bool)
|
||||
|
||||
// start accepting connections
|
||||
go testAccept(t, l, wait)
|
||||
|
||||
// send a message
|
||||
testSend(t, l.Addr())
|
||||
|
||||
// wait until message is received
|
||||
<-wait
|
||||
}
|
125
plugin/default.go
Normal file
125
plugin/default.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// Package plugin provides the ability to load plugins
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
pg "plugin"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/micro/go-micro/broker"
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/client/selector"
|
||||
"github.com/micro/go-micro/config/cmd"
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/server"
|
||||
"github.com/micro/go-micro/transport"
|
||||
)
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
// Init sets up the plugin
|
||||
func (p *plugin) Init(c *Config) error {
|
||||
switch c.Type {
|
||||
case "broker":
|
||||
pg, ok := c.NewFunc.(func(...broker.Option) broker.Broker)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid plugin %s", c.Name)
|
||||
}
|
||||
cmd.DefaultBrokers[c.Name] = pg
|
||||
case "client":
|
||||
pg, ok := c.NewFunc.(func(...client.Option) client.Client)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid plugin %s", c.Name)
|
||||
}
|
||||
cmd.DefaultClients[c.Name] = pg
|
||||
case "registry":
|
||||
pg, ok := c.NewFunc.(func(...registry.Option) registry.Registry)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid plugin %s", c.Name)
|
||||
}
|
||||
cmd.DefaultRegistries[c.Name] = pg
|
||||
|
||||
case "selector":
|
||||
pg, ok := c.NewFunc.(func(...selector.Option) selector.Selector)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid plugin %s", c.Name)
|
||||
}
|
||||
cmd.DefaultSelectors[c.Name] = pg
|
||||
case "server":
|
||||
pg, ok := c.NewFunc.(func(...server.Option) server.Server)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid plugin %s", c.Name)
|
||||
}
|
||||
cmd.DefaultServers[c.Name] = pg
|
||||
case "transport":
|
||||
pg, ok := c.NewFunc.(func(...transport.Option) transport.Transport)
|
||||
if !ok {
|
||||
return fmt.Errorf("Invalid plugin %s", c.Name)
|
||||
}
|
||||
cmd.DefaultTransports[c.Name] = pg
|
||||
default:
|
||||
return fmt.Errorf("Unknown plugin type: %s for %s", c.Type, c.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Load loads a plugin created with `go build -buildmode=plugin`
|
||||
func (p *plugin) Load(path string) (*Config, error) {
|
||||
plugin, err := pg.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s, err := plugin.Lookup("Plugin")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pl, ok := s.(*Config)
|
||||
if !ok {
|
||||
return nil, errors.New("could not cast Plugin object")
|
||||
}
|
||||
return pl, nil
|
||||
}
|
||||
|
||||
// Generate creates a go file at the specified path.
|
||||
// You must use `go build -buildmode=plugin`to build it.
|
||||
func (p *plugin) Generate(path string, c *Config) error {
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
t, err := template.New(c.Name).Parse(tmpl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.Execute(f, c)
|
||||
}
|
||||
|
||||
// Build generates a dso plugin using the go command `go build -buildmode=plugin`
|
||||
func (p *plugin) Build(path string, c *Config) error {
|
||||
path = strings.TrimSuffix(path, ".so")
|
||||
|
||||
// create go file in tmp path
|
||||
temp := os.TempDir()
|
||||
base := filepath.Base(path)
|
||||
goFile := filepath.Join(temp, base+".go")
|
||||
|
||||
// generate .go file
|
||||
if err := p.Generate(goFile, c); err != nil {
|
||||
return err
|
||||
}
|
||||
// remove .go file
|
||||
defer os.Remove(goFile)
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil && !os.IsExist(err) {
|
||||
return fmt.Errorf("Failed to create dir %s: %v", filepath.Dir(path), err)
|
||||
}
|
||||
cmd := exec.Command("go", "build", "-buildmode=plugin", "-o", path+".so", goFile)
|
||||
return cmd.Run()
|
||||
}
|
46
plugin/plugin.go
Normal file
46
plugin/plugin.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Package plugin provides the ability to load plugins
|
||||
package plugin
|
||||
|
||||
// Plugin is a plugin loaded from a file
|
||||
type Plugin interface {
|
||||
// Initialise a plugin with the config
|
||||
Init(c *Config) error
|
||||
// Load loads a .so plugin at the given path
|
||||
Load(path string) (*Config, error)
|
||||
// Build a .so plugin with config at the path specified
|
||||
Build(path string, c *Config) error
|
||||
}
|
||||
|
||||
// Config is the plugin config
|
||||
type Config struct {
|
||||
// Name of the plugin e.g rabbitmq
|
||||
Name string
|
||||
// Type of the plugin e.g broker
|
||||
Type string
|
||||
// Path specifies the import path
|
||||
Path string
|
||||
// NewFunc creates an instance of the plugin
|
||||
NewFunc interface{}
|
||||
}
|
||||
|
||||
var (
|
||||
// Default plugin loader
|
||||
DefaultPlugin = NewPlugin()
|
||||
)
|
||||
|
||||
// NewPlugin creates a new plugin interface
|
||||
func NewPlugin() Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
func Build(path string, c *Config) error {
|
||||
return DefaultPlugin.Build(path, c)
|
||||
}
|
||||
|
||||
func Load(path string) (*Config, error) {
|
||||
return DefaultPlugin.Load(path)
|
||||
}
|
||||
|
||||
func Init(c *Config) error {
|
||||
return DefaultPlugin.Init(c)
|
||||
}
|
20
plugin/template.go
Normal file
20
plugin/template.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package plugin
|
||||
|
||||
var (
|
||||
tmpl = `
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/plugin"
|
||||
|
||||
"{{.Path}}"
|
||||
)
|
||||
|
||||
var Plugin = plugin.Config{
|
||||
Name: "{{.Name}}",
|
||||
Type: "{{.Type}}",
|
||||
Path: "{{.Path}}",
|
||||
NewFunc: {{.Name}}.{{.NewFunc}},
|
||||
}
|
||||
`
|
||||
)
|
@@ -10,7 +10,8 @@ import (
|
||||
"github.com/micro/go-micro/client/grpc"
|
||||
"github.com/micro/go-micro/codec"
|
||||
"github.com/micro/go-micro/config/options"
|
||||
"github.com/micro/go-micro/network/proxy"
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/proxy"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
@@ -61,6 +62,10 @@ func readLoop(r server.Request, s client.Stream) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Proxy) SendRequest(ctx context.Context, req client.Request, rsp client.Response) error {
|
||||
return errors.InternalServerError("go.micro.proxy.grpc", "SendRequest is unsupported")
|
||||
}
|
||||
|
||||
// ServeRequest honours the server.Proxy interface
|
||||
func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server.Response) error {
|
||||
// set default client
|
@@ -10,9 +10,10 @@ import (
|
||||
"net/url"
|
||||
"path"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/config/options"
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/network/proxy"
|
||||
"github.com/micro/go-micro/proxy"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
@@ -44,6 +45,10 @@ func getEndpoint(hdr map[string]string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *Proxy) SendRequest(ctx context.Context, req client.Request, rsp client.Response) error {
|
||||
return errors.InternalServerError("go.micro.proxy.http", "SendRequest is unsupported")
|
||||
}
|
||||
|
||||
// ServeRequest honours the server.Router interface
|
||||
func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server.Response) error {
|
||||
if p.Endpoint == "" {
|
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -12,8 +13,9 @@ import (
|
||||
"github.com/micro/go-micro/codec"
|
||||
"github.com/micro/go-micro/codec/bytes"
|
||||
"github.com/micro/go-micro/config/options"
|
||||
"github.com/micro/go-micro/network/proxy"
|
||||
"github.com/micro/go-micro/network/router"
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/proxy"
|
||||
"github.com/micro/go-micro/router"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
@@ -26,9 +28,12 @@ type Proxy struct {
|
||||
// Endpoint specifies the fixed service endpoint to call.
|
||||
Endpoint string
|
||||
|
||||
// The client to use for outbound requests
|
||||
// The client to use for outbound requests in the local network
|
||||
Client client.Client
|
||||
|
||||
// Links are used for outbound requests not in the local network
|
||||
Links map[string]client.Client
|
||||
|
||||
// The router for routes
|
||||
Router router.Router
|
||||
|
||||
@@ -76,7 +81,7 @@ func readLoop(r server.Request, s client.Stream) error {
|
||||
}
|
||||
|
||||
// toNodes returns a list of node addresses from given routes
|
||||
func toNodes(routes map[uint64]router.Route) []string {
|
||||
func toNodes(routes []router.Route) []string {
|
||||
var nodes []string
|
||||
for _, node := range routes {
|
||||
address := node.Address
|
||||
@@ -88,37 +93,63 @@ func toNodes(routes map[uint64]router.Route) []string {
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (p *Proxy) getRoute(service string) ([]string, error) {
|
||||
func (p *Proxy) getLink(r router.Route) (client.Client, error) {
|
||||
if r.Link == "local" || len(p.Links) == 0 {
|
||||
return p.Client, nil
|
||||
}
|
||||
l, ok := p.Links[r.Link]
|
||||
if !ok {
|
||||
return nil, errors.InternalServerError("go.micro.proxy", "link not found")
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (p *Proxy) getRoute(service string) ([]router.Route, error) {
|
||||
toSlice := func(r map[uint64]router.Route) []router.Route {
|
||||
var routes []router.Route
|
||||
for _, v := range r {
|
||||
routes = append(routes, v)
|
||||
}
|
||||
|
||||
// sort the routes in order of metric
|
||||
sort.Slice(routes, func(i, j int) bool { return routes[i].Metric < routes[j].Metric })
|
||||
|
||||
return routes
|
||||
}
|
||||
|
||||
// lookup the route cache first
|
||||
p.Lock()
|
||||
routes, ok := p.Routes[service]
|
||||
if ok {
|
||||
p.Unlock()
|
||||
return toNodes(routes), nil
|
||||
return toSlice(routes), nil
|
||||
}
|
||||
p.Routes[service] = make(map[uint64]router.Route)
|
||||
p.Unlock()
|
||||
|
||||
// if the router is broken return error
|
||||
if status := p.Router.Status(); status.Code == router.Error {
|
||||
return nil, status.Error
|
||||
}
|
||||
|
||||
// lookup the routes in the router
|
||||
results, err := p.Router.Lookup(router.NewQuery(router.QueryService(service)))
|
||||
if err != nil {
|
||||
// check the status of the router
|
||||
if status := p.Router.Status(); status.Code == router.Error {
|
||||
return nil, status.Error
|
||||
}
|
||||
// otherwise return the error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// update the proxy cache
|
||||
p.Lock()
|
||||
for _, route := range results {
|
||||
// create if does not exist
|
||||
if _, ok := p.Routes[service]; !ok {
|
||||
p.Routes[service] = make(map[uint64]router.Route)
|
||||
}
|
||||
p.Routes[service][route.Hash()] = route
|
||||
}
|
||||
routes = p.Routes[service]
|
||||
p.Unlock()
|
||||
|
||||
return toNodes(routes), nil
|
||||
return toSlice(routes), nil
|
||||
}
|
||||
|
||||
// manageRouteCache applies action on a given route to Proxy route cache
|
||||
@@ -130,9 +161,6 @@ func (p *Proxy) manageRouteCache(route router.Route, action string) error {
|
||||
}
|
||||
p.Routes[route.Service][route.Hash()] = route
|
||||
case "delete":
|
||||
if _, ok := p.Routes[route.Service]; !ok {
|
||||
return fmt.Errorf("route not found")
|
||||
}
|
||||
delete(p.Routes[route.Service], route.Hash())
|
||||
default:
|
||||
return fmt.Errorf("unknown action: %s", action)
|
||||
@@ -171,12 +199,31 @@ func (p *Proxy) watchRoutes() {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Proxy) SendRequest(ctx context.Context, req client.Request, rsp client.Response) error {
|
||||
return errors.InternalServerError("go.micro.proxy", "SendRequest is unsupported")
|
||||
}
|
||||
|
||||
// ServeRequest honours the server.Router interface
|
||||
func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server.Response) error {
|
||||
// service name
|
||||
service := req.Service()
|
||||
endpoint := req.Endpoint()
|
||||
// determine if its local routing
|
||||
var local bool
|
||||
// address to call
|
||||
var addresses []string
|
||||
// routes
|
||||
var routes []router.Route
|
||||
// service name to call
|
||||
service := req.Service()
|
||||
// endpoint to call
|
||||
endpoint := req.Endpoint()
|
||||
|
||||
if len(service) == 0 {
|
||||
return errors.BadRequest("go.micro.proxy", "service name is blank")
|
||||
}
|
||||
|
||||
// are we network routing or local routing
|
||||
if len(p.Links) == 0 {
|
||||
local = true
|
||||
}
|
||||
|
||||
// call a specific backend endpoint either by name or address
|
||||
if len(p.Endpoint) > 0 {
|
||||
@@ -190,7 +237,7 @@ func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server
|
||||
return err
|
||||
}
|
||||
// set the address
|
||||
addresses = addr
|
||||
routes = addr
|
||||
// set the name
|
||||
service = p.Endpoint
|
||||
}
|
||||
@@ -201,16 +248,66 @@ func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addresses = addr
|
||||
routes = addr
|
||||
}
|
||||
|
||||
var opts []client.CallOption
|
||||
|
||||
// set address if available
|
||||
// if the address is already set just serve it
|
||||
// TODO: figure it out if we should know to pick a link
|
||||
if len(addresses) > 0 {
|
||||
opts = append(opts, client.WithAddress(addresses...))
|
||||
// serve the normal way
|
||||
return p.serveRequest(ctx, p.Client, service, endpoint, req, rsp, client.WithAddress(addresses...))
|
||||
}
|
||||
|
||||
// there's no links e.g we're local routing then just serve it with addresses
|
||||
if local {
|
||||
var opts []client.CallOption
|
||||
|
||||
// set address if available via routes or specific endpoint
|
||||
if len(routes) > 0 {
|
||||
addresses := toNodes(routes)
|
||||
opts = append(opts, client.WithAddress(addresses...))
|
||||
}
|
||||
|
||||
// serve the normal way
|
||||
return p.serveRequest(ctx, p.Client, service, endpoint, req, rsp, opts...)
|
||||
}
|
||||
|
||||
var gerr error
|
||||
|
||||
// we're routing globally with multiple links
|
||||
// so we need to pick a link per route
|
||||
for _, route := range routes {
|
||||
// pick the link or error out
|
||||
link, err := p.getLink(route)
|
||||
if err != nil {
|
||||
// ok let's try again
|
||||
gerr = err
|
||||
continue
|
||||
}
|
||||
|
||||
// set the address to call
|
||||
addresses := toNodes([]router.Route{route})
|
||||
|
||||
// do the request with the link
|
||||
gerr = p.serveRequest(ctx, link, service, endpoint, req, rsp, client.WithAddress(addresses...))
|
||||
// return on no error since we succeeded
|
||||
if gerr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// return where the context deadline was exceeded
|
||||
if gerr == context.Canceled || gerr == context.DeadlineExceeded {
|
||||
return err
|
||||
}
|
||||
|
||||
// otherwise attempt to do it all over again
|
||||
}
|
||||
|
||||
// if we got here something went really badly wrong
|
||||
return gerr
|
||||
}
|
||||
|
||||
func (p *Proxy) serveRequest(ctx context.Context, link client.Client, service, endpoint string, req server.Request, rsp server.Response, opts ...client.CallOption) error {
|
||||
// read initial request
|
||||
body, err := req.Read()
|
||||
if err != nil {
|
||||
@@ -218,16 +315,33 @@ func (p *Proxy) ServeRequest(ctx context.Context, req server.Request, rsp server
|
||||
}
|
||||
|
||||
// create new request with raw bytes body
|
||||
creq := p.Client.NewRequest(service, endpoint, &bytes.Frame{body}, client.WithContentType(req.ContentType()))
|
||||
creq := link.NewRequest(service, endpoint, &bytes.Frame{body}, client.WithContentType(req.ContentType()))
|
||||
|
||||
// not a stream so make a client.Call request
|
||||
if !req.Stream() {
|
||||
crsp := new(bytes.Frame)
|
||||
|
||||
// make a call to the backend
|
||||
if err := link.Call(ctx, creq, crsp, opts...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write the response
|
||||
if err := rsp.Write(crsp.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// create new stream
|
||||
stream, err := p.Client.Stream(ctx, creq, opts...)
|
||||
stream, err := link.Stream(ctx, creq, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stream.Close()
|
||||
|
||||
// create client request read loop
|
||||
// create client request read loop if streaming
|
||||
go readLoop(req, stream)
|
||||
|
||||
// get raw response
|
||||
@@ -283,6 +397,7 @@ func NewSingleHostProxy(endpoint string) *Proxy {
|
||||
// NewProxy returns a new proxy which will route based on mucp headers
|
||||
func NewProxy(opts ...options.Option) proxy.Proxy {
|
||||
p := new(Proxy)
|
||||
p.Links = map[string]client.Client{}
|
||||
p.Options = options.NewOptions(opts...)
|
||||
p.Options.Init(options.WithString("mucp"))
|
||||
|
||||
@@ -303,6 +418,12 @@ func NewProxy(opts ...options.Option) proxy.Proxy {
|
||||
p.Client = client.DefaultClient
|
||||
}
|
||||
|
||||
// get client
|
||||
links, ok := p.Options.Values().Get("proxy.links")
|
||||
if ok {
|
||||
p.Links = links.(map[string]client.Client)
|
||||
}
|
||||
|
||||
// get router
|
||||
r, ok := p.Options.Values().Get("proxy.router")
|
||||
if ok {
|
@@ -6,13 +6,15 @@ import (
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/config/options"
|
||||
"github.com/micro/go-micro/network/router"
|
||||
"github.com/micro/go-micro/router"
|
||||
"github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
// Proxy can be used as a proxy server for go-micro services
|
||||
type Proxy interface {
|
||||
options.Options
|
||||
// SendRequest honours the client.Router interface
|
||||
SendRequest(context.Context, client.Request, client.Response) error
|
||||
// ServeRequest honours the server.Router interface
|
||||
ServeRequest(context.Context, server.Request, server.Response) error
|
||||
}
|
||||
@@ -35,3 +37,20 @@ func WithClient(c client.Client) options.Option {
|
||||
func WithRouter(r router.Router) options.Option {
|
||||
return options.WithValue("proxy.router", r)
|
||||
}
|
||||
|
||||
// WithLink sets a link for outbound requests
|
||||
func WithLink(name string, c client.Client) options.Option {
|
||||
return func(o *options.Values) error {
|
||||
var links map[string]client.Client
|
||||
v, ok := o.Get("proxy.links")
|
||||
if ok {
|
||||
links = v.(map[string]client.Client)
|
||||
} else {
|
||||
links = map[string]client.Client{}
|
||||
}
|
||||
links[name] = c
|
||||
// save the links
|
||||
o.Set("proxy.links", links)
|
||||
return nil
|
||||
}
|
||||
}
|
15
registry/cache/rcache.go
vendored
15
registry/cache/rcache.go
vendored
@@ -325,18 +325,27 @@ func (c *cache) run(service string) {
|
||||
// watch loops the next event and calls update
|
||||
// it returns if there's an error
|
||||
func (c *cache) watch(w registry.Watcher) error {
|
||||
defer w.Stop()
|
||||
// used to stop the watch
|
||||
stop := make(chan bool)
|
||||
|
||||
// manage this loop
|
||||
go func() {
|
||||
defer w.Stop()
|
||||
|
||||
select {
|
||||
// wait for exit
|
||||
<-c.exit
|
||||
w.Stop()
|
||||
case <-c.exit:
|
||||
return
|
||||
// we've been stopped
|
||||
case <-stop:
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
res, err := w.Next()
|
||||
if err != nil {
|
||||
close(stop)
|
||||
return err
|
||||
}
|
||||
c.update(res)
|
||||
|
@@ -13,14 +13,17 @@ import (
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
"github.com/micro/go-micro/registry"
|
||||
mnet "github.com/micro/go-micro/util/net"
|
||||
hash "github.com/mitchellh/hashstructure"
|
||||
)
|
||||
|
||||
type consulRegistry struct {
|
||||
Address string
|
||||
Client *consul.Client
|
||||
Address []string
|
||||
opts registry.Options
|
||||
|
||||
client *consul.Client
|
||||
config *consul.Config
|
||||
|
||||
// connect enabled
|
||||
connect bool
|
||||
|
||||
@@ -95,24 +98,33 @@ func configure(c *consulRegistry, opts ...registry.Option) {
|
||||
}
|
||||
|
||||
// check if there are any addrs
|
||||
if len(c.opts.Addrs) > 0 {
|
||||
addr, port, err := net.SplitHostPort(c.opts.Addrs[0])
|
||||
var addrs []string
|
||||
|
||||
// iterate the options addresses
|
||||
for _, address := range c.opts.Addrs {
|
||||
// check we have a port
|
||||
addr, port, err := net.SplitHostPort(address)
|
||||
if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" {
|
||||
port = "8500"
|
||||
addr = c.opts.Addrs[0]
|
||||
config.Address = fmt.Sprintf("%s:%s", addr, port)
|
||||
addr = address
|
||||
addrs = append(addrs, fmt.Sprintf("%s:%s", addr, port))
|
||||
} else if err == nil {
|
||||
config.Address = fmt.Sprintf("%s:%s", addr, port)
|
||||
addrs = append(addrs, fmt.Sprintf("%s:%s", addr, port))
|
||||
}
|
||||
}
|
||||
|
||||
// set the addrs
|
||||
if len(addrs) > 0 {
|
||||
c.Address = addrs
|
||||
config.Address = c.Address[0]
|
||||
}
|
||||
|
||||
if config.HttpClient == nil {
|
||||
config.HttpClient = new(http.Client)
|
||||
}
|
||||
|
||||
// requires secure connection?
|
||||
if c.opts.Secure || c.opts.TLSConfig != nil {
|
||||
|
||||
config.Scheme = "https"
|
||||
// We're going to support InsecureSkipVerify
|
||||
config.HttpClient.Transport = newTransport(c.opts.TLSConfig)
|
||||
@@ -123,12 +135,14 @@ func configure(c *consulRegistry, opts ...registry.Option) {
|
||||
config.HttpClient.Timeout = c.opts.Timeout
|
||||
}
|
||||
|
||||
// create the client
|
||||
client, _ := consul.NewClient(config)
|
||||
// set the config
|
||||
c.config = config
|
||||
|
||||
// set address/client
|
||||
c.Address = config.Address
|
||||
c.Client = client
|
||||
// remove client
|
||||
c.client = nil
|
||||
|
||||
// setup the client
|
||||
c.Client()
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Init(opts ...registry.Option) error {
|
||||
@@ -148,7 +162,7 @@ func (c *consulRegistry) Deregister(s *registry.Service) error {
|
||||
c.Unlock()
|
||||
|
||||
node := s.Nodes[0]
|
||||
return c.Client.Agent().ServiceDeregister(node.Id)
|
||||
return c.Client().Agent().ServiceDeregister(node.Id)
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Register(s *registry.Service, opts ...registry.RegisterOption) error {
|
||||
@@ -193,7 +207,7 @@ func (c *consulRegistry) Register(s *registry.Service, opts ...registry.Register
|
||||
if time.Since(lastChecked) <= getDeregisterTTL(regInterval) {
|
||||
return nil
|
||||
}
|
||||
services, _, err := c.Client.Health().Checks(s.Name, c.queryOptions)
|
||||
services, _, err := c.Client().Health().Checks(s.Name, c.queryOptions)
|
||||
if err == nil {
|
||||
for _, v := range services {
|
||||
if v.ServiceID == node.Id {
|
||||
@@ -204,7 +218,7 @@ func (c *consulRegistry) Register(s *registry.Service, opts ...registry.Register
|
||||
} else {
|
||||
// if the err is nil we're all good, bail out
|
||||
// if not, we don't know what the state is, so full re-register
|
||||
if err := c.Client.Agent().PassTTL("service:"+node.Id, ""); err == nil {
|
||||
if err := c.Client().Agent().PassTTL("service:"+node.Id, ""); err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -237,6 +251,9 @@ func (c *consulRegistry) Register(s *registry.Service, opts ...registry.Register
|
||||
}
|
||||
|
||||
host, pt, _ := net.SplitHostPort(node.Address)
|
||||
if host == "" {
|
||||
host = node.Address
|
||||
}
|
||||
port, _ := strconv.Atoi(pt)
|
||||
|
||||
// register the service
|
||||
@@ -256,7 +273,7 @@ func (c *consulRegistry) Register(s *registry.Service, opts ...registry.Register
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.Client.Agent().ServiceRegister(asr); err != nil {
|
||||
if err := c.Client().Agent().ServiceRegister(asr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -272,7 +289,7 @@ func (c *consulRegistry) Register(s *registry.Service, opts ...registry.Register
|
||||
}
|
||||
|
||||
// pass the healthcheck
|
||||
return c.Client.Agent().PassTTL("service:"+node.Id, "")
|
||||
return c.Client().Agent().PassTTL("service:"+node.Id, "")
|
||||
}
|
||||
|
||||
func (c *consulRegistry) GetService(name string) ([]*registry.Service, error) {
|
||||
@@ -281,9 +298,9 @@ func (c *consulRegistry) GetService(name string) ([]*registry.Service, error) {
|
||||
|
||||
// if we're connect enabled only get connect services
|
||||
if c.connect {
|
||||
rsp, _, err = c.Client.Health().Connect(name, "", false, c.queryOptions)
|
||||
rsp, _, err = c.Client().Health().Connect(name, "", false, c.queryOptions)
|
||||
} else {
|
||||
rsp, _, err = c.Client.Health().Service(name, "", false, c.queryOptions)
|
||||
rsp, _, err = c.Client().Health().Service(name, "", false, c.queryOptions)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -338,7 +355,7 @@ func (c *consulRegistry) GetService(name string) ([]*registry.Service, error) {
|
||||
|
||||
svc.Nodes = append(svc.Nodes, ®istry.Node{
|
||||
Id: id,
|
||||
Address: fmt.Sprintf("%s:%d", address, s.Service.Port),
|
||||
Address: mnet.HostPort(address, s.Service.Port),
|
||||
Metadata: decodeMetadata(s.Service.Tags),
|
||||
})
|
||||
}
|
||||
@@ -351,7 +368,7 @@ func (c *consulRegistry) GetService(name string) ([]*registry.Service, error) {
|
||||
}
|
||||
|
||||
func (c *consulRegistry) ListServices() ([]*registry.Service, error) {
|
||||
rsp, _, err := c.Client.Catalog().Services(c.queryOptions)
|
||||
rsp, _, err := c.Client().Catalog().Services(c.queryOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -377,6 +394,36 @@ func (c *consulRegistry) Options() registry.Options {
|
||||
return c.opts
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Client() *consul.Client {
|
||||
if c.client != nil {
|
||||
return c.client
|
||||
}
|
||||
|
||||
for _, addr := range c.Address {
|
||||
// set the address
|
||||
c.config.Address = addr
|
||||
|
||||
// create a new client
|
||||
tmpClient, _ := consul.NewClient(c.config)
|
||||
|
||||
// test the client
|
||||
_, err := tmpClient.Agent().Host()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// set the client
|
||||
c.client = tmpClient
|
||||
return c.client
|
||||
}
|
||||
|
||||
// set the default
|
||||
c.client, _ = consul.NewClient(c.config)
|
||||
|
||||
// return the client
|
||||
return c.client
|
||||
}
|
||||
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
cr := &consulRegistry{
|
||||
opts: registry.Options{},
|
||||
|
@@ -50,22 +50,24 @@ func newConsulTestRegistry(r *mockRegistry) (*consulRegistry, func()) {
|
||||
}
|
||||
cfg := consul.DefaultConfig()
|
||||
cfg.Address = l.Addr().String()
|
||||
cl, _ := consul.NewClient(cfg)
|
||||
|
||||
go newMockServer(r, l)
|
||||
|
||||
return &consulRegistry{
|
||||
Address: cfg.Address,
|
||||
Client: cl,
|
||||
opts: registry.Options{},
|
||||
register: make(map[string]uint64),
|
||||
lastChecked: make(map[string]time.Time),
|
||||
queryOptions: &consul.QueryOptions{
|
||||
AllowStale: true,
|
||||
},
|
||||
}, func() {
|
||||
l.Close()
|
||||
}
|
||||
var cr = &consulRegistry{
|
||||
config: cfg,
|
||||
Address: []string{cfg.Address},
|
||||
opts: registry.Options{},
|
||||
register: make(map[string]uint64),
|
||||
lastChecked: make(map[string]time.Time),
|
||||
queryOptions: &consul.QueryOptions{
|
||||
AllowStale: true,
|
||||
},
|
||||
}
|
||||
cr.Client()
|
||||
|
||||
return cr, func() {
|
||||
l.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func newServiceList(svc []*consul.ServiceEntry) []byte {
|
||||
|
@@ -45,7 +45,7 @@ func newConsulWatcher(cr *consulRegistry, opts ...registry.WatchOption) (registr
|
||||
}
|
||||
|
||||
wp.Handler = cw.handle
|
||||
go wp.RunWithClientAndLogger(cr.Client, log.New(os.Stderr, "", log.LstdFlags))
|
||||
go wp.RunWithClientAndLogger(cr.Client(), log.New(os.Stderr, "", log.LstdFlags))
|
||||
cw.wp = wp
|
||||
|
||||
return cw, nil
|
||||
@@ -209,7 +209,7 @@ func (cw *consulWatcher) handle(idx uint64, data interface{}) {
|
||||
})
|
||||
if err == nil {
|
||||
wp.Handler = cw.serviceHandler
|
||||
go wp.RunWithClientAndLogger(cw.r.Client, log.New(os.Stderr, "", log.LstdFlags))
|
||||
go wp.RunWithClientAndLogger(cw.r.Client(), log.New(os.Stderr, "", log.LstdFlags))
|
||||
cw.watchers[service] = wp
|
||||
cw.next <- ®istry.Result{Action: "create", Service: ®istry.Service{Name: service}}
|
||||
}
|
||||
|
76
registry/handler/handler.go
Normal file
76
registry/handler/handler.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/registry"
|
||||
pb "github.com/micro/go-micro/registry/proto"
|
||||
"github.com/micro/go-micro/registry/service"
|
||||
)
|
||||
|
||||
type Registry struct {
|
||||
// internal registry
|
||||
Registry registry.Registry
|
||||
}
|
||||
|
||||
func (r *Registry) GetService(ctx context.Context, req *pb.GetRequest, rsp *pb.GetResponse) error {
|
||||
services, err := r.Registry.GetService(req.Service)
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
for _, srv := range services {
|
||||
rsp.Services = append(rsp.Services, service.ToProto(srv))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry) Register(ctx context.Context, req *pb.Service, rsp *pb.EmptyResponse) error {
|
||||
err := r.Registry.Register(service.ToService(req))
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry) Deregister(ctx context.Context, req *pb.Service, rsp *pb.EmptyResponse) error {
|
||||
err := r.Registry.Deregister(service.ToService(req))
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry) ListServices(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error {
|
||||
services, err := r.Registry.ListServices()
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
for _, srv := range services {
|
||||
rsp.Services = append(rsp.Services, service.ToProto(srv))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Registry) Watch(ctx context.Context, req *pb.WatchRequest, rsp pb.Registry_WatchStream) error {
|
||||
watcher, err := r.Registry.Watch(registry.WatchService(req.Service))
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
|
||||
for {
|
||||
next, err := watcher.Next()
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
err = rsp.Send(&pb.Result{
|
||||
Action: next.Action,
|
||||
Service: service.ToProto(next.Service),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.registry", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@@ -2,6 +2,8 @@
|
||||
package mdns
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/go-micro/registry"
|
||||
)
|
||||
|
||||
@@ -9,3 +11,13 @@ import (
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
return registry.NewRegistry(opts...)
|
||||
}
|
||||
|
||||
// Domain sets the mdnsDomain
|
||||
func Domain(d string) registry.Option {
|
||||
return func(o *registry.Options) {
|
||||
if o.Context == nil {
|
||||
o.Context = context.Background()
|
||||
}
|
||||
o.Context = context.WithValue(o.Context, "mdns.domain", d)
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,11 @@ import (
|
||||
hash "github.com/mitchellh/hashstructure"
|
||||
)
|
||||
|
||||
var (
|
||||
// use a .micro domain rather than .local
|
||||
mdnsDomain = "micro"
|
||||
)
|
||||
|
||||
type mdnsTxt struct {
|
||||
Service string
|
||||
Version string
|
||||
@@ -29,6 +34,8 @@ type mdnsEntry struct {
|
||||
|
||||
type mdnsRegistry struct {
|
||||
opts Options
|
||||
// the mdns domain
|
||||
domain string
|
||||
|
||||
sync.Mutex
|
||||
services map[string][]*mdnsEntry
|
||||
@@ -36,11 +43,25 @@ type mdnsRegistry struct {
|
||||
|
||||
func newRegistry(opts ...Option) Registry {
|
||||
options := Options{
|
||||
Context: context.Background(),
|
||||
Timeout: time.Millisecond * 100,
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
// set the domain
|
||||
domain := mdnsDomain
|
||||
|
||||
d, ok := options.Context.Value("mdns.domain").(string)
|
||||
if ok {
|
||||
domain = d
|
||||
}
|
||||
|
||||
return &mdnsRegistry{
|
||||
opts: options,
|
||||
domain: domain,
|
||||
services: make(map[string][]*mdnsEntry),
|
||||
}
|
||||
}
|
||||
@@ -66,7 +87,7 @@ func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error
|
||||
s, err := mdns.NewMDNSService(
|
||||
service.Name,
|
||||
"_services",
|
||||
"",
|
||||
m.domain+".",
|
||||
"",
|
||||
9999,
|
||||
[]net.IP{net.ParseIP("0.0.0.0")},
|
||||
@@ -141,7 +162,7 @@ func (m *mdnsRegistry) Register(service *Service, opts ...RegisterOption) error
|
||||
s, err := mdns.NewMDNSService(
|
||||
node.Id,
|
||||
service.Name,
|
||||
"",
|
||||
m.domain+".",
|
||||
"",
|
||||
port,
|
||||
[]net.IP{net.ParseIP(host)},
|
||||
@@ -214,6 +235,8 @@ func (m *mdnsRegistry) GetService(service string) ([]*Service, error) {
|
||||
p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout)
|
||||
// set entries channel
|
||||
p.Entries = entries
|
||||
// set the domain
|
||||
p.Domain = m.domain
|
||||
|
||||
go func() {
|
||||
for {
|
||||
@@ -223,7 +246,9 @@ func (m *mdnsRegistry) GetService(service string) ([]*Service, error) {
|
||||
if p.Service == "_services" {
|
||||
continue
|
||||
}
|
||||
|
||||
if p.Domain != m.domain {
|
||||
continue
|
||||
}
|
||||
if e.TTL == 0 {
|
||||
continue
|
||||
}
|
||||
@@ -288,6 +313,8 @@ func (m *mdnsRegistry) ListServices() ([]*Service, error) {
|
||||
p.Context, _ = context.WithTimeout(context.Background(), m.opts.Timeout)
|
||||
// set entries channel
|
||||
p.Entries = entries
|
||||
// set domain
|
||||
p.Domain = m.domain
|
||||
|
||||
var services []*Service
|
||||
|
||||
@@ -298,7 +325,9 @@ func (m *mdnsRegistry) ListServices() ([]*Service, error) {
|
||||
if e.TTL == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(e.Name, p.Domain+".") {
|
||||
continue
|
||||
}
|
||||
name := strings.TrimSuffix(e.Name, "."+p.Service+"."+p.Domain+".")
|
||||
if !serviceMap[name] {
|
||||
serviceMap[name] = true
|
||||
@@ -329,9 +358,10 @@ func (m *mdnsRegistry) Watch(opts ...WatchOption) (Watcher, error) {
|
||||
}
|
||||
|
||||
md := &mdnsWatcher{
|
||||
wo: wo,
|
||||
ch: make(chan *mdns.ServiceEntry, 32),
|
||||
exit: make(chan struct{}),
|
||||
wo: wo,
|
||||
ch: make(chan *mdns.ServiceEntry, 32),
|
||||
exit: make(chan struct{}),
|
||||
domain: m.domain,
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
@@ -11,6 +11,8 @@ type mdnsWatcher struct {
|
||||
wo WatchOptions
|
||||
ch chan *mdns.ServiceEntry
|
||||
exit chan struct{}
|
||||
// the mdns domain
|
||||
domain string
|
||||
}
|
||||
|
||||
func (m *mdnsWatcher) Next() (*Result, error) {
|
||||
@@ -46,13 +48,14 @@ func (m *mdnsWatcher) Next() (*Result, error) {
|
||||
Endpoints: txt.Endpoints,
|
||||
}
|
||||
|
||||
// TODO: don't hardcode .local.
|
||||
if !strings.HasSuffix(e.Name, "."+service.Name+".local.") {
|
||||
// skip anything without the domain we care about
|
||||
suffix := fmt.Sprintf(".%s.%s.", service.Name, m.domain)
|
||||
if !strings.HasSuffix(e.Name, suffix) {
|
||||
continue
|
||||
}
|
||||
|
||||
service.Nodes = append(service.Nodes, &Node{
|
||||
Id: strings.TrimSuffix(e.Name, "."+service.Name+".local."),
|
||||
Id: strings.TrimSuffix(e.Name, suffix),
|
||||
Address: fmt.Sprintf("%s:%d", e.AddrV4.String(), e.Port),
|
||||
Metadata: txt.Metadata,
|
||||
})
|
||||
|
224
registry/proto/registry.micro.go
Normal file
224
registry/proto/registry.micro.go
Normal file
@@ -0,0 +1,224 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: micro/go-micro/registry/proto/registry.proto
|
||||
|
||||
package go_micro_registry
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
import (
|
||||
context "context"
|
||||
client "github.com/micro/go-micro/client"
|
||||
server "github.com/micro/go-micro/server"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ client.Option
|
||||
var _ server.Option
|
||||
|
||||
// Client API for Registry service
|
||||
|
||||
type RegistryService interface {
|
||||
GetService(ctx context.Context, in *GetRequest, opts ...client.CallOption) (*GetResponse, error)
|
||||
Register(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error)
|
||||
Deregister(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error)
|
||||
ListServices(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
|
||||
Watch(ctx context.Context, in *WatchRequest, opts ...client.CallOption) (Registry_WatchService, error)
|
||||
}
|
||||
|
||||
type registryService struct {
|
||||
c client.Client
|
||||
name string
|
||||
}
|
||||
|
||||
func NewRegistryService(name string, c client.Client) RegistryService {
|
||||
if c == nil {
|
||||
c = client.NewClient()
|
||||
}
|
||||
if len(name) == 0 {
|
||||
name = "go.micro.registry"
|
||||
}
|
||||
return ®istryService{
|
||||
c: c,
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *registryService) GetService(ctx context.Context, in *GetRequest, opts ...client.CallOption) (*GetResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Registry.GetService", in)
|
||||
out := new(GetResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryService) Register(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Registry.Register", in)
|
||||
out := new(EmptyResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryService) Deregister(ctx context.Context, in *Service, opts ...client.CallOption) (*EmptyResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Registry.Deregister", in)
|
||||
out := new(EmptyResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryService) ListServices(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Registry.ListServices", in)
|
||||
out := new(ListResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryService) Watch(ctx context.Context, in *WatchRequest, opts ...client.CallOption) (Registry_WatchService, error) {
|
||||
req := c.c.NewRequest(c.name, "Registry.Watch", &WatchRequest{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := stream.Send(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ®istryServiceWatch{stream}, nil
|
||||
}
|
||||
|
||||
type Registry_WatchService interface {
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
Recv() (*Result, error)
|
||||
}
|
||||
|
||||
type registryServiceWatch struct {
|
||||
stream client.Stream
|
||||
}
|
||||
|
||||
func (x *registryServiceWatch) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *registryServiceWatch) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *registryServiceWatch) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *registryServiceWatch) Recv() (*Result, error) {
|
||||
m := new(Result)
|
||||
err := x.stream.Recv(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Server API for Registry service
|
||||
|
||||
type RegistryHandler interface {
|
||||
GetService(context.Context, *GetRequest, *GetResponse) error
|
||||
Register(context.Context, *Service, *EmptyResponse) error
|
||||
Deregister(context.Context, *Service, *EmptyResponse) error
|
||||
ListServices(context.Context, *ListRequest, *ListResponse) error
|
||||
Watch(context.Context, *WatchRequest, Registry_WatchStream) error
|
||||
}
|
||||
|
||||
func RegisterRegistryHandler(s server.Server, hdlr RegistryHandler, opts ...server.HandlerOption) error {
|
||||
type registry interface {
|
||||
GetService(ctx context.Context, in *GetRequest, out *GetResponse) error
|
||||
Register(ctx context.Context, in *Service, out *EmptyResponse) error
|
||||
Deregister(ctx context.Context, in *Service, out *EmptyResponse) error
|
||||
ListServices(ctx context.Context, in *ListRequest, out *ListResponse) error
|
||||
Watch(ctx context.Context, stream server.Stream) error
|
||||
}
|
||||
type Registry struct {
|
||||
registry
|
||||
}
|
||||
h := ®istryHandler{hdlr}
|
||||
return s.Handle(s.NewHandler(&Registry{h}, opts...))
|
||||
}
|
||||
|
||||
type registryHandler struct {
|
||||
RegistryHandler
|
||||
}
|
||||
|
||||
func (h *registryHandler) GetService(ctx context.Context, in *GetRequest, out *GetResponse) error {
|
||||
return h.RegistryHandler.GetService(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *registryHandler) Register(ctx context.Context, in *Service, out *EmptyResponse) error {
|
||||
return h.RegistryHandler.Register(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *registryHandler) Deregister(ctx context.Context, in *Service, out *EmptyResponse) error {
|
||||
return h.RegistryHandler.Deregister(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *registryHandler) ListServices(ctx context.Context, in *ListRequest, out *ListResponse) error {
|
||||
return h.RegistryHandler.ListServices(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *registryHandler) Watch(ctx context.Context, stream server.Stream) error {
|
||||
m := new(WatchRequest)
|
||||
if err := stream.Recv(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return h.RegistryHandler.Watch(ctx, m, ®istryWatchStream{stream})
|
||||
}
|
||||
|
||||
type Registry_WatchStream interface {
|
||||
SendMsg(interface{}) error
|
||||
RecvMsg(interface{}) error
|
||||
Close() error
|
||||
Send(*Result) error
|
||||
}
|
||||
|
||||
type registryWatchStream struct {
|
||||
stream server.Stream
|
||||
}
|
||||
|
||||
func (x *registryWatchStream) Close() error {
|
||||
return x.stream.Close()
|
||||
}
|
||||
|
||||
func (x *registryWatchStream) SendMsg(m interface{}) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
||||
|
||||
func (x *registryWatchStream) RecvMsg(m interface{}) error {
|
||||
return x.stream.Recv(m)
|
||||
}
|
||||
|
||||
func (x *registryWatchStream) Send(m *Result) error {
|
||||
return x.stream.Send(m)
|
||||
}
|
848
registry/proto/registry.pb.go
Normal file
848
registry/proto/registry.pb.go
Normal file
@@ -0,0 +1,848 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: micro/go-micro/registry/proto/registry.proto
|
||||
|
||||
package go_micro_registry
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// Service represents a go-micro service
|
||||
type Service struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
|
||||
Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Endpoints []*Endpoint `protobuf:"bytes,4,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
|
||||
Nodes []*Node `protobuf:"bytes,5,rep,name=nodes,proto3" json:"nodes,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Service) Reset() { *m = Service{} }
|
||||
func (m *Service) String() string { return proto.CompactTextString(m) }
|
||||
func (*Service) ProtoMessage() {}
|
||||
func (*Service) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{0}
|
||||
}
|
||||
|
||||
func (m *Service) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Service.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Service) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Service.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Service) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Service.Merge(m, src)
|
||||
}
|
||||
func (m *Service) XXX_Size() int {
|
||||
return xxx_messageInfo_Service.Size(m)
|
||||
}
|
||||
func (m *Service) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Service.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Service proto.InternalMessageInfo
|
||||
|
||||
func (m *Service) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Service) GetVersion() string {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Service) GetMetadata() map[string]string {
|
||||
if m != nil {
|
||||
return m.Metadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Service) GetEndpoints() []*Endpoint {
|
||||
if m != nil {
|
||||
return m.Endpoints
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Service) GetNodes() []*Node {
|
||||
if m != nil {
|
||||
return m.Nodes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Node represents the node the service is on
|
||||
type Node struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
|
||||
Port int64 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"`
|
||||
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Node) Reset() { *m = Node{} }
|
||||
func (m *Node) String() string { return proto.CompactTextString(m) }
|
||||
func (*Node) ProtoMessage() {}
|
||||
func (*Node) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{1}
|
||||
}
|
||||
|
||||
func (m *Node) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Node.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Node.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Node) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Node.Merge(m, src)
|
||||
}
|
||||
func (m *Node) XXX_Size() int {
|
||||
return xxx_messageInfo_Node.Size(m)
|
||||
}
|
||||
func (m *Node) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Node.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Node proto.InternalMessageInfo
|
||||
|
||||
func (m *Node) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Node) GetAddress() string {
|
||||
if m != nil {
|
||||
return m.Address
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Node) GetPort() int64 {
|
||||
if m != nil {
|
||||
return m.Port
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Node) GetMetadata() map[string]string {
|
||||
if m != nil {
|
||||
return m.Metadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Endpoint is a endpoint provided by a service
|
||||
type Endpoint struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Request *Value `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"`
|
||||
Response *Value `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"`
|
||||
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Endpoint) Reset() { *m = Endpoint{} }
|
||||
func (m *Endpoint) String() string { return proto.CompactTextString(m) }
|
||||
func (*Endpoint) ProtoMessage() {}
|
||||
func (*Endpoint) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{2}
|
||||
}
|
||||
|
||||
func (m *Endpoint) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Endpoint.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Endpoint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Endpoint.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Endpoint) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Endpoint.Merge(m, src)
|
||||
}
|
||||
func (m *Endpoint) XXX_Size() int {
|
||||
return xxx_messageInfo_Endpoint.Size(m)
|
||||
}
|
||||
func (m *Endpoint) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Endpoint.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Endpoint proto.InternalMessageInfo
|
||||
|
||||
func (m *Endpoint) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Endpoint) GetRequest() *Value {
|
||||
if m != nil {
|
||||
return m.Request
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Endpoint) GetResponse() *Value {
|
||||
if m != nil {
|
||||
return m.Response
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Endpoint) GetMetadata() map[string]string {
|
||||
if m != nil {
|
||||
return m.Metadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value is an opaque value for a request or response
|
||||
type Value struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Values []*Value `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Value) Reset() { *m = Value{} }
|
||||
func (m *Value) String() string { return proto.CompactTextString(m) }
|
||||
func (*Value) ProtoMessage() {}
|
||||
func (*Value) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{3}
|
||||
}
|
||||
|
||||
func (m *Value) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Value.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Value.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Value) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Value.Merge(m, src)
|
||||
}
|
||||
func (m *Value) XXX_Size() int {
|
||||
return xxx_messageInfo_Value.Size(m)
|
||||
}
|
||||
func (m *Value) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Value.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Value proto.InternalMessageInfo
|
||||
|
||||
func (m *Value) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Value) GetType() string {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Value) GetValues() []*Value {
|
||||
if m != nil {
|
||||
return m.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Result is returns by the watcher
|
||||
type Result struct {
|
||||
Action string `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"`
|
||||
Service *Service `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"`
|
||||
Timestamp int64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Result) Reset() { *m = Result{} }
|
||||
func (m *Result) String() string { return proto.CompactTextString(m) }
|
||||
func (*Result) ProtoMessage() {}
|
||||
func (*Result) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{4}
|
||||
}
|
||||
|
||||
func (m *Result) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Result.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Result) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Result.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Result) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Result.Merge(m, src)
|
||||
}
|
||||
func (m *Result) XXX_Size() int {
|
||||
return xxx_messageInfo_Result.Size(m)
|
||||
}
|
||||
func (m *Result) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Result.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Result proto.InternalMessageInfo
|
||||
|
||||
func (m *Result) GetAction() string {
|
||||
if m != nil {
|
||||
return m.Action
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Result) GetService() *Service {
|
||||
if m != nil {
|
||||
return m.Service
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Result) GetTimestamp() int64 {
|
||||
if m != nil {
|
||||
return m.Timestamp
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type EmptyResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EmptyResponse) Reset() { *m = EmptyResponse{} }
|
||||
func (m *EmptyResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*EmptyResponse) ProtoMessage() {}
|
||||
func (*EmptyResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{5}
|
||||
}
|
||||
|
||||
func (m *EmptyResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EmptyResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EmptyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EmptyResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EmptyResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EmptyResponse.Merge(m, src)
|
||||
}
|
||||
func (m *EmptyResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_EmptyResponse.Size(m)
|
||||
}
|
||||
func (m *EmptyResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EmptyResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EmptyResponse proto.InternalMessageInfo
|
||||
|
||||
type GetRequest struct {
|
||||
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetRequest) Reset() { *m = GetRequest{} }
|
||||
func (m *GetRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetRequest) ProtoMessage() {}
|
||||
func (*GetRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{6}
|
||||
}
|
||||
|
||||
func (m *GetRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetRequest.Merge(m, src)
|
||||
}
|
||||
func (m *GetRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_GetRequest.Size(m)
|
||||
}
|
||||
func (m *GetRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetRequest) GetService() string {
|
||||
if m != nil {
|
||||
return m.Service
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetResponse struct {
|
||||
Services []*Service `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetResponse) Reset() { *m = GetResponse{} }
|
||||
func (m *GetResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetResponse) ProtoMessage() {}
|
||||
func (*GetResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{7}
|
||||
}
|
||||
|
||||
func (m *GetResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetResponse.Merge(m, src)
|
||||
}
|
||||
func (m *GetResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_GetResponse.Size(m)
|
||||
}
|
||||
func (m *GetResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *GetResponse) GetServices() []*Service {
|
||||
if m != nil {
|
||||
return m.Services
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListRequest) Reset() { *m = ListRequest{} }
|
||||
func (m *ListRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListRequest) ProtoMessage() {}
|
||||
func (*ListRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{8}
|
||||
}
|
||||
|
||||
func (m *ListRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ListRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ListRequest.Size(m)
|
||||
}
|
||||
func (m *ListRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListRequest proto.InternalMessageInfo
|
||||
|
||||
type ListResponse struct {
|
||||
Services []*Service `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListResponse) Reset() { *m = ListResponse{} }
|
||||
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListResponse) ProtoMessage() {}
|
||||
func (*ListResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{9}
|
||||
}
|
||||
|
||||
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ListResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ListResponse.Size(m)
|
||||
}
|
||||
func (m *ListResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ListResponse) GetServices() []*Service {
|
||||
if m != nil {
|
||||
return m.Services
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WatchRequest struct {
|
||||
// service is optional
|
||||
Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WatchRequest) Reset() { *m = WatchRequest{} }
|
||||
func (m *WatchRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*WatchRequest) ProtoMessage() {}
|
||||
func (*WatchRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f287a6b809166ad2, []int{10}
|
||||
}
|
||||
|
||||
func (m *WatchRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WatchRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WatchRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WatchRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WatchRequest.Merge(m, src)
|
||||
}
|
||||
func (m *WatchRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_WatchRequest.Size(m)
|
||||
}
|
||||
func (m *WatchRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WatchRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WatchRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *WatchRequest) GetService() string {
|
||||
if m != nil {
|
||||
return m.Service
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Service)(nil), "go.micro.registry.Service")
|
||||
proto.RegisterMapType((map[string]string)(nil), "go.micro.registry.Service.MetadataEntry")
|
||||
proto.RegisterType((*Node)(nil), "go.micro.registry.Node")
|
||||
proto.RegisterMapType((map[string]string)(nil), "go.micro.registry.Node.MetadataEntry")
|
||||
proto.RegisterType((*Endpoint)(nil), "go.micro.registry.Endpoint")
|
||||
proto.RegisterMapType((map[string]string)(nil), "go.micro.registry.Endpoint.MetadataEntry")
|
||||
proto.RegisterType((*Value)(nil), "go.micro.registry.Value")
|
||||
proto.RegisterType((*Result)(nil), "go.micro.registry.Result")
|
||||
proto.RegisterType((*EmptyResponse)(nil), "go.micro.registry.EmptyResponse")
|
||||
proto.RegisterType((*GetRequest)(nil), "go.micro.registry.GetRequest")
|
||||
proto.RegisterType((*GetResponse)(nil), "go.micro.registry.GetResponse")
|
||||
proto.RegisterType((*ListRequest)(nil), "go.micro.registry.ListRequest")
|
||||
proto.RegisterType((*ListResponse)(nil), "go.micro.registry.ListResponse")
|
||||
proto.RegisterType((*WatchRequest)(nil), "go.micro.registry.WatchRequest")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("micro/go-micro/registry/proto/registry.proto", fileDescriptor_f287a6b809166ad2)
|
||||
}
|
||||
|
||||
var fileDescriptor_f287a6b809166ad2 = []byte{
|
||||
// 577 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0x6d, 0x8b, 0xd3, 0x4c,
|
||||
0x14, 0x6d, 0x92, 0xbe, 0xde, 0x6e, 0x9f, 0x47, 0x2f, 0xa2, 0x31, 0xbe, 0x95, 0x80, 0x52, 0xc1,
|
||||
0xcd, 0x2e, 0x75, 0x11, 0x5f, 0x3e, 0x09, 0x5b, 0x17, 0x64, 0x57, 0x70, 0x04, 0xfd, 0x1c, 0x9b,
|
||||
0x4b, 0x0d, 0x6e, 0x5e, 0x9c, 0x99, 0x16, 0xfa, 0x1f, 0x04, 0xff, 0x84, 0x3f, 0xc5, 0x1f, 0x26,
|
||||
0x99, 0xcc, 0x34, 0x5d, 0x36, 0xa9, 0x1f, 0x56, 0xbf, 0xcd, 0xcd, 0x9c, 0x73, 0xe6, 0x9e, 0x73,
|
||||
0x67, 0x5a, 0x78, 0x92, 0xc4, 0x73, 0x9e, 0x1d, 0x2c, 0xb2, 0xfd, 0x72, 0xc1, 0x69, 0x11, 0x0b,
|
||||
0xc9, 0xd7, 0x07, 0x39, 0xcf, 0x64, 0x55, 0x06, 0xaa, 0xc4, 0xeb, 0x8b, 0x2c, 0x50, 0xb8, 0xc0,
|
||||
0x6c, 0xf8, 0x3f, 0x6d, 0xe8, 0x7d, 0x20, 0xbe, 0x8a, 0xe7, 0x84, 0x08, 0xed, 0x34, 0x4c, 0xc8,
|
||||
0xb5, 0xc6, 0xd6, 0x64, 0xc0, 0xd4, 0x1a, 0x5d, 0xe8, 0xad, 0x88, 0x8b, 0x38, 0x4b, 0x5d, 0x5b,
|
||||
0x7d, 0x36, 0x25, 0x1e, 0x43, 0x3f, 0x21, 0x19, 0x46, 0xa1, 0x0c, 0x5d, 0x67, 0xec, 0x4c, 0x86,
|
||||
0xd3, 0x49, 0x70, 0x49, 0x3f, 0xd0, 0xda, 0xc1, 0x99, 0x86, 0xce, 0x52, 0xc9, 0xd7, 0x6c, 0xc3,
|
||||
0xc4, 0x17, 0x30, 0xa0, 0x34, 0xca, 0xb3, 0x38, 0x95, 0xc2, 0x6d, 0x2b, 0x99, 0x3b, 0x35, 0x32,
|
||||
0x33, 0x8d, 0x61, 0x15, 0x1a, 0xf7, 0xa1, 0x93, 0x66, 0x11, 0x09, 0xb7, 0xa3, 0x68, 0xb7, 0x6a,
|
||||
0x68, 0xef, 0xb2, 0x88, 0x58, 0x89, 0xf2, 0x5e, 0xc1, 0xe8, 0x42, 0x13, 0x78, 0x0d, 0x9c, 0xaf,
|
||||
0xb4, 0xd6, 0x6e, 0x8b, 0x25, 0xde, 0x80, 0xce, 0x2a, 0x3c, 0x5f, 0x92, 0xb6, 0x5a, 0x16, 0x2f,
|
||||
0xed, 0xe7, 0x96, 0xff, 0xcb, 0x82, 0x76, 0x21, 0x86, 0xff, 0x81, 0x1d, 0x47, 0x9a, 0x63, 0xc7,
|
||||
0x51, 0x91, 0x4f, 0x18, 0x45, 0x9c, 0x84, 0x30, 0xf9, 0xe8, 0xb2, 0x48, 0x33, 0xcf, 0xb8, 0x74,
|
||||
0x9d, 0xb1, 0x35, 0x71, 0x98, 0x5a, 0xe3, 0xeb, 0xad, 0xcc, 0x4a, 0xb3, 0x0f, 0x1b, 0xba, 0x6e,
|
||||
0x0a, 0xec, 0x6a, 0x36, 0xbe, 0xdb, 0xd0, 0x37, 0x51, 0xd6, 0x8e, 0x7b, 0x0a, 0x3d, 0x4e, 0xdf,
|
||||
0x96, 0x24, 0xa4, 0x22, 0x0f, 0xa7, 0x6e, 0x4d, 0x7f, 0x1f, 0x0b, 0x3d, 0x66, 0x80, 0x78, 0x04,
|
||||
0x7d, 0x4e, 0x22, 0xcf, 0x52, 0x41, 0xca, 0xec, 0x2e, 0xd2, 0x06, 0x89, 0xb3, 0x4b, 0x51, 0x3c,
|
||||
0xde, 0x31, 0xf7, 0x7f, 0x13, 0x47, 0x08, 0x1d, 0xd5, 0x56, 0x6d, 0x14, 0x08, 0x6d, 0xb9, 0xce,
|
||||
0x0d, 0x4b, 0xad, 0xf1, 0x10, 0xba, 0x8a, 0x2d, 0xf4, 0x8d, 0x6f, 0x36, 0xaa, 0x71, 0xbe, 0x84,
|
||||
0x2e, 0x23, 0xb1, 0x3c, 0x97, 0x78, 0x13, 0xba, 0xe1, 0x5c, 0x16, 0x0f, 0xa9, 0x3c, 0x45, 0x57,
|
||||
0x78, 0x04, 0x3d, 0x51, 0x3e, 0x12, 0x1d, 0xb9, 0xd7, 0xfc, 0x8c, 0x98, 0x81, 0xe2, 0x5d, 0x18,
|
||||
0xc8, 0x38, 0x21, 0x21, 0xc3, 0x24, 0xd7, 0x57, 0xac, 0xfa, 0xe0, 0xff, 0x0f, 0xa3, 0x59, 0x92,
|
||||
0xcb, 0x35, 0xd3, 0x69, 0xfb, 0x8f, 0x00, 0x4e, 0x48, 0x32, 0x3d, 0x31, 0xb7, 0x3a, 0xb2, 0xec,
|
||||
0xc5, 0x94, 0xfe, 0x0c, 0x86, 0x0a, 0xa7, 0x87, 0xf4, 0x0c, 0xfa, 0x7a, 0x47, 0xb8, 0x96, 0x72,
|
||||
0xbc, 0xab, 0xb9, 0x0d, 0xd6, 0x1f, 0xc1, 0xf0, 0x34, 0x16, 0xe6, 0x3c, 0xff, 0x0d, 0xec, 0x95,
|
||||
0xe5, 0x15, 0x65, 0x27, 0xb0, 0xf7, 0x29, 0x94, 0xf3, 0x2f, 0x7f, 0xf4, 0x31, 0xfd, 0xe1, 0x40,
|
||||
0x9f, 0x69, 0x21, 0x3c, 0x53, 0xe6, 0xcd, 0xaf, 0xdc, 0xbd, 0x9a, 0xa3, 0xaa, 0x6c, 0xbc, 0xfb,
|
||||
0x4d, 0xdb, 0x3a, 0xc9, 0x16, 0xbe, 0x35, 0xd2, 0xc4, 0x71, 0x47, 0xdf, 0xde, 0xb8, 0xee, 0x3e,
|
||||
0x5f, 0x98, 0x4a, 0x0b, 0x4f, 0x01, 0x8e, 0x89, 0xff, 0x2d, 0xb5, 0xf7, 0x65, 0xce, 0x9a, 0x22,
|
||||
0xb0, 0xce, 0xcb, 0xd6, 0x5c, 0xbc, 0x07, 0x8d, 0xfb, 0x1b, 0xc9, 0x13, 0xe8, 0xa8, 0xc8, 0xb1,
|
||||
0x0e, 0xbb, 0x3d, 0x0c, 0xef, 0x76, 0x0d, 0xa0, 0xbc, 0xfa, 0x7e, 0xeb, 0xd0, 0xfa, 0xdc, 0x55,
|
||||
0x7f, 0x41, 0x4f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x0b, 0x12, 0xd6, 0xb2, 0x06, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// RegistryClient is the client API for Registry service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type RegistryClient interface {
|
||||
GetService(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error)
|
||||
Register(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error)
|
||||
Deregister(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error)
|
||||
ListServices(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error)
|
||||
Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (Registry_WatchClient, error)
|
||||
}
|
||||
|
||||
type registryClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewRegistryClient(cc *grpc.ClientConn) RegistryClient {
|
||||
return ®istryClient{cc}
|
||||
}
|
||||
|
||||
func (c *registryClient) GetService(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) {
|
||||
out := new(GetResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/GetService", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryClient) Register(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error) {
|
||||
out := new(EmptyResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/Register", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryClient) Deregister(ctx context.Context, in *Service, opts ...grpc.CallOption) (*EmptyResponse, error) {
|
||||
out := new(EmptyResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/Deregister", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryClient) ListServices(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
|
||||
out := new(ListResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.registry.Registry/ListServices", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *registryClient) Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (Registry_WatchClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_Registry_serviceDesc.Streams[0], "/go.micro.registry.Registry/Watch", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
x := ®istryWatchClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := x.ClientStream.CloseSend(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return x, nil
|
||||
}
|
||||
|
||||
type Registry_WatchClient interface {
|
||||
Recv() (*Result, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type registryWatchClient struct {
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *registryWatchClient) Recv() (*Result, error) {
|
||||
m := new(Result)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// RegistryServer is the server API for Registry service.
|
||||
type RegistryServer interface {
|
||||
GetService(context.Context, *GetRequest) (*GetResponse, error)
|
||||
Register(context.Context, *Service) (*EmptyResponse, error)
|
||||
Deregister(context.Context, *Service) (*EmptyResponse, error)
|
||||
ListServices(context.Context, *ListRequest) (*ListResponse, error)
|
||||
Watch(*WatchRequest, Registry_WatchServer) error
|
||||
}
|
||||
|
||||
func RegisterRegistryServer(s *grpc.Server, srv RegistryServer) {
|
||||
s.RegisterService(&_Registry_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Registry_GetService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServer).GetService(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.registry.Registry/GetService",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServer).GetService(ctx, req.(*GetRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Registry_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Service)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServer).Register(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.registry.Registry/Register",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServer).Register(ctx, req.(*Service))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Registry_Deregister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Service)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServer).Deregister(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.registry.Registry/Deregister",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServer).Deregister(ctx, req.(*Service))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Registry_ListServices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RegistryServer).ListServices(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.registry.Registry/ListServices",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RegistryServer).ListServices(ctx, req.(*ListRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Registry_Watch_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(WatchRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
return srv.(RegistryServer).Watch(m, ®istryWatchServer{stream})
|
||||
}
|
||||
|
||||
type Registry_WatchServer interface {
|
||||
Send(*Result) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type registryWatchServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *registryWatchServer) Send(m *Result) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
var _Registry_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "go.micro.registry.Registry",
|
||||
HandlerType: (*RegistryServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetService",
|
||||
Handler: _Registry_GetService_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Register",
|
||||
Handler: _Registry_Register_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Deregister",
|
||||
Handler: _Registry_Deregister_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListServices",
|
||||
Handler: _Registry_ListServices_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Watch",
|
||||
Handler: _Registry_Watch_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "micro/go-micro/registry/proto/registry.proto",
|
||||
}
|
73
registry/proto/registry.proto
Normal file
73
registry/proto/registry.proto
Normal file
@@ -0,0 +1,73 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package go.micro.registry;
|
||||
|
||||
service Registry {
|
||||
rpc GetService(GetRequest) returns (GetResponse) {};
|
||||
rpc Register(Service) returns (EmptyResponse) {};
|
||||
rpc Deregister(Service) returns (EmptyResponse) {};
|
||||
rpc ListServices(ListRequest) returns (ListResponse) {};
|
||||
rpc Watch(WatchRequest) returns (stream Result) {};
|
||||
}
|
||||
|
||||
// Service represents a go-micro service
|
||||
message Service {
|
||||
string name = 1;
|
||||
string version = 2;
|
||||
map<string,string> metadata = 3;
|
||||
repeated Endpoint endpoints = 4;
|
||||
repeated Node nodes = 5;
|
||||
}
|
||||
|
||||
// Node represents the node the service is on
|
||||
message Node {
|
||||
string id = 1;
|
||||
string address = 2;
|
||||
int64 port = 3;
|
||||
map<string,string> metadata = 4;
|
||||
}
|
||||
|
||||
// Endpoint is a endpoint provided by a service
|
||||
message Endpoint {
|
||||
string name = 1;
|
||||
Value request = 2;
|
||||
Value response = 3;
|
||||
map<string, string> metadata = 4;
|
||||
}
|
||||
|
||||
// Value is an opaque value for a request or response
|
||||
message Value {
|
||||
string name = 1;
|
||||
string type = 2;
|
||||
repeated Value values = 3;
|
||||
}
|
||||
|
||||
// Result is returns by the watcher
|
||||
message Result {
|
||||
string action = 1; // create, update, delete
|
||||
Service service = 2;
|
||||
int64 timestamp = 3; // unix timestamp
|
||||
}
|
||||
|
||||
message EmptyResponse {}
|
||||
|
||||
message GetRequest {
|
||||
string service = 1;
|
||||
}
|
||||
|
||||
message GetResponse {
|
||||
repeated Service services = 1;
|
||||
}
|
||||
|
||||
message ListRequest {
|
||||
// TODO: filtering
|
||||
}
|
||||
|
||||
message ListResponse {
|
||||
repeated Service services = 1;
|
||||
}
|
||||
|
||||
message WatchRequest {
|
||||
// service is optional
|
||||
string service = 1;
|
||||
}
|
@@ -29,7 +29,7 @@ var (
|
||||
DefaultRegistry = NewRegistry()
|
||||
|
||||
// Not found error when GetService is called
|
||||
ErrNotFound = errors.New("not found")
|
||||
ErrNotFound = errors.New("service not found")
|
||||
// Watcher stopped error when watcher is stopped
|
||||
ErrWatcherStopped = errors.New("watcher stopped")
|
||||
)
|
||||
|
155
registry/service/service.go
Normal file
155
registry/service/service.go
Normal file
@@ -0,0 +1,155 @@
|
||||
// Package service uses the registry service
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/registry"
|
||||
pb "github.com/micro/go-micro/registry/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
// The default service name
|
||||
DefaultService = "go.micro.service"
|
||||
)
|
||||
|
||||
type serviceRegistry struct {
|
||||
opts registry.Options
|
||||
// name of the registry
|
||||
name string
|
||||
// address
|
||||
address []string
|
||||
// client to call registry
|
||||
client pb.RegistryService
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) callOpts() []client.CallOption {
|
||||
var opts []client.CallOption
|
||||
|
||||
// set registry address
|
||||
if len(s.address) > 0 {
|
||||
opts = append(opts, client.WithAddress(s.address...))
|
||||
}
|
||||
|
||||
// set timeout
|
||||
if s.opts.Timeout > time.Duration(0) {
|
||||
opts = append(opts, client.WithRequestTimeout(s.opts.Timeout))
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) Init(opts ...registry.Option) error {
|
||||
for _, o := range opts {
|
||||
o(&s.opts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) Options() registry.Options {
|
||||
return s.opts
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) Register(srv *registry.Service, opts ...registry.RegisterOption) error {
|
||||
var options registry.RegisterOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
// register the service
|
||||
_, err := s.client.Register(context.TODO(), ToProto(srv), s.callOpts()...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) Deregister(srv *registry.Service) error {
|
||||
// deregister the service
|
||||
_, err := s.client.Deregister(context.TODO(), ToProto(srv), s.callOpts()...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) GetService(name string) ([]*registry.Service, error) {
|
||||
rsp, err := s.client.GetService(context.TODO(), &pb.GetRequest{
|
||||
Service: name,
|
||||
}, s.callOpts()...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
for _, service := range rsp.Services {
|
||||
services = append(services, ToService(service))
|
||||
}
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) ListServices() ([]*registry.Service, error) {
|
||||
rsp, err := s.client.ListServices(context.TODO(), &pb.ListRequest{}, s.callOpts()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var services []*registry.Service
|
||||
for _, service := range rsp.Services {
|
||||
services = append(services, ToService(service))
|
||||
}
|
||||
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
|
||||
var options registry.WatchOptions
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
stream, err := s.client.Watch(context.TODO(), &pb.WatchRequest{
|
||||
Service: options.Service,
|
||||
}, s.callOpts()...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newWatcher(stream), nil
|
||||
}
|
||||
|
||||
func (s *serviceRegistry) String() string {
|
||||
return s.name
|
||||
}
|
||||
|
||||
// NewRegistry returns a new registry service client
|
||||
func NewRegistry(opts ...registry.Option) registry.Registry {
|
||||
var options registry.Options
|
||||
for _, o := range opts {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
// use mdns to find the service registry
|
||||
mReg := registry.NewRegistry()
|
||||
|
||||
// create new client with mdns
|
||||
cli := client.NewClient(
|
||||
client.Registry(mReg),
|
||||
)
|
||||
|
||||
// service name
|
||||
// TODO: accept option
|
||||
name := DefaultService
|
||||
|
||||
return &serviceRegistry{
|
||||
opts: options,
|
||||
name: name,
|
||||
address: options.Addrs,
|
||||
client: pb.NewRegistryService(name, cli),
|
||||
}
|
||||
}
|
133
registry/service/util.go
Normal file
133
registry/service/util.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/registry"
|
||||
pb "github.com/micro/go-micro/registry/proto"
|
||||
)
|
||||
|
||||
func values(v []*registry.Value) []*pb.Value {
|
||||
if len(v) == 0 {
|
||||
return []*pb.Value{}
|
||||
}
|
||||
|
||||
var vs []*pb.Value
|
||||
for _, vi := range v {
|
||||
vs = append(vs, &pb.Value{
|
||||
Name: vi.Name,
|
||||
Type: vi.Type,
|
||||
Values: values(vi.Values),
|
||||
})
|
||||
}
|
||||
return vs
|
||||
}
|
||||
|
||||
func toValues(v []*pb.Value) []*registry.Value {
|
||||
if len(v) == 0 {
|
||||
return []*registry.Value{}
|
||||
}
|
||||
|
||||
var vs []*registry.Value
|
||||
for _, vi := range v {
|
||||
vs = append(vs, ®istry.Value{
|
||||
Name: vi.Name,
|
||||
Type: vi.Type,
|
||||
Values: toValues(vi.Values),
|
||||
})
|
||||
}
|
||||
return vs
|
||||
}
|
||||
|
||||
func ToProto(s *registry.Service) *pb.Service {
|
||||
var endpoints []*pb.Endpoint
|
||||
for _, ep := range s.Endpoints {
|
||||
var request, response *pb.Value
|
||||
|
||||
if ep.Request != nil {
|
||||
request = &pb.Value{
|
||||
Name: ep.Request.Name,
|
||||
Type: ep.Request.Type,
|
||||
Values: values(ep.Request.Values),
|
||||
}
|
||||
}
|
||||
|
||||
if ep.Response != nil {
|
||||
response = &pb.Value{
|
||||
Name: ep.Response.Name,
|
||||
Type: ep.Response.Type,
|
||||
Values: values(ep.Response.Values),
|
||||
}
|
||||
}
|
||||
|
||||
endpoints = append(endpoints, &pb.Endpoint{
|
||||
Name: ep.Name,
|
||||
Request: request,
|
||||
Response: response,
|
||||
Metadata: ep.Metadata,
|
||||
})
|
||||
}
|
||||
|
||||
var nodes []*pb.Node
|
||||
|
||||
for _, node := range s.Nodes {
|
||||
nodes = append(nodes, &pb.Node{
|
||||
Id: node.Id,
|
||||
Address: node.Address,
|
||||
Metadata: node.Metadata,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.Service{
|
||||
Name: s.Name,
|
||||
Version: s.Version,
|
||||
Metadata: s.Metadata,
|
||||
Endpoints: endpoints,
|
||||
Nodes: nodes,
|
||||
}
|
||||
}
|
||||
|
||||
func ToService(s *pb.Service) *registry.Service {
|
||||
var endpoints []*registry.Endpoint
|
||||
for _, ep := range s.Endpoints {
|
||||
var request, response *registry.Value
|
||||
|
||||
if ep.Request != nil {
|
||||
request = ®istry.Value{
|
||||
Name: ep.Request.Name,
|
||||
Type: ep.Request.Type,
|
||||
Values: toValues(ep.Request.Values),
|
||||
}
|
||||
}
|
||||
|
||||
if ep.Response != nil {
|
||||
response = ®istry.Value{
|
||||
Name: ep.Response.Name,
|
||||
Type: ep.Response.Type,
|
||||
Values: toValues(ep.Response.Values),
|
||||
}
|
||||
}
|
||||
|
||||
endpoints = append(endpoints, ®istry.Endpoint{
|
||||
Name: ep.Name,
|
||||
Request: request,
|
||||
Response: response,
|
||||
Metadata: ep.Metadata,
|
||||
})
|
||||
}
|
||||
|
||||
var nodes []*registry.Node
|
||||
for _, node := range s.Nodes {
|
||||
nodes = append(nodes, ®istry.Node{
|
||||
Id: node.Id,
|
||||
Address: node.Address,
|
||||
Metadata: node.Metadata,
|
||||
})
|
||||
}
|
||||
|
||||
return ®istry.Service{
|
||||
Name: s.Name,
|
||||
Version: s.Version,
|
||||
Metadata: s.Metadata,
|
||||
Endpoints: endpoints,
|
||||
Nodes: nodes,
|
||||
}
|
||||
}
|
49
registry/service/watcher.go
Normal file
49
registry/service/watcher.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/registry"
|
||||
pb "github.com/micro/go-micro/registry/proto"
|
||||
)
|
||||
|
||||
type serviceWatcher struct {
|
||||
stream pb.Registry_WatchService
|
||||
closed chan bool
|
||||
}
|
||||
|
||||
func (s *serviceWatcher) Next() (*registry.Result, error) {
|
||||
for {
|
||||
// check if closed
|
||||
select {
|
||||
case <-s.closed:
|
||||
return nil, registry.ErrWatcherStopped
|
||||
default:
|
||||
}
|
||||
|
||||
r, err := s.stream.Recv()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ®istry.Result{
|
||||
Action: r.Action,
|
||||
Service: ToService(r.Service),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *serviceWatcher) Stop() {
|
||||
select {
|
||||
case <-s.closed:
|
||||
return
|
||||
default:
|
||||
close(s.closed)
|
||||
s.stream.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func newWatcher(stream pb.Registry_WatchService) registry.Watcher {
|
||||
return &serviceWatcher{
|
||||
stream: stream,
|
||||
closed: make(chan bool),
|
||||
}
|
||||
}
|
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/micro/go-micro/registry"
|
||||
"github.com/micro/go-micro/util/log"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -43,10 +44,9 @@ var (
|
||||
// router implements default router
|
||||
type router struct {
|
||||
sync.RWMutex
|
||||
// embed the table
|
||||
table *table
|
||||
opts Options
|
||||
options Options
|
||||
status Status
|
||||
table *table
|
||||
exit chan struct{}
|
||||
errChan chan error
|
||||
eventChan chan *Event
|
||||
@@ -67,33 +67,41 @@ func newRouter(opts ...Option) Router {
|
||||
o(&options)
|
||||
}
|
||||
|
||||
r := &router{
|
||||
// set initial status to Stopped
|
||||
status := Status{Code: Stopped, Error: nil}
|
||||
|
||||
return &router{
|
||||
options: options,
|
||||
status: status,
|
||||
table: newTable(),
|
||||
opts: options,
|
||||
status: Status{Code: Stopped, Error: nil},
|
||||
advertWg: &sync.WaitGroup{},
|
||||
wg: &sync.WaitGroup{},
|
||||
subscribers: make(map[string]chan *Advert),
|
||||
}
|
||||
|
||||
go r.run()
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// Init initializes router with given options
|
||||
func (r *router) Init(opts ...Option) error {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
for _, o := range opts {
|
||||
o(&r.opts)
|
||||
o(&r.options)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Options returns router options
|
||||
func (r *router) Options() Options {
|
||||
return r.opts
|
||||
r.Lock()
|
||||
options := r.options
|
||||
r.Unlock()
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
// Table returns routing table
|
||||
func (r *router) Table() Table {
|
||||
return r.table
|
||||
}
|
||||
@@ -113,6 +121,9 @@ func (r *router) manageRoute(route Route, action string) error {
|
||||
if err := r.table.Delete(route); err != nil && err != ErrRouteNotFound {
|
||||
return fmt.Errorf("failed deleting route for service %s: %s", route.Service, err)
|
||||
}
|
||||
case "solicit":
|
||||
// nothing to do here
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("failed to manage route for service %s. Unknown action: %s", route.Service, action)
|
||||
}
|
||||
@@ -132,7 +143,8 @@ func (r *router) manageServiceRoutes(service *registry.Service, action string) e
|
||||
Service: service.Name,
|
||||
Address: node.Address,
|
||||
Gateway: "",
|
||||
Network: r.opts.Network,
|
||||
Network: r.options.Network,
|
||||
Router: r.options.Id,
|
||||
Link: DefaultLink,
|
||||
Metric: DefaultLocalMetric,
|
||||
}
|
||||
@@ -174,13 +186,26 @@ func (r *router) manageRegistryRoutes(reg registry.Registry, action string) erro
|
||||
// watchRegistry watches registry and updates routing table based on the received events.
|
||||
// It returns error if either the registry watcher fails with error or if the routing table update fails.
|
||||
func (r *router) watchRegistry(w registry.Watcher) error {
|
||||
exit := make(chan bool)
|
||||
|
||||
defer func() {
|
||||
// close the exit channel when the go routine finishes
|
||||
close(exit)
|
||||
r.wg.Done()
|
||||
}()
|
||||
|
||||
// wait in the background for the router to stop
|
||||
// when the router stops, stop the watcher and exit
|
||||
r.wg.Add(1)
|
||||
go func() {
|
||||
defer r.wg.Done()
|
||||
<-r.exit
|
||||
w.Stop()
|
||||
defer w.Stop()
|
||||
|
||||
select {
|
||||
case <-r.exit:
|
||||
return
|
||||
case <-exit:
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
var watchErr error
|
||||
@@ -205,13 +230,26 @@ func (r *router) watchRegistry(w registry.Watcher) error {
|
||||
// watchTable watches routing table entries and either adds or deletes locally registered service to/from network registry
|
||||
// It returns error if the locally registered services either fails to be added/deleted to/from network registry.
|
||||
func (r *router) watchTable(w Watcher) error {
|
||||
exit := make(chan bool)
|
||||
|
||||
defer func() {
|
||||
// close the exit channel when the go routine finishes
|
||||
close(exit)
|
||||
r.wg.Done()
|
||||
}()
|
||||
|
||||
// wait in the background for the router to stop
|
||||
// when the router stops, stop the watcher and exit
|
||||
r.wg.Add(1)
|
||||
go func() {
|
||||
defer r.wg.Done()
|
||||
<-r.exit
|
||||
w.Stop()
|
||||
defer w.Stop()
|
||||
|
||||
select {
|
||||
case <-r.exit:
|
||||
return
|
||||
case <-exit:
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
var watchErr error
|
||||
@@ -245,13 +283,14 @@ func (r *router) publishAdvert(advType AdvertType, events []*Event) {
|
||||
defer r.advertWg.Done()
|
||||
|
||||
a := &Advert{
|
||||
Id: r.opts.Id,
|
||||
Id: r.options.Id,
|
||||
Type: advType,
|
||||
TTL: DefaultAdvertTTL,
|
||||
Timestamp: time.Now(),
|
||||
Events: events,
|
||||
}
|
||||
|
||||
log.Debugf("Router publishing advert; %+v", a)
|
||||
r.RLock()
|
||||
for _, sub := range r.subscribers {
|
||||
// check the exit chan first
|
||||
@@ -275,6 +314,7 @@ func (r *router) publishAdvert(advType AdvertType, events []*Event) {
|
||||
func (r *router) advertiseTable() error {
|
||||
// create table advertisement ticker
|
||||
ticker := time.NewTicker(AdvertiseTableTick)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -324,6 +364,8 @@ type routeAdvert struct {
|
||||
func (r *router) advertiseEvents() error {
|
||||
// ticker to periodically scan event for advertising
|
||||
ticker := time.NewTicker(AdvertiseEventsTick)
|
||||
defer ticker.Stop()
|
||||
|
||||
// advertMap is a map of advert events
|
||||
advertMap := make(map[uint64]*routeAdvert)
|
||||
|
||||
@@ -426,7 +468,6 @@ func (r *router) advertiseEvents() error {
|
||||
// update event penalty and recorded timestamp
|
||||
advert.lastUpdate = time.Now()
|
||||
advert.penalty += penalty
|
||||
|
||||
case <-r.exit:
|
||||
// first wait for the advertiser to finish
|
||||
r.advertWg.Wait()
|
||||
@@ -435,100 +476,122 @@ func (r *router) advertiseEvents() error {
|
||||
}
|
||||
}
|
||||
|
||||
// close closes exit channels
|
||||
func (r *router) close() {
|
||||
// notify all goroutines to finish
|
||||
close(r.exit)
|
||||
|
||||
// drain the advertise channel only if advertising
|
||||
if r.status.Code == Advertising {
|
||||
// drain the event channel
|
||||
for range r.eventChan {
|
||||
}
|
||||
|
||||
// close advert subscribers
|
||||
for id, sub := range r.subscribers {
|
||||
// close the channel
|
||||
close(sub)
|
||||
|
||||
// delete the subscriber
|
||||
delete(r.subscribers, id)
|
||||
}
|
||||
}
|
||||
|
||||
// mark the router as Stopped and set its Error to nil
|
||||
r.status = Status{Code: Stopped, Error: nil}
|
||||
}
|
||||
|
||||
// watchErrors watches router errors and takes appropriate actions
|
||||
func (r *router) watchErrors() {
|
||||
var err error
|
||||
|
||||
select {
|
||||
case <-r.exit:
|
||||
return
|
||||
case err = <-r.errChan:
|
||||
}
|
||||
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
// if the router is not stopped, stop it
|
||||
if r.status.Code != Stopped {
|
||||
// notify all goroutines to finish
|
||||
close(r.exit)
|
||||
|
||||
// drain the advertise channel only if advertising
|
||||
if r.status.Code == Advertising {
|
||||
// drain the event channel
|
||||
for range r.eventChan {
|
||||
}
|
||||
// close all the channels
|
||||
r.close()
|
||||
// set the status error
|
||||
if err != nil {
|
||||
r.status.Error = err
|
||||
}
|
||||
|
||||
// mark the router as Stopped and set its Error to nil
|
||||
r.status = Status{Code: Stopped, Error: nil}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
r.status = Status{Code: Error, Error: err}
|
||||
}
|
||||
}
|
||||
|
||||
// Run runs the router.
|
||||
func (r *router) run() {
|
||||
// Start starts the router
|
||||
func (r *router) Start() error {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
switch r.status.Code {
|
||||
case Stopped, Error:
|
||||
// add all local service routes into the routing table
|
||||
if err := r.manageRegistryRoutes(r.opts.Registry, "create"); err != nil {
|
||||
r.status = Status{Code: Error, Error: fmt.Errorf("failed adding registry routes: %s", err)}
|
||||
return
|
||||
}
|
||||
|
||||
// add default gateway into routing table
|
||||
if r.opts.Gateway != "" {
|
||||
// note, the only non-default value is the gateway
|
||||
route := Route{
|
||||
Service: "*",
|
||||
Address: "*",
|
||||
Gateway: r.opts.Gateway,
|
||||
Network: "*",
|
||||
Metric: DefaultLocalMetric,
|
||||
}
|
||||
if err := r.table.Create(route); err != nil {
|
||||
r.status = Status{Code: Error, Error: fmt.Errorf("failed adding default gateway route: %s", err)}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// create error and exit channels
|
||||
r.errChan = make(chan error, 1)
|
||||
r.exit = make(chan struct{})
|
||||
|
||||
// registry watcher
|
||||
regWatcher, err := r.opts.Registry.Watch()
|
||||
if err != nil {
|
||||
r.status = Status{Code: Error, Error: fmt.Errorf("failed creating registry watcher: %v", err)}
|
||||
return
|
||||
}
|
||||
|
||||
r.wg.Add(1)
|
||||
go func() {
|
||||
defer r.wg.Done()
|
||||
select {
|
||||
case r.errChan <- r.watchRegistry(regWatcher):
|
||||
case <-r.exit:
|
||||
}
|
||||
}()
|
||||
|
||||
// watch for errors and cleanup
|
||||
r.wg.Add(1)
|
||||
go func() {
|
||||
defer r.wg.Done()
|
||||
r.watchErrors()
|
||||
}()
|
||||
|
||||
// mark router as Running and set its Error to nil
|
||||
r.status = Status{Code: Running, Error: nil}
|
||||
|
||||
return
|
||||
// only start if we're stopped
|
||||
if r.status.Code != Stopped {
|
||||
return nil
|
||||
}
|
||||
|
||||
return
|
||||
// add all local service routes into the routing table
|
||||
if err := r.manageRegistryRoutes(r.options.Registry, "create"); err != nil {
|
||||
e := fmt.Errorf("failed adding registry routes: %s", err)
|
||||
r.status = Status{Code: Error, Error: e}
|
||||
return e
|
||||
}
|
||||
|
||||
// add default gateway into routing table
|
||||
if r.options.Gateway != "" {
|
||||
// note, the only non-default value is the gateway
|
||||
route := Route{
|
||||
Service: "*",
|
||||
Address: "*",
|
||||
Gateway: r.options.Gateway,
|
||||
Network: "*",
|
||||
Router: r.options.Id,
|
||||
Link: DefaultLink,
|
||||
Metric: DefaultLocalMetric,
|
||||
}
|
||||
if err := r.table.Create(route); err != nil {
|
||||
e := fmt.Errorf("failed adding default gateway route: %s", err)
|
||||
r.status = Status{Code: Error, Error: e}
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
// create error and exit channels
|
||||
r.errChan = make(chan error, 1)
|
||||
r.exit = make(chan struct{})
|
||||
|
||||
// registry watcher
|
||||
regWatcher, err := r.options.Registry.Watch()
|
||||
if err != nil {
|
||||
e := fmt.Errorf("failed creating registry watcher: %v", err)
|
||||
r.status = Status{Code: Error, Error: e}
|
||||
return e
|
||||
}
|
||||
|
||||
r.wg.Add(1)
|
||||
go func() {
|
||||
defer r.wg.Done()
|
||||
select {
|
||||
case r.errChan <- r.watchRegistry(regWatcher):
|
||||
case <-r.exit:
|
||||
}
|
||||
}()
|
||||
|
||||
// watch for errors and cleanup
|
||||
r.wg.Add(1)
|
||||
go func() {
|
||||
defer r.wg.Done()
|
||||
r.watchErrors()
|
||||
}()
|
||||
|
||||
// mark router as Running
|
||||
r.status = Status{Code: Running, Error: nil}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Advertise stars advertising the routes to the network and returns the advertisements channel to consume from.
|
||||
@@ -540,24 +603,14 @@ func (r *router) Advertise() (<-chan *Advert, error) {
|
||||
|
||||
switch r.status.Code {
|
||||
case Advertising:
|
||||
advertChan := make(chan *Advert)
|
||||
advertChan := make(chan *Advert, 128)
|
||||
r.subscribers[uuid.New().String()] = advertChan
|
||||
return advertChan, nil
|
||||
case Running:
|
||||
// list routing table routes to announce
|
||||
routes, err := r.table.List()
|
||||
// list all the routes and pack them into even slice to advertise
|
||||
events, err := r.flushRouteEvents(Create)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed listing routes: %s", err)
|
||||
}
|
||||
// collect all the added routes before we attempt to add default gateway
|
||||
events := make([]*Event, len(routes))
|
||||
for i, route := range routes {
|
||||
event := &Event{
|
||||
Type: Create,
|
||||
Timestamp: time.Now(),
|
||||
Route: route,
|
||||
}
|
||||
events[i] = event
|
||||
return nil, fmt.Errorf("failed to flush routes: %s", err)
|
||||
}
|
||||
|
||||
// create event channels
|
||||
@@ -590,7 +643,7 @@ func (r *router) Advertise() (<-chan *Advert, error) {
|
||||
r.status = Status{Code: Advertising, Error: nil}
|
||||
|
||||
// create advert channel
|
||||
advertChan := make(chan *Advert)
|
||||
advertChan := make(chan *Advert, 128)
|
||||
r.subscribers[uuid.New().String()] = advertChan
|
||||
|
||||
return advertChan, nil
|
||||
@@ -613,6 +666,10 @@ func (r *router) Process(a *Advert) error {
|
||||
})
|
||||
|
||||
for _, event := range events {
|
||||
// skip if the router is the origin of this route
|
||||
if event.Route.Router == r.options.Id {
|
||||
continue
|
||||
}
|
||||
// create a copy of the route
|
||||
route := event.Route
|
||||
action := event.Type
|
||||
@@ -624,10 +681,49 @@ func (r *router) Process(a *Advert) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// flushRouteEvents returns a slice of events, one per each route in the routing table
|
||||
func (r *router) flushRouteEvents(evType EventType) ([]*Event, error) {
|
||||
// list all routes
|
||||
routes, err := r.table.List()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed listing routes: %s", err)
|
||||
}
|
||||
|
||||
// build a list of events to advertise
|
||||
events := make([]*Event, len(routes))
|
||||
for i, route := range routes {
|
||||
event := &Event{
|
||||
Type: evType,
|
||||
Timestamp: time.Now(),
|
||||
Route: route,
|
||||
}
|
||||
events[i] = event
|
||||
}
|
||||
|
||||
return events, nil
|
||||
}
|
||||
|
||||
// Solicit advertises all of its routes to the network
|
||||
// It returns error if the router fails to list the routes
|
||||
func (r *router) Solicit() error {
|
||||
events, err := r.flushRouteEvents(Update)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed solicit routes: %s", err)
|
||||
}
|
||||
|
||||
// advertise the routes
|
||||
r.advertWg.Add(1)
|
||||
go r.publishAdvert(RouteUpdate, events)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lookup routes in the routing table
|
||||
func (r *router) Lookup(q Query) ([]Route, error) {
|
||||
return r.table.Query(q)
|
||||
}
|
||||
|
||||
// Watch routes
|
||||
func (r *router) Watch(opts ...WatchOption) (Watcher, error) {
|
||||
return r.table.Watch(opts...)
|
||||
}
|
||||
@@ -646,31 +742,15 @@ func (r *router) Status() Status {
|
||||
// Stop stops the router
|
||||
func (r *router) Stop() error {
|
||||
r.Lock()
|
||||
// only close the channel if the router is running and/or advertising
|
||||
if r.status.Code == Running || r.status.Code == Advertising {
|
||||
// notify all goroutines to finish
|
||||
close(r.exit)
|
||||
defer r.Unlock()
|
||||
|
||||
// drain the advertise channel only if advertising
|
||||
if r.status.Code == Advertising {
|
||||
// drain the event channel
|
||||
for range r.eventChan {
|
||||
}
|
||||
}
|
||||
|
||||
// close advert subscribers
|
||||
for id, sub := range r.subscribers {
|
||||
// close the channel
|
||||
close(sub)
|
||||
|
||||
// delete the subscriber
|
||||
delete(r.subscribers, id)
|
||||
}
|
||||
|
||||
// mark the router as Stopped and set its Error to nil
|
||||
r.status = Status{Code: Stopped, Error: nil}
|
||||
switch r.status.Code {
|
||||
case Stopped, Error:
|
||||
return r.status.Error
|
||||
case Running, Advertising:
|
||||
// close all the channels
|
||||
r.close()
|
||||
}
|
||||
r.Unlock()
|
||||
|
||||
// wait for all goroutines to finish
|
||||
r.wg.Wait()
|
||||
@@ -680,5 +760,5 @@ func (r *router) Stop() error {
|
||||
|
||||
// String prints debugging information about router
|
||||
func (r *router) String() string {
|
||||
return "default"
|
||||
return "memory"
|
||||
}
|
184
router/handler/router.go
Normal file
184
router/handler/router.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/router"
|
||||
pb "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
// Router implements router handler
|
||||
type Router struct {
|
||||
Router router.Router
|
||||
}
|
||||
|
||||
// Lookup looks up routes in the routing table and returns them
|
||||
func (r *Router) Lookup(ctx context.Context, req *pb.LookupRequest, resp *pb.LookupResponse) error {
|
||||
query := router.NewQuery(
|
||||
router.QueryService(req.Query.Service),
|
||||
)
|
||||
|
||||
routes, err := r.Router.Lookup(query)
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to lookup routes: %v", err)
|
||||
}
|
||||
|
||||
var respRoutes []*pb.Route
|
||||
for _, route := range routes {
|
||||
respRoute := &pb.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int64(route.Metric),
|
||||
}
|
||||
respRoutes = append(respRoutes, respRoute)
|
||||
}
|
||||
|
||||
resp.Routes = respRoutes
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Router) Advertise(ctx context.Context, req *pb.Request, stream pb.Router_AdvertiseStream) error {
|
||||
advertChan, err := r.Router.Advertise()
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to get adverts: %v", err)
|
||||
}
|
||||
|
||||
for advert := range advertChan {
|
||||
var events []*pb.Event
|
||||
for _, event := range advert.Events {
|
||||
route := &pb.Route{
|
||||
Service: event.Route.Service,
|
||||
Address: event.Route.Address,
|
||||
Gateway: event.Route.Gateway,
|
||||
Network: event.Route.Network,
|
||||
Router: event.Route.Router,
|
||||
Link: event.Route.Link,
|
||||
Metric: int64(event.Route.Metric),
|
||||
}
|
||||
e := &pb.Event{
|
||||
Type: pb.EventType(event.Type),
|
||||
Timestamp: event.Timestamp.UnixNano(),
|
||||
Route: route,
|
||||
}
|
||||
events = append(events, e)
|
||||
}
|
||||
|
||||
advert := &pb.Advert{
|
||||
Id: advert.Id,
|
||||
Type: pb.AdvertType(advert.Type),
|
||||
Timestamp: advert.Timestamp.UnixNano(),
|
||||
Events: events,
|
||||
}
|
||||
|
||||
// send the advert
|
||||
err := stream.Send(advert)
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "error sending message %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Router) Process(ctx context.Context, req *pb.Advert, rsp *pb.ProcessResponse) error {
|
||||
events := make([]*router.Event, len(req.Events))
|
||||
for i, event := range req.Events {
|
||||
route := router.Route{
|
||||
Service: event.Route.Service,
|
||||
Address: event.Route.Address,
|
||||
Gateway: event.Route.Gateway,
|
||||
Network: event.Route.Network,
|
||||
Router: event.Route.Router,
|
||||
Link: event.Route.Link,
|
||||
Metric: int(event.Route.Metric),
|
||||
}
|
||||
|
||||
events[i] = &router.Event{
|
||||
Type: router.EventType(event.Type),
|
||||
Timestamp: time.Unix(0, event.Timestamp),
|
||||
Route: route,
|
||||
}
|
||||
}
|
||||
|
||||
advert := &router.Advert{
|
||||
Id: req.Id,
|
||||
Type: router.AdvertType(req.Type),
|
||||
Timestamp: time.Unix(0, req.Timestamp),
|
||||
TTL: time.Duration(req.Ttl),
|
||||
Events: events,
|
||||
}
|
||||
|
||||
if err := r.Router.Process(advert); err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "error publishing advert: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Router) Status(ctx context.Context, req *pb.Request, rsp *pb.StatusResponse) error {
|
||||
status := r.Router.Status()
|
||||
|
||||
rsp.Status = &pb.Status{
|
||||
Code: status.Code.String(),
|
||||
}
|
||||
|
||||
if status.Error != nil {
|
||||
rsp.Status.Error = status.Error.Error()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Watch streans routing table events
|
||||
func (r *Router) Watch(ctx context.Context, req *pb.WatchRequest, stream pb.Router_WatchStream) error {
|
||||
watcher, err := r.Router.Watch()
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed creating event watcher: %v", err)
|
||||
}
|
||||
|
||||
defer stream.Close()
|
||||
|
||||
for {
|
||||
event, err := watcher.Next()
|
||||
if err == router.ErrWatcherStopped {
|
||||
break
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "error watching events: %v", err)
|
||||
}
|
||||
|
||||
route := &pb.Route{
|
||||
Service: event.Route.Service,
|
||||
Address: event.Route.Address,
|
||||
Gateway: event.Route.Gateway,
|
||||
Network: event.Route.Network,
|
||||
Router: event.Route.Router,
|
||||
Link: event.Route.Link,
|
||||
Metric: int64(event.Route.Metric),
|
||||
}
|
||||
|
||||
tableEvent := &pb.Event{
|
||||
Type: pb.EventType(event.Type),
|
||||
Timestamp: event.Timestamp.UnixNano(),
|
||||
Route: route,
|
||||
}
|
||||
|
||||
if err := stream.Send(tableEvent); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
119
router/handler/table.go
Normal file
119
router/handler/table.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/go-micro/errors"
|
||||
"github.com/micro/go-micro/router"
|
||||
pb "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
type Table struct {
|
||||
Router router.Router
|
||||
}
|
||||
|
||||
func (t *Table) Create(ctx context.Context, route *pb.Route, resp *pb.CreateResponse) error {
|
||||
err := t.Router.Table().Create(router.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int(route.Metric),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to create route: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Table) Update(ctx context.Context, route *pb.Route, resp *pb.UpdateResponse) error {
|
||||
err := t.Router.Table().Update(router.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int(route.Metric),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to update route: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Table) Delete(ctx context.Context, route *pb.Route, resp *pb.DeleteResponse) error {
|
||||
err := t.Router.Table().Delete(router.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int(route.Metric),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to delete route: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List returns all routes in the routing table
|
||||
func (t *Table) List(ctx context.Context, req *pb.Request, resp *pb.ListResponse) error {
|
||||
routes, err := t.Router.Table().List()
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to list routes: %s", err)
|
||||
}
|
||||
|
||||
var respRoutes []*pb.Route
|
||||
for _, route := range routes {
|
||||
respRoute := &pb.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int64(route.Metric),
|
||||
}
|
||||
respRoutes = append(respRoutes, respRoute)
|
||||
}
|
||||
|
||||
resp.Routes = respRoutes
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Table) Query(ctx context.Context, req *pb.QueryRequest, resp *pb.QueryResponse) error {
|
||||
query := router.NewQuery(
|
||||
router.QueryService(req.Query.Service),
|
||||
)
|
||||
|
||||
routes, err := t.Router.Table().Query(query)
|
||||
if err != nil {
|
||||
return errors.InternalServerError("go.micro.router", "failed to lookup routes: %s", err)
|
||||
}
|
||||
|
||||
var respRoutes []*pb.Route
|
||||
for _, route := range routes {
|
||||
respRoute := &pb.Route{
|
||||
Service: route.Service,
|
||||
Address: route.Address,
|
||||
Gateway: route.Gateway,
|
||||
Network: route.Network,
|
||||
Router: route.Router,
|
||||
Link: route.Link,
|
||||
Metric: int64(route.Metric),
|
||||
}
|
||||
respRoutes = append(respRoutes, respRoute)
|
||||
}
|
||||
|
||||
resp.Routes = respRoutes
|
||||
|
||||
return nil
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||
// source: go-micro/network/router/proto/router.proto
|
||||
// source: micro/go-micro/router/proto/router.proto
|
||||
|
||||
package go_micro_router
|
||||
|
||||
@@ -36,7 +36,7 @@ var _ server.Option
|
||||
type RouterService interface {
|
||||
Lookup(ctx context.Context, in *LookupRequest, opts ...client.CallOption) (*LookupResponse, error)
|
||||
Watch(ctx context.Context, in *WatchRequest, opts ...client.CallOption) (Router_WatchService, error)
|
||||
Advertise(ctx context.Context, in *AdvertiseRequest, opts ...client.CallOption) (Router_AdvertiseService, error)
|
||||
Advertise(ctx context.Context, in *Request, opts ...client.CallOption) (Router_AdvertiseService, error)
|
||||
Process(ctx context.Context, in *Advert, opts ...client.CallOption) (*ProcessResponse, error)
|
||||
Status(ctx context.Context, in *Request, opts ...client.CallOption) (*StatusResponse, error)
|
||||
}
|
||||
@@ -113,8 +113,8 @@ func (x *routerServiceWatch) Recv() (*Event, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *routerService) Advertise(ctx context.Context, in *AdvertiseRequest, opts ...client.CallOption) (Router_AdvertiseService, error) {
|
||||
req := c.c.NewRequest(c.name, "Router.Advertise", &AdvertiseRequest{})
|
||||
func (c *routerService) Advertise(ctx context.Context, in *Request, opts ...client.CallOption) (Router_AdvertiseService, error) {
|
||||
req := c.c.NewRequest(c.name, "Router.Advertise", &Request{})
|
||||
stream, err := c.c.Stream(ctx, req, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -182,7 +182,7 @@ func (c *routerService) Status(ctx context.Context, in *Request, opts ...client.
|
||||
type RouterHandler interface {
|
||||
Lookup(context.Context, *LookupRequest, *LookupResponse) error
|
||||
Watch(context.Context, *WatchRequest, Router_WatchStream) error
|
||||
Advertise(context.Context, *AdvertiseRequest, Router_AdvertiseStream) error
|
||||
Advertise(context.Context, *Request, Router_AdvertiseStream) error
|
||||
Process(context.Context, *Advert, *ProcessResponse) error
|
||||
Status(context.Context, *Request, *StatusResponse) error
|
||||
}
|
||||
@@ -246,7 +246,7 @@ func (x *routerWatchStream) Send(m *Event) error {
|
||||
}
|
||||
|
||||
func (h *routerHandler) Advertise(ctx context.Context, stream server.Stream) error {
|
||||
m := new(AdvertiseRequest)
|
||||
m := new(Request)
|
||||
if err := stream.Recv(m); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -294,8 +294,8 @@ type TableService interface {
|
||||
Create(ctx context.Context, in *Route, opts ...client.CallOption) (*CreateResponse, error)
|
||||
Delete(ctx context.Context, in *Route, opts ...client.CallOption) (*DeleteResponse, error)
|
||||
Update(ctx context.Context, in *Route, opts ...client.CallOption) (*UpdateResponse, error)
|
||||
Query(ctx context.Context, in *QueryRequest, opts ...client.CallOption) (*QueryResponse, error)
|
||||
List(ctx context.Context, in *Request, opts ...client.CallOption) (*ListResponse, error)
|
||||
Query(ctx context.Context, in *QueryRequest, opts ...client.CallOption) (*QueryResponse, error)
|
||||
}
|
||||
|
||||
type tableService struct {
|
||||
@@ -346,9 +346,9 @@ func (c *tableService) Update(ctx context.Context, in *Route, opts ...client.Cal
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tableService) Query(ctx context.Context, in *QueryRequest, opts ...client.CallOption) (*QueryResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Table.Query", in)
|
||||
out := new(QueryResponse)
|
||||
func (c *tableService) List(ctx context.Context, in *Request, opts ...client.CallOption) (*ListResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Table.List", in)
|
||||
out := new(ListResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -356,9 +356,9 @@ func (c *tableService) Query(ctx context.Context, in *QueryRequest, opts ...clie
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tableService) List(ctx context.Context, in *Request, opts ...client.CallOption) (*ListResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Table.List", in)
|
||||
out := new(ListResponse)
|
||||
func (c *tableService) Query(ctx context.Context, in *QueryRequest, opts ...client.CallOption) (*QueryResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Table.Query", in)
|
||||
out := new(QueryResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -372,8 +372,8 @@ type TableHandler interface {
|
||||
Create(context.Context, *Route, *CreateResponse) error
|
||||
Delete(context.Context, *Route, *DeleteResponse) error
|
||||
Update(context.Context, *Route, *UpdateResponse) error
|
||||
Query(context.Context, *QueryRequest, *QueryResponse) error
|
||||
List(context.Context, *Request, *ListResponse) error
|
||||
Query(context.Context, *QueryRequest, *QueryResponse) error
|
||||
}
|
||||
|
||||
func RegisterTableHandler(s server.Server, hdlr TableHandler, opts ...server.HandlerOption) error {
|
||||
@@ -381,8 +381,8 @@ func RegisterTableHandler(s server.Server, hdlr TableHandler, opts ...server.Han
|
||||
Create(ctx context.Context, in *Route, out *CreateResponse) error
|
||||
Delete(ctx context.Context, in *Route, out *DeleteResponse) error
|
||||
Update(ctx context.Context, in *Route, out *UpdateResponse) error
|
||||
Query(ctx context.Context, in *QueryRequest, out *QueryResponse) error
|
||||
List(ctx context.Context, in *Request, out *ListResponse) error
|
||||
Query(ctx context.Context, in *QueryRequest, out *QueryResponse) error
|
||||
}
|
||||
type Table struct {
|
||||
table
|
||||
@@ -407,10 +407,10 @@ func (h *tableHandler) Update(ctx context.Context, in *Route, out *UpdateRespons
|
||||
return h.TableHandler.Update(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *tableHandler) Query(ctx context.Context, in *QueryRequest, out *QueryResponse) error {
|
||||
return h.TableHandler.Query(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *tableHandler) List(ctx context.Context, in *Request, out *ListResponse) error {
|
||||
return h.TableHandler.List(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *tableHandler) Query(ctx context.Context, in *QueryRequest, out *QueryResponse) error {
|
||||
return h.TableHandler.Query(ctx, in, out)
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: go-micro/network/router/proto/router.proto
|
||||
// source: micro/go-micro/router/proto/router.proto
|
||||
|
||||
package go_micro_router
|
||||
|
||||
@@ -45,7 +45,7 @@ func (x AdvertType) String() string {
|
||||
}
|
||||
|
||||
func (AdvertType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{0}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{0}
|
||||
}
|
||||
|
||||
// EventType defines the type of event
|
||||
@@ -74,7 +74,7 @@ func (x EventType) String() string {
|
||||
}
|
||||
|
||||
func (EventType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{1}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{1}
|
||||
}
|
||||
|
||||
// Empty request
|
||||
@@ -88,7 +88,7 @@ func (m *Request) Reset() { *m = Request{} }
|
||||
func (m *Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*Request) ProtoMessage() {}
|
||||
func (*Request) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{0}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{0}
|
||||
}
|
||||
|
||||
func (m *Request) XXX_Unmarshal(b []byte) error {
|
||||
@@ -121,7 +121,7 @@ func (m *ListResponse) Reset() { *m = ListResponse{} }
|
||||
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListResponse) ProtoMessage() {}
|
||||
func (*ListResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{1}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{1}
|
||||
}
|
||||
|
||||
func (m *ListResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -161,7 +161,7 @@ func (m *LookupRequest) Reset() { *m = LookupRequest{} }
|
||||
func (m *LookupRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*LookupRequest) ProtoMessage() {}
|
||||
func (*LookupRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{2}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{2}
|
||||
}
|
||||
|
||||
func (m *LookupRequest) XXX_Unmarshal(b []byte) error {
|
||||
@@ -201,7 +201,7 @@ func (m *LookupResponse) Reset() { *m = LookupResponse{} }
|
||||
func (m *LookupResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*LookupResponse) ProtoMessage() {}
|
||||
func (*LookupResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{3}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{3}
|
||||
}
|
||||
|
||||
func (m *LookupResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -240,7 +240,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} }
|
||||
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*QueryRequest) ProtoMessage() {}
|
||||
func (*QueryRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{4}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{4}
|
||||
}
|
||||
|
||||
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
|
||||
@@ -279,7 +279,7 @@ func (m *QueryResponse) Reset() { *m = QueryResponse{} }
|
||||
func (m *QueryResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*QueryResponse) ProtoMessage() {}
|
||||
func (*QueryResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{5}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{5}
|
||||
}
|
||||
|
||||
func (m *QueryResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -318,7 +318,7 @@ func (m *WatchRequest) Reset() { *m = WatchRequest{} }
|
||||
func (m *WatchRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*WatchRequest) ProtoMessage() {}
|
||||
func (*WatchRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{6}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{6}
|
||||
}
|
||||
|
||||
func (m *WatchRequest) XXX_Unmarshal(b []byte) error {
|
||||
@@ -339,38 +339,6 @@ func (m *WatchRequest) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_WatchRequest proto.InternalMessageInfo
|
||||
|
||||
// AdvertiseRequest request a stream of Adverts
|
||||
type AdvertiseRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AdvertiseRequest) Reset() { *m = AdvertiseRequest{} }
|
||||
func (m *AdvertiseRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*AdvertiseRequest) ProtoMessage() {}
|
||||
func (*AdvertiseRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{7}
|
||||
}
|
||||
|
||||
func (m *AdvertiseRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_AdvertiseRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *AdvertiseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_AdvertiseRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *AdvertiseRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_AdvertiseRequest.Merge(m, src)
|
||||
}
|
||||
func (m *AdvertiseRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_AdvertiseRequest.Size(m)
|
||||
}
|
||||
func (m *AdvertiseRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_AdvertiseRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_AdvertiseRequest proto.InternalMessageInfo
|
||||
|
||||
// Advert is router advertsement streamed by Watch
|
||||
type Advert struct {
|
||||
// id of the advertising router
|
||||
@@ -392,7 +360,7 @@ func (m *Advert) Reset() { *m = Advert{} }
|
||||
func (m *Advert) String() string { return proto.CompactTextString(m) }
|
||||
func (*Advert) ProtoMessage() {}
|
||||
func (*Advert) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{8}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{7}
|
||||
}
|
||||
|
||||
func (m *Advert) XXX_Unmarshal(b []byte) error {
|
||||
@@ -459,7 +427,7 @@ func (m *ProcessResponse) Reset() { *m = ProcessResponse{} }
|
||||
func (m *ProcessResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ProcessResponse) ProtoMessage() {}
|
||||
func (*ProcessResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{9}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{8}
|
||||
}
|
||||
|
||||
func (m *ProcessResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -491,7 +459,7 @@ func (m *CreateResponse) Reset() { *m = CreateResponse{} }
|
||||
func (m *CreateResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateResponse) ProtoMessage() {}
|
||||
func (*CreateResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{10}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{9}
|
||||
}
|
||||
|
||||
func (m *CreateResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -523,7 +491,7 @@ func (m *DeleteResponse) Reset() { *m = DeleteResponse{} }
|
||||
func (m *DeleteResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*DeleteResponse) ProtoMessage() {}
|
||||
func (*DeleteResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{11}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{10}
|
||||
}
|
||||
|
||||
func (m *DeleteResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -555,7 +523,7 @@ func (m *UpdateResponse) Reset() { *m = UpdateResponse{} }
|
||||
func (m *UpdateResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*UpdateResponse) ProtoMessage() {}
|
||||
func (*UpdateResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{12}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{11}
|
||||
}
|
||||
|
||||
func (m *UpdateResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -593,7 +561,7 @@ func (m *Event) Reset() { *m = Event{} }
|
||||
func (m *Event) String() string { return proto.CompactTextString(m) }
|
||||
func (*Event) ProtoMessage() {}
|
||||
func (*Event) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{13}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{12}
|
||||
}
|
||||
|
||||
func (m *Event) XXX_Unmarshal(b []byte) error {
|
||||
@@ -652,7 +620,7 @@ func (m *Query) Reset() { *m = Query{} }
|
||||
func (m *Query) String() string { return proto.CompactTextString(m) }
|
||||
func (*Query) ProtoMessage() {}
|
||||
func (*Query) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{14}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{13}
|
||||
}
|
||||
|
||||
func (m *Query) XXX_Unmarshal(b []byte) error {
|
||||
@@ -704,10 +672,12 @@ type Route struct {
|
||||
Gateway string `protobuf:"bytes,3,opt,name=gateway,proto3" json:"gateway,omitempty"`
|
||||
// the network for this destination
|
||||
Network string `protobuf:"bytes,4,opt,name=network,proto3" json:"network,omitempty"`
|
||||
// router if the router id
|
||||
Router string `protobuf:"bytes,5,opt,name=router,proto3" json:"router,omitempty"`
|
||||
// the network link
|
||||
Link string `protobuf:"bytes,5,opt,name=link,proto3" json:"link,omitempty"`
|
||||
Link string `protobuf:"bytes,6,opt,name=link,proto3" json:"link,omitempty"`
|
||||
// the metric / score of this route
|
||||
Metric int64 `protobuf:"varint,6,opt,name=metric,proto3" json:"metric,omitempty"`
|
||||
Metric int64 `protobuf:"varint,7,opt,name=metric,proto3" json:"metric,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -717,7 +687,7 @@ func (m *Route) Reset() { *m = Route{} }
|
||||
func (m *Route) String() string { return proto.CompactTextString(m) }
|
||||
func (*Route) ProtoMessage() {}
|
||||
func (*Route) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{15}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{14}
|
||||
}
|
||||
|
||||
func (m *Route) XXX_Unmarshal(b []byte) error {
|
||||
@@ -766,6 +736,13 @@ func (m *Route) GetNetwork() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Route) GetRouter() string {
|
||||
if m != nil {
|
||||
return m.Router
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Route) GetLink() string {
|
||||
if m != nil {
|
||||
return m.Link
|
||||
@@ -792,7 +769,7 @@ func (m *Status) Reset() { *m = Status{} }
|
||||
func (m *Status) String() string { return proto.CompactTextString(m) }
|
||||
func (*Status) ProtoMessage() {}
|
||||
func (*Status) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{16}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{15}
|
||||
}
|
||||
|
||||
func (m *Status) XXX_Unmarshal(b []byte) error {
|
||||
@@ -838,7 +815,7 @@ func (m *StatusResponse) Reset() { *m = StatusResponse{} }
|
||||
func (m *StatusResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatusResponse) ProtoMessage() {}
|
||||
func (*StatusResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fc08514fc6dadd29, []int{17}
|
||||
return fileDescriptor_6a36eee0b1adf739, []int{16}
|
||||
}
|
||||
|
||||
func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
|
||||
@@ -876,7 +853,6 @@ func init() {
|
||||
proto.RegisterType((*QueryRequest)(nil), "go.micro.router.QueryRequest")
|
||||
proto.RegisterType((*QueryResponse)(nil), "go.micro.router.QueryResponse")
|
||||
proto.RegisterType((*WatchRequest)(nil), "go.micro.router.WatchRequest")
|
||||
proto.RegisterType((*AdvertiseRequest)(nil), "go.micro.router.AdvertiseRequest")
|
||||
proto.RegisterType((*Advert)(nil), "go.micro.router.Advert")
|
||||
proto.RegisterType((*ProcessResponse)(nil), "go.micro.router.ProcessResponse")
|
||||
proto.RegisterType((*CreateResponse)(nil), "go.micro.router.CreateResponse")
|
||||
@@ -890,55 +866,55 @@ func init() {
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("go-micro/network/router/proto/router.proto", fileDescriptor_fc08514fc6dadd29)
|
||||
proto.RegisterFile("micro/go-micro/router/proto/router.proto", fileDescriptor_6a36eee0b1adf739)
|
||||
}
|
||||
|
||||
var fileDescriptor_fc08514fc6dadd29 = []byte{
|
||||
// 702 bytes of a gzipped FileDescriptorProto
|
||||
var fileDescriptor_6a36eee0b1adf739 = []byte{
|
||||
// 699 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xcd, 0x4e, 0xdb, 0x40,
|
||||
0x10, 0xb6, 0x93, 0xd8, 0xc8, 0xd3, 0x60, 0xdc, 0x51, 0x05, 0x56, 0x5a, 0x68, 0xea, 0x13, 0x42,
|
||||
0xd4, 0xa9, 0xd2, 0x6b, 0xff, 0x52, 0x4a, 0x55, 0x09, 0x0e, 0xad, 0x0b, 0xea, 0xd9, 0xd8, 0x2b,
|
||||
0x6a, 0x91, 0x78, 0xcd, 0xee, 0x06, 0x94, 0x73, 0x1f, 0xa3, 0x4f, 0xd0, 0xe7, 0xea, 0x33, 0xf4,
|
||||
0x5e, 0x79, 0x77, 0x1d, 0x92, 0x18, 0x23, 0xc1, 0xc9, 0x3b, 0x7f, 0xdf, 0xec, 0xcc, 0xce, 0x37,
|
||||
0x86, 0xbd, 0x73, 0xfa, 0x72, 0x92, 0x25, 0x8c, 0x0e, 0x72, 0x22, 0xae, 0x29, 0xbb, 0x18, 0x30,
|
||||
0x3a, 0x15, 0x84, 0x0d, 0x0a, 0x46, 0x05, 0xd5, 0x42, 0x28, 0x05, 0xdc, 0x38, 0xa7, 0xa1, 0xf4,
|
||||
0x0d, 0x95, 0x3a, 0x70, 0x60, 0x2d, 0x22, 0x97, 0x53, 0xc2, 0x45, 0xf0, 0x0e, 0xba, 0xc7, 0x19,
|
||||
0x17, 0x11, 0xe1, 0x05, 0xcd, 0x39, 0xc1, 0x10, 0x6c, 0xe9, 0xc4, 0x7d, 0xb3, 0xdf, 0xde, 0x7d,
|
||||
0x34, 0xdc, 0x0c, 0x57, 0x82, 0xc3, 0xa8, 0xfc, 0x44, 0xda, 0x2b, 0x78, 0x0b, 0xeb, 0xc7, 0x94,
|
||||
0x5e, 0x4c, 0x0b, 0x0d, 0x88, 0xfb, 0x60, 0x5d, 0x4e, 0x09, 0x9b, 0xf9, 0x66, 0xdf, 0xbc, 0x35,
|
||||
0xfe, 0x5b, 0x69, 0x8d, 0x94, 0x53, 0xf0, 0x01, 0xdc, 0x2a, 0xfc, 0x81, 0x17, 0x78, 0x03, 0x5d,
|
||||
0x85, 0xf8, 0xa0, 0xfc, 0xef, 0x61, 0x5d, 0x47, 0x3f, 0x30, 0xbd, 0x0b, 0xdd, 0x1f, 0xb1, 0x48,
|
||||
0x7e, 0x56, 0xfd, 0x44, 0xf0, 0x46, 0xe9, 0x15, 0x61, 0x22, 0xe3, 0xa4, 0xd2, 0xfd, 0x31, 0xc1,
|
||||
0x56, 0x4a, 0x74, 0xa1, 0x95, 0xa5, 0xf2, 0x6a, 0x4e, 0xd4, 0xca, 0x52, 0x1c, 0x40, 0x47, 0xcc,
|
||||
0x0a, 0xe2, 0xb7, 0xfa, 0xe6, 0xae, 0x3b, 0x7c, 0x5a, 0x4b, 0xa6, 0xc2, 0x4e, 0x66, 0x05, 0x89,
|
||||
0xa4, 0x23, 0x3e, 0x03, 0x47, 0x64, 0x13, 0xc2, 0x45, 0x3c, 0x29, 0xfc, 0x76, 0xdf, 0xdc, 0x6d,
|
||||
0x47, 0x37, 0x0a, 0xf4, 0xa0, 0x2d, 0xc4, 0xd8, 0xef, 0x48, 0x7d, 0x79, 0x2c, 0xeb, 0x21, 0x57,
|
||||
0x24, 0x17, 0xdc, 0xb7, 0x1a, 0xea, 0x39, 0x2c, 0xcd, 0x91, 0xf6, 0x0a, 0x1e, 0xc3, 0xc6, 0x57,
|
||||
0x46, 0x13, 0xc2, 0x79, 0xd5, 0x92, 0xc0, 0x03, 0xf7, 0x80, 0x91, 0x58, 0x90, 0x45, 0xcd, 0x27,
|
||||
0x32, 0x26, 0xcb, 0x9a, 0xd3, 0x22, 0x5d, 0xf4, 0xf9, 0x65, 0x82, 0x25, 0xa1, 0x31, 0xd4, 0x35,
|
||||
0x9a, 0xb2, 0xc6, 0xde, 0xed, 0x17, 0x68, 0x2a, 0xb1, 0xb5, 0x5a, 0xe2, 0x3e, 0x58, 0x32, 0x4e,
|
||||
0x16, 0xdf, 0xfc, 0x3e, 0xca, 0x29, 0x38, 0x05, 0x4b, 0xbe, 0x2f, 0xfa, 0xb0, 0xc6, 0x09, 0xbb,
|
||||
0xca, 0x12, 0xa2, 0xbb, 0x5f, 0x89, 0xa5, 0xe5, 0x3c, 0x16, 0xe4, 0x3a, 0x9e, 0xc9, 0x64, 0x4e,
|
||||
0x54, 0x89, 0xa5, 0x45, 0x93, 0x4b, 0x26, 0x73, 0xa2, 0x4a, 0x0c, 0x7e, 0x9b, 0x60, 0xc9, 0x3c,
|
||||
0x77, 0xe3, 0xc6, 0x69, 0xca, 0x08, 0xe7, 0x15, 0xae, 0x16, 0x17, 0x33, 0xb6, 0x1b, 0x33, 0x76,
|
||||
0x96, 0x32, 0x22, 0x42, 0x67, 0x9c, 0xe5, 0x17, 0xbe, 0x25, 0xd5, 0xf2, 0x8c, 0x9b, 0x60, 0x4f,
|
||||
0x88, 0x60, 0x59, 0xe2, 0xdb, 0xb2, 0x4b, 0x5a, 0x0a, 0x86, 0x60, 0x7f, 0x17, 0xb1, 0x98, 0xf2,
|
||||
0x32, 0x2a, 0xa1, 0x69, 0x75, 0x35, 0x79, 0xc6, 0x27, 0x60, 0x11, 0xc6, 0x28, 0xd3, 0xb7, 0x52,
|
||||
0x42, 0x30, 0x02, 0x57, 0xc5, 0xcc, 0x99, 0x30, 0x00, 0x9b, 0x4b, 0x8d, 0x66, 0xd2, 0x56, 0xad,
|
||||
0xd3, 0x3a, 0x40, 0xbb, 0xed, 0x0d, 0x01, 0x6e, 0xc6, 0x15, 0x11, 0x5c, 0x25, 0x8d, 0xf2, 0x9c,
|
||||
0x4e, 0xf3, 0x84, 0x78, 0x06, 0x7a, 0xd0, 0x55, 0x3a, 0x35, 0x2b, 0x9e, 0xb9, 0x37, 0x00, 0x67,
|
||||
0xfe, 0xfc, 0x08, 0x60, 0xab, 0x41, 0xf3, 0x8c, 0xf2, 0xac, 0x46, 0xcc, 0x33, 0xcb, 0xb3, 0x0e,
|
||||
0x68, 0x0d, 0xff, 0xb5, 0xc0, 0x96, 0x9d, 0x67, 0x78, 0x04, 0xb6, 0xda, 0x1d, 0xb8, 0x53, 0xbb,
|
||||
0xda, 0xd2, 0x4e, 0xea, 0x3d, 0x6f, 0xb4, 0xeb, 0x61, 0x35, 0xf0, 0x23, 0x58, 0x92, 0xc7, 0xb8,
|
||||
0x5d, 0xf3, 0x5d, 0xe4, 0x77, 0xaf, 0x81, 0x3f, 0x81, 0xf1, 0xca, 0xc4, 0x23, 0x70, 0xe6, 0xdc,
|
||||
0xc7, 0x17, 0x0d, 0x5c, 0xbe, 0xd9, 0x0b, 0xbd, 0xad, 0x06, 0x17, 0x09, 0xf6, 0x19, 0xd6, 0x34,
|
||||
0x11, 0xb1, 0xc9, 0xaf, 0xd7, 0xaf, 0x19, 0x56, 0xb9, 0x6b, 0xe0, 0xe1, 0x7c, 0x18, 0xfc, 0x3a,
|
||||
0x55, 0x1a, 0xfb, 0xb3, 0x3c, 0x0b, 0x81, 0x31, 0xfc, 0xdb, 0x02, 0xeb, 0x24, 0x3e, 0x1b, 0x13,
|
||||
0x3c, 0xa8, 0x5e, 0x09, 0x1b, 0xb8, 0x77, 0x0b, 0xdc, 0xca, 0xfe, 0x30, 0x4a, 0x10, 0xf5, 0xbc,
|
||||
0xf7, 0x00, 0x59, 0x59, 0x39, 0x12, 0x44, 0xcd, 0xc5, 0x3d, 0x40, 0x56, 0xb6, 0x94, 0x81, 0x5f,
|
||||
0xaa, 0x0d, 0xb1, 0xdd, 0xf0, 0xa7, 0xd0, 0x3d, 0xda, 0x69, 0x32, 0xcf, 0x91, 0x46, 0xd0, 0x29,
|
||||
0x7f, 0xa5, 0x77, 0xf4, 0xb9, 0x9e, 0x62, 0xf1, 0xdf, 0x1b, 0x18, 0x67, 0xb6, 0xfc, 0x61, 0xbf,
|
||||
0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xfc, 0x65, 0xca, 0xde, 0x07, 0x00, 0x00,
|
||||
0x10, 0xb6, 0x9d, 0xd8, 0x91, 0xa7, 0xc1, 0xb8, 0xa3, 0x0a, 0xac, 0xb4, 0x40, 0xe4, 0x53, 0x84,
|
||||
0xa8, 0x53, 0xa5, 0xd7, 0xfe, 0x05, 0x4a, 0x55, 0xa9, 0x1c, 0x5a, 0x17, 0xd4, 0xb3, 0xb1, 0x57,
|
||||
0xd4, 0x22, 0xb1, 0xcd, 0xee, 0x06, 0x94, 0x73, 0x9f, 0xa6, 0xe7, 0x3e, 0x52, 0xaf, 0x7d, 0x88,
|
||||
0xca, 0xbb, 0xeb, 0x10, 0x62, 0x8c, 0x44, 0x4e, 0xde, 0x99, 0xf9, 0xe6, 0x9b, 0x99, 0xdd, 0x99,
|
||||
0x31, 0x0c, 0xa6, 0x69, 0x4c, 0xf3, 0xe1, 0x45, 0xfe, 0x52, 0x1e, 0x68, 0x3e, 0xe3, 0x84, 0x0e,
|
||||
0x0b, 0x9a, 0xf3, 0x4a, 0x08, 0x84, 0x80, 0x9b, 0x17, 0x79, 0x20, 0x30, 0x81, 0x54, 0xfb, 0x36,
|
||||
0x74, 0x42, 0x72, 0x35, 0x23, 0x8c, 0xfb, 0xef, 0xa0, 0x7b, 0x92, 0x32, 0x1e, 0x12, 0x56, 0xe4,
|
||||
0x19, 0x23, 0x18, 0x80, 0x25, 0x40, 0xcc, 0xd3, 0xfb, 0xad, 0xc1, 0x93, 0xd1, 0x56, 0xb0, 0xe2,
|
||||
0x1c, 0x84, 0xe5, 0x27, 0x54, 0x28, 0xff, 0x2d, 0x6c, 0x9c, 0xe4, 0xf9, 0xe5, 0xac, 0x50, 0x84,
|
||||
0x78, 0x00, 0xe6, 0xd5, 0x8c, 0xd0, 0xb9, 0xa7, 0xf7, 0xf5, 0x7b, 0xfd, 0xbf, 0x95, 0xd6, 0x50,
|
||||
0x82, 0xfc, 0x0f, 0xe0, 0x54, 0xee, 0x6b, 0x26, 0xf0, 0x06, 0xba, 0x92, 0x71, 0xad, 0xf8, 0xef,
|
||||
0x61, 0x43, 0x79, 0xaf, 0x19, 0xde, 0x81, 0xee, 0x8f, 0x88, 0xc7, 0x3f, 0xab, 0xfb, 0xfc, 0xad,
|
||||
0x83, 0x35, 0x4e, 0xae, 0x09, 0xe5, 0xe8, 0x80, 0x91, 0x26, 0x22, 0x0d, 0x3b, 0x34, 0xd2, 0x04,
|
||||
0x87, 0xd0, 0xe6, 0xf3, 0x82, 0x78, 0x46, 0x5f, 0x1f, 0x38, 0xa3, 0xe7, 0x35, 0x62, 0xe9, 0x76,
|
||||
0x3a, 0x2f, 0x48, 0x28, 0x80, 0xf8, 0x02, 0x6c, 0x9e, 0x4e, 0x09, 0xe3, 0xd1, 0xb4, 0xf0, 0x5a,
|
||||
0x7d, 0x7d, 0xd0, 0x0a, 0x6f, 0x15, 0xe8, 0x42, 0x8b, 0xf3, 0x89, 0xd7, 0x16, 0xfa, 0xf2, 0x58,
|
||||
0xe6, 0x4e, 0xae, 0x49, 0xc6, 0x99, 0x67, 0x36, 0xe4, 0x7e, 0x5c, 0x9a, 0x43, 0x85, 0xf2, 0x9f,
|
||||
0xc2, 0xe6, 0x57, 0x9a, 0xc7, 0x84, 0xb1, 0xaa, 0x7c, 0xdf, 0x05, 0xe7, 0x88, 0x92, 0x88, 0x93,
|
||||
0x65, 0xcd, 0x47, 0x32, 0x21, 0x77, 0x35, 0x67, 0x45, 0xb2, 0x8c, 0xf9, 0xa5, 0x83, 0x29, 0xa8,
|
||||
0x31, 0x50, 0x35, 0xea, 0xa2, 0xc6, 0xde, 0xfd, 0x09, 0x34, 0x95, 0x68, 0xac, 0x96, 0x78, 0x00,
|
||||
0xa6, 0xf0, 0x13, 0xc5, 0x37, 0xbf, 0x85, 0x04, 0xf9, 0x67, 0x60, 0x8a, 0xb7, 0x44, 0x0f, 0x3a,
|
||||
0x8c, 0xd0, 0xeb, 0x34, 0x26, 0xea, 0xf6, 0x2b, 0xb1, 0xb4, 0x5c, 0x44, 0x9c, 0xdc, 0x44, 0x73,
|
||||
0x11, 0xcc, 0x0e, 0x2b, 0xb1, 0xb4, 0x64, 0x84, 0xdf, 0xe4, 0xf4, 0x52, 0x04, 0xb3, 0xc3, 0x4a,
|
||||
0xf4, 0xff, 0xe8, 0x60, 0x8a, 0x38, 0x0f, 0xf3, 0x46, 0x49, 0x42, 0x09, 0x63, 0x15, 0xaf, 0x12,
|
||||
0x97, 0x23, 0xb6, 0x1a, 0x23, 0xb6, 0xef, 0x44, 0xc4, 0x2d, 0xd5, 0x83, 0xd4, 0x33, 0x85, 0x41,
|
||||
0x49, 0x88, 0xd0, 0x9e, 0xa4, 0xd9, 0xa5, 0x67, 0x09, 0xad, 0x38, 0x97, 0xd8, 0x29, 0xe1, 0x34,
|
||||
0x8d, 0xbd, 0x8e, 0xb8, 0x3d, 0x25, 0xf9, 0x23, 0xb0, 0xbe, 0xf3, 0x88, 0xcf, 0x58, 0xe9, 0x15,
|
||||
0xe7, 0x49, 0x95, 0xb2, 0x38, 0xe3, 0x33, 0x30, 0x09, 0xa5, 0x39, 0x55, 0xd9, 0x4a, 0xc1, 0x1f,
|
||||
0x83, 0x23, 0x7d, 0x16, 0xd3, 0x30, 0x04, 0x8b, 0x09, 0x8d, 0x9a, 0xa6, 0xed, 0xda, 0x0b, 0x28,
|
||||
0x07, 0x05, 0xdb, 0x1f, 0x01, 0xdc, 0xb6, 0x31, 0x22, 0x38, 0x52, 0x1a, 0x67, 0x59, 0x3e, 0xcb,
|
||||
0x62, 0xe2, 0x6a, 0xe8, 0x42, 0x57, 0xea, 0x64, 0x0f, 0xb9, 0xfa, 0xfe, 0x10, 0xec, 0x45, 0x5b,
|
||||
0x20, 0x80, 0x25, 0x1b, 0xd0, 0xd5, 0xca, 0xb3, 0x6c, 0x3d, 0x57, 0x2f, 0xcf, 0xca, 0xc1, 0x18,
|
||||
0xfd, 0x33, 0xc0, 0x0a, 0xe5, 0x95, 0x7c, 0x01, 0x4b, 0xee, 0x0f, 0xdc, 0xad, 0xa5, 0x76, 0x67,
|
||||
0x2f, 0xf5, 0xf6, 0x1a, 0xed, 0xaa, 0x89, 0x35, 0x3c, 0x04, 0x53, 0xcc, 0x32, 0xee, 0xd4, 0xb0,
|
||||
0xcb, 0x33, 0xde, 0x6b, 0x98, 0x2b, 0x5f, 0x7b, 0xa5, 0xe3, 0x21, 0xd8, 0xb2, 0xbc, 0x94, 0x11,
|
||||
0xf4, 0xea, 0x0d, 0xab, 0x28, 0xb6, 0x1b, 0xa6, 0x5f, 0x70, 0x7c, 0x82, 0x8e, 0x9a, 0x4b, 0x6c,
|
||||
0xc2, 0xf5, 0xfa, 0x35, 0xc3, 0xea, 0x28, 0x6b, 0x78, 0xbc, 0xe8, 0x81, 0xe6, 0x44, 0xf6, 0x9a,
|
||||
0x5e, 0x74, 0x41, 0x33, 0xfa, 0x6b, 0x80, 0x79, 0x1a, 0x9d, 0x4f, 0x08, 0x1e, 0x55, 0x8f, 0x83,
|
||||
0x0d, 0xa3, 0x78, 0x0f, 0xdd, 0xca, 0x3a, 0xd1, 0x4a, 0x12, 0xf9, 0xaa, 0x8f, 0x20, 0x59, 0xd9,
|
||||
0x40, 0x82, 0x44, 0xb6, 0xc3, 0x23, 0x48, 0x56, 0x96, 0x96, 0x86, 0x63, 0x68, 0x97, 0xff, 0xbe,
|
||||
0x07, 0x6e, 0xa7, 0xde, 0x08, 0xcb, 0x3f, 0x4b, 0x5f, 0xc3, 0xcf, 0xd5, 0xce, 0xd9, 0x69, 0xf8,
|
||||
0xcf, 0x28, 0xa2, 0xdd, 0x26, 0x73, 0xc5, 0x74, 0x6e, 0x89, 0x7f, 0xf5, 0xeb, 0xff, 0x01, 0x00,
|
||||
0x00, 0xff, 0xff, 0xe2, 0xe9, 0xe2, 0x3b, 0xd7, 0x07, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -955,7 +931,7 @@ const _ = grpc.SupportPackageIsVersion4
|
||||
type RouterClient interface {
|
||||
Lookup(ctx context.Context, in *LookupRequest, opts ...grpc.CallOption) (*LookupResponse, error)
|
||||
Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (Router_WatchClient, error)
|
||||
Advertise(ctx context.Context, in *AdvertiseRequest, opts ...grpc.CallOption) (Router_AdvertiseClient, error)
|
||||
Advertise(ctx context.Context, in *Request, opts ...grpc.CallOption) (Router_AdvertiseClient, error)
|
||||
Process(ctx context.Context, in *Advert, opts ...grpc.CallOption) (*ProcessResponse, error)
|
||||
Status(ctx context.Context, in *Request, opts ...grpc.CallOption) (*StatusResponse, error)
|
||||
}
|
||||
@@ -1009,7 +985,7 @@ func (x *routerWatchClient) Recv() (*Event, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *routerClient) Advertise(ctx context.Context, in *AdvertiseRequest, opts ...grpc.CallOption) (Router_AdvertiseClient, error) {
|
||||
func (c *routerClient) Advertise(ctx context.Context, in *Request, opts ...grpc.CallOption) (Router_AdvertiseClient, error) {
|
||||
stream, err := c.cc.NewStream(ctx, &_Router_serviceDesc.Streams[1], "/go.micro.router.Router/Advertise", opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1063,7 +1039,7 @@ func (c *routerClient) Status(ctx context.Context, in *Request, opts ...grpc.Cal
|
||||
type RouterServer interface {
|
||||
Lookup(context.Context, *LookupRequest) (*LookupResponse, error)
|
||||
Watch(*WatchRequest, Router_WatchServer) error
|
||||
Advertise(*AdvertiseRequest, Router_AdvertiseServer) error
|
||||
Advertise(*Request, Router_AdvertiseServer) error
|
||||
Process(context.Context, *Advert) (*ProcessResponse, error)
|
||||
Status(context.Context, *Request) (*StatusResponse, error)
|
||||
}
|
||||
@@ -1112,7 +1088,7 @@ func (x *routerWatchServer) Send(m *Event) error {
|
||||
}
|
||||
|
||||
func _Router_Advertise_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(AdvertiseRequest)
|
||||
m := new(Request)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1197,7 +1173,7 @@ var _Router_serviceDesc = grpc.ServiceDesc{
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
Metadata: "go-micro/network/router/proto/router.proto",
|
||||
Metadata: "micro/go-micro/router/proto/router.proto",
|
||||
}
|
||||
|
||||
// TableClient is the client API for Table service.
|
||||
@@ -1207,8 +1183,8 @@ type TableClient interface {
|
||||
Create(ctx context.Context, in *Route, opts ...grpc.CallOption) (*CreateResponse, error)
|
||||
Delete(ctx context.Context, in *Route, opts ...grpc.CallOption) (*DeleteResponse, error)
|
||||
Update(ctx context.Context, in *Route, opts ...grpc.CallOption) (*UpdateResponse, error)
|
||||
Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryResponse, error)
|
||||
List(ctx context.Context, in *Request, opts ...grpc.CallOption) (*ListResponse, error)
|
||||
Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryResponse, error)
|
||||
}
|
||||
|
||||
type tableClient struct {
|
||||
@@ -1246,18 +1222,18 @@ func (c *tableClient) Update(ctx context.Context, in *Route, opts ...grpc.CallOp
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tableClient) Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryResponse, error) {
|
||||
out := new(QueryResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.router.Table/Query", in, out, opts...)
|
||||
func (c *tableClient) List(ctx context.Context, in *Request, opts ...grpc.CallOption) (*ListResponse, error) {
|
||||
out := new(ListResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.router.Table/List", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *tableClient) List(ctx context.Context, in *Request, opts ...grpc.CallOption) (*ListResponse, error) {
|
||||
out := new(ListResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.router.Table/List", in, out, opts...)
|
||||
func (c *tableClient) Query(ctx context.Context, in *QueryRequest, opts ...grpc.CallOption) (*QueryResponse, error) {
|
||||
out := new(QueryResponse)
|
||||
err := c.cc.Invoke(ctx, "/go.micro.router.Table/Query", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1269,8 +1245,8 @@ type TableServer interface {
|
||||
Create(context.Context, *Route) (*CreateResponse, error)
|
||||
Delete(context.Context, *Route) (*DeleteResponse, error)
|
||||
Update(context.Context, *Route) (*UpdateResponse, error)
|
||||
Query(context.Context, *QueryRequest) (*QueryResponse, error)
|
||||
List(context.Context, *Request) (*ListResponse, error)
|
||||
Query(context.Context, *QueryRequest) (*QueryResponse, error)
|
||||
}
|
||||
|
||||
func RegisterTableServer(s *grpc.Server, srv TableServer) {
|
||||
@@ -1331,24 +1307,6 @@ func _Table_Update_Handler(srv interface{}, ctx context.Context, dec func(interf
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Table_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(QueryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TableServer).Query(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.router.Table/Query",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TableServer).Query(ctx, req.(*QueryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Table_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Request)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -1367,6 +1325,24 @@ func _Table_List_Handler(srv interface{}, ctx context.Context, dec func(interfac
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Table_Query_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(QueryRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(TableServer).Query(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/go.micro.router.Table/Query",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(TableServer).Query(ctx, req.(*QueryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Table_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "go.micro.router.Table",
|
||||
HandlerType: (*TableServer)(nil),
|
||||
@@ -1383,15 +1359,15 @@ var _Table_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Update",
|
||||
Handler: _Table_Update_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Query",
|
||||
Handler: _Table_Query_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "List",
|
||||
Handler: _Table_List_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Query",
|
||||
Handler: _Table_Query_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "go-micro/network/router/proto/router.proto",
|
||||
Metadata: "micro/go-micro/router/proto/router.proto",
|
||||
}
|
@@ -7,11 +7,12 @@ service Router {
|
||||
rpc Lookup(LookupRequest) returns (LookupResponse) {};
|
||||
rpc Watch(WatchRequest) returns (stream Event) {};
|
||||
rpc Advertise(Request) returns (stream Advert) {};
|
||||
rpc Solicit(Request) returns (Response) {};
|
||||
rpc Process(Advert) returns (ProcessResponse) {};
|
||||
rpc Status(Request) returns (StatusResponse) {};
|
||||
}
|
||||
|
||||
service Table {
|
||||
service Table {
|
||||
rpc Create(Route) returns (CreateResponse) {};
|
||||
rpc Delete(Route) returns (DeleteResponse) {};
|
||||
rpc Update(Route) returns (UpdateResponse) {};
|
||||
@@ -22,6 +23,9 @@ service Table {
|
||||
// Empty request
|
||||
message Request {}
|
||||
|
||||
// Empty response
|
||||
message Response {}
|
||||
|
||||
// ListResponse is returned by List
|
||||
message ListResponse {
|
||||
repeated Route routes = 1;
|
||||
@@ -37,10 +41,12 @@ message LookupResponse {
|
||||
repeated Route routes = 1;
|
||||
}
|
||||
|
||||
// QueryRequest queries Table for Routes
|
||||
message QueryRequest{
|
||||
Query query = 1;
|
||||
}
|
||||
|
||||
// QueryResponse is returned by Query
|
||||
message QueryResponse {
|
||||
repeated Route routes = 1;
|
||||
}
|
||||
@@ -117,10 +123,12 @@ message Route {
|
||||
string gateway = 3;
|
||||
// the network for this destination
|
||||
string network = 4;
|
||||
// router if the router id
|
||||
string router = 5;
|
||||
// the network link
|
||||
string link = 5;
|
||||
string link = 6;
|
||||
// the metric / score of this route
|
||||
int64 metric = 6;
|
||||
int64 metric = 7;
|
||||
}
|
||||
|
||||
message Status {
|
@@ -11,29 +11,38 @@ type QueryOptions struct {
|
||||
Gateway string
|
||||
// Network is network address
|
||||
Network string
|
||||
// Router is router id
|
||||
Router string
|
||||
}
|
||||
|
||||
// QueryService sets destination address
|
||||
// QueryService sets service to query
|
||||
func QueryService(s string) QueryOption {
|
||||
return func(o *QueryOptions) {
|
||||
o.Service = s
|
||||
}
|
||||
}
|
||||
|
||||
// QueryGateway sets route gateway
|
||||
// QueryGateway sets gateway address to query
|
||||
func QueryGateway(g string) QueryOption {
|
||||
return func(o *QueryOptions) {
|
||||
o.Gateway = g
|
||||
}
|
||||
}
|
||||
|
||||
// QueryNetwork sets route network address
|
||||
// QueryNetwork sets network name to query
|
||||
func QueryNetwork(n string) QueryOption {
|
||||
return func(o *QueryOptions) {
|
||||
o.Network = n
|
||||
}
|
||||
}
|
||||
|
||||
// QueryRouter sets router id to query
|
||||
func QueryRouter(r string) QueryOption {
|
||||
return func(o *QueryOptions) {
|
||||
o.Router = r
|
||||
}
|
||||
}
|
||||
|
||||
// Query is routing table query
|
||||
type Query interface {
|
||||
// Options returns query options
|
||||
@@ -52,6 +61,7 @@ func NewQuery(opts ...QueryOption) Query {
|
||||
Service: "*",
|
||||
Gateway: "*",
|
||||
Network: "*",
|
||||
Router: "*",
|
||||
}
|
||||
|
||||
for _, o := range opts {
|
||||
@@ -67,8 +77,3 @@ func NewQuery(opts ...QueryOption) Query {
|
||||
func (q *query) Options() QueryOptions {
|
||||
return q.opts
|
||||
}
|
||||
|
||||
// String prints routing table query in human readable form
|
||||
func (q query) String() string {
|
||||
return "query"
|
||||
}
|
@@ -7,9 +7,9 @@ import (
|
||||
var (
|
||||
// DefaultLink is default network link
|
||||
DefaultLink = "local"
|
||||
// DefaultLocalMetric is default route cost metric for the local network
|
||||
// DefaultLocalMetric is default route cost for a local route
|
||||
DefaultLocalMetric = 1
|
||||
// DefaultNetworkMetric is default route cost metric for the micro network
|
||||
// DefaultNetworkMetric is default route cost for a network route
|
||||
DefaultNetworkMetric = 10
|
||||
)
|
||||
|
||||
@@ -23,6 +23,8 @@ type Route struct {
|
||||
Gateway string
|
||||
// Network is network address
|
||||
Network string
|
||||
// Router is router id
|
||||
Router string
|
||||
// Link is network link
|
||||
Link string
|
||||
// Metric is the route cost metric
|
||||
@@ -33,6 +35,6 @@ type Route struct {
|
||||
func (r *Route) Hash() uint64 {
|
||||
h := fnv.New64()
|
||||
h.Reset()
|
||||
h.Write([]byte(r.Service + r.Address + r.Gateway + r.Network + r.Link))
|
||||
h.Write([]byte(r.Service + r.Address + r.Gateway + r.Network + r.Router + r.Link))
|
||||
return h.Sum64()
|
||||
}
|
@@ -5,6 +5,17 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultAddress is default router address
|
||||
DefaultAddress = ":9093"
|
||||
// DefaultName is default router service name
|
||||
DefaultName = "go.micro.router"
|
||||
// DefaultNetwork is default micro network
|
||||
DefaultNetwork = "go.micro"
|
||||
// DefaultRouter is default network router
|
||||
DefaultRouter = NewRouter()
|
||||
)
|
||||
|
||||
// Router is an interface for a routing control plane
|
||||
type Router interface {
|
||||
// Init initializes the router with options
|
||||
@@ -17,10 +28,14 @@ type Router interface {
|
||||
Advertise() (<-chan *Advert, error)
|
||||
// Process processes incoming adverts
|
||||
Process(*Advert) error
|
||||
// Solicit advertises the whole routing table to the network
|
||||
Solicit() error
|
||||
// Lookup queries routes in the routing table
|
||||
Lookup(Query) ([]Route, error)
|
||||
// Watch returns a watcher which tracks updates to the routing table
|
||||
Watch(opts ...WatchOption) (Watcher, error)
|
||||
// Start starts the router
|
||||
Start() error
|
||||
// Status returns router status
|
||||
Status() Status
|
||||
// Stop stops the router
|
||||
@@ -29,16 +44,17 @@ type Router interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// Table is an interface for routing table
|
||||
type Table interface {
|
||||
// Create new route in the routing table
|
||||
Create(Route) error
|
||||
// Delete deletes existing route from the routing table
|
||||
// Delete existing route from the routing table
|
||||
Delete(Route) error
|
||||
// Update updates route in the routing table
|
||||
// Update route in the routing table
|
||||
Update(Route) error
|
||||
// List returns the list of all routes in the table
|
||||
// List all routes in the table
|
||||
List() ([]Route, error)
|
||||
// Query queries routes in the routing table
|
||||
// Query routes in the routing table
|
||||
Query(Query) ([]Route, error)
|
||||
}
|
||||
|
||||
@@ -76,10 +92,15 @@ func (s StatusCode) String() string {
|
||||
|
||||
// Status is router status
|
||||
type Status struct {
|
||||
// Error is router error
|
||||
Error error
|
||||
// Code defines router status
|
||||
Code StatusCode
|
||||
// Error contains error description
|
||||
Error error
|
||||
}
|
||||
|
||||
// String returns human readable status
|
||||
func (s Status) String() string {
|
||||
return s.Code.String()
|
||||
}
|
||||
|
||||
// AdvertType is route advertisement type
|
||||
@@ -118,17 +139,6 @@ type Advert struct {
|
||||
Events []*Event
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultAddress is default router address
|
||||
DefaultAddress = ":9093"
|
||||
// DefaultName is default router service name
|
||||
DefaultName = "go.micro.router"
|
||||
// DefaultNetwork is default micro network
|
||||
DefaultNetwork = "go.micro"
|
||||
// DefaultRouter is default network router
|
||||
DefaultRouter = NewRouter()
|
||||
)
|
||||
|
||||
// NewRouter creates new Router and returns it
|
||||
func NewRouter(opts ...Option) Router {
|
||||
return newRouter(opts...)
|
@@ -9,8 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/network/router"
|
||||
pb "github.com/micro/go-micro/network/router/proto"
|
||||
"github.com/micro/go-micro/router"
|
||||
pb "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
type svc struct {
|
||||
@@ -43,9 +43,16 @@ func NewRouter(opts ...router.Option) router.Router {
|
||||
cli = options.Client
|
||||
}
|
||||
|
||||
// set the status to Stopped
|
||||
status := &router.Status{
|
||||
Code: router.Stopped,
|
||||
Error: nil,
|
||||
}
|
||||
|
||||
// NOTE: should we have Client/Service option in router.Options?
|
||||
s := &svc{
|
||||
opts: options,
|
||||
status: status,
|
||||
router: pb.NewRouterService(router.DefaultName, cli),
|
||||
}
|
||||
|
||||
@@ -63,21 +70,43 @@ func NewRouter(opts ...router.Option) router.Router {
|
||||
|
||||
// Init initializes router with given options
|
||||
func (s *svc) Init(opts ...router.Option) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
for _, o := range opts {
|
||||
o(&s.opts)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Options returns router options
|
||||
func (s *svc) Options() router.Options {
|
||||
return s.opts
|
||||
s.Lock()
|
||||
opts := s.opts
|
||||
s.Unlock()
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
// Table returns routing table
|
||||
func (s *svc) Table() router.Table {
|
||||
return s.table
|
||||
}
|
||||
|
||||
// Start starts the service
|
||||
func (s *svc) Start() error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
s.status = &router.Status{
|
||||
Code: router.Running,
|
||||
Error: nil,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *svc) advertiseEvents(advertChan chan *router.Advert, stream pb.Router_AdvertiseService) error {
|
||||
go func() {
|
||||
<-s.exit
|
||||
@@ -140,12 +169,9 @@ func (s *svc) Advertise() (<-chan *router.Advert, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
// get the status
|
||||
status := s.Status()
|
||||
|
||||
switch status.Code {
|
||||
switch s.status.Code {
|
||||
case router.Running, router.Advertising:
|
||||
stream, err := s.router.Advertise(context.Background(), &pb.AdvertiseRequest{}, s.callOpts...)
|
||||
stream, err := s.router.Advertise(context.Background(), &pb.Request{}, s.callOpts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed getting advert stream: %s", err)
|
||||
}
|
||||
@@ -154,15 +180,7 @@ func (s *svc) Advertise() (<-chan *router.Advert, error) {
|
||||
go s.advertiseEvents(advertChan, stream)
|
||||
return advertChan, nil
|
||||
case router.Stopped:
|
||||
// check if our router is stopped
|
||||
select {
|
||||
case <-s.exit:
|
||||
s.exit = make(chan bool)
|
||||
// call advertise again
|
||||
return s.Advertise()
|
||||
default:
|
||||
return nil, fmt.Errorf("not running")
|
||||
}
|
||||
return nil, fmt.Errorf("not running")
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("error: %s", s.status.Error)
|
||||
@@ -202,6 +220,42 @@ func (s *svc) Process(advert *router.Advert) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Solicit advertise all routes
|
||||
func (s *svc) Solicit() error {
|
||||
// list all the routes
|
||||
routes, err := s.table.List()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// build events to advertise
|
||||
events := make([]*router.Event, len(routes))
|
||||
for i, _ := range events {
|
||||
events[i] = &router.Event{
|
||||
Type: router.Update,
|
||||
Timestamp: time.Now(),
|
||||
Route: routes[i],
|
||||
}
|
||||
}
|
||||
|
||||
advert := &router.Advert{
|
||||
Id: s.opts.Id,
|
||||
Type: router.RouteUpdate,
|
||||
Timestamp: time.Now(),
|
||||
TTL: time.Duration(router.DefaultAdvertTTL),
|
||||
Events: events,
|
||||
}
|
||||
|
||||
select {
|
||||
case s.advertChan <- advert:
|
||||
case <-s.exit:
|
||||
close(s.advertChan)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns router status
|
||||
func (s *svc) Status() router.Status {
|
||||
s.Lock()
|
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/micro/go-micro/client"
|
||||
"github.com/micro/go-micro/network/router"
|
||||
pb "github.com/micro/go-micro/network/router/proto"
|
||||
"github.com/micro/go-micro/router"
|
||||
pb "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
type table struct {
|
@@ -5,8 +5,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/micro/go-micro/network/router"
|
||||
pb "github.com/micro/go-micro/network/router/proto"
|
||||
"github.com/micro/go-micro/router"
|
||||
pb "github.com/micro/go-micro/router/proto"
|
||||
)
|
||||
|
||||
type watcher struct {
|
@@ -8,7 +8,14 @@ import (
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// table is an in memory routing table
|
||||
var (
|
||||
// ErrRouteNotFound is returned when no route was found in the routing table
|
||||
ErrRouteNotFound = errors.New("route not found")
|
||||
// ErrDuplicateRoute is returned when the route already exists
|
||||
ErrDuplicateRoute = errors.New("duplicate route")
|
||||
)
|
||||
|
||||
// table is an in-memory routing table
|
||||
type table struct {
|
||||
sync.RWMutex
|
||||
// routes stores service routes
|
||||
@@ -25,6 +32,19 @@ func newTable(opts ...Option) *table {
|
||||
}
|
||||
}
|
||||
|
||||
// sendEvent sends events to all subscribed watchers
|
||||
func (t *table) sendEvent(e *Event) {
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
for _, w := range t.watchers {
|
||||
select {
|
||||
case w.resChan <- e:
|
||||
case <-w.done:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create creates new route in the routing table
|
||||
func (t *table) Create(r Route) error {
|
||||
service := r.Service
|
||||
@@ -63,8 +83,10 @@ func (t *table) Delete(r Route) error {
|
||||
return ErrRouteNotFound
|
||||
}
|
||||
|
||||
delete(t.routes[service], sum)
|
||||
go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r})
|
||||
if _, ok := t.routes[service][sum]; ok {
|
||||
delete(t.routes[service], sum)
|
||||
go t.sendEvent(&Event{Type: Delete, Timestamp: time.Now(), Route: r})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -85,8 +107,10 @@ func (t *table) Update(r Route) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
t.routes[service][sum] = r
|
||||
go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: r})
|
||||
if _, ok := t.routes[service][sum]; !ok {
|
||||
t.routes[service][sum] = r
|
||||
go t.sendEvent(&Event{Type: Update, Timestamp: time.Now(), Route: r})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -106,21 +130,23 @@ func (t *table) List() ([]Route, error) {
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
// isMatch checks if the route matches given network and router
|
||||
func isMatch(route Route, network, router string) bool {
|
||||
if network == "*" || network == route.Network {
|
||||
if router == "*" || router == route.Gateway {
|
||||
return true
|
||||
// isMatch checks if the route matches given query options
|
||||
func isMatch(route Route, gateway, network, router string) bool {
|
||||
if gateway == "*" || gateway == route.Gateway {
|
||||
if network == "*" || network == route.Network {
|
||||
if router == "*" || router == route.Router {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// findRoutes finds all the routes for given network and router and returns them
|
||||
func findRoutes(routes map[uint64]Route, network, router string) []Route {
|
||||
func findRoutes(routes map[uint64]Route, gateway, network, router string) []Route {
|
||||
var results []Route
|
||||
for _, route := range routes {
|
||||
if isMatch(route, network, router) {
|
||||
if isMatch(route, gateway, network, router) {
|
||||
results = append(results, route)
|
||||
}
|
||||
}
|
||||
@@ -136,13 +162,13 @@ func (t *table) Query(q Query) ([]Route, error) {
|
||||
if _, ok := t.routes[q.Options().Service]; !ok {
|
||||
return nil, ErrRouteNotFound
|
||||
}
|
||||
return findRoutes(t.routes[q.Options().Service], q.Options().Network, q.Options().Gateway), nil
|
||||
return findRoutes(t.routes[q.Options().Service], q.Options().Gateway, q.Options().Network, q.Options().Router), nil
|
||||
}
|
||||
|
||||
var results []Route
|
||||
// search through all destinations
|
||||
for _, routes := range t.routes {
|
||||
results = append(results, findRoutes(routes, q.Options().Network, q.Options().Gateway)...)
|
||||
results = append(results, findRoutes(routes, q.Options().Gateway, q.Options().Network, q.Options().Router)...)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
@@ -160,34 +186,24 @@ func (t *table) Watch(opts ...WatchOption) (Watcher, error) {
|
||||
}
|
||||
|
||||
w := &tableWatcher{
|
||||
id: uuid.New().String(),
|
||||
opts: wopts,
|
||||
resChan: make(chan *Event, 10),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
|
||||
// when the watcher is stopped delete it
|
||||
go func() {
|
||||
<-w.done
|
||||
t.Lock()
|
||||
delete(t.watchers, w.id)
|
||||
t.Unlock()
|
||||
}()
|
||||
|
||||
// save the watcher
|
||||
t.Lock()
|
||||
t.watchers[uuid.New().String()] = w
|
||||
t.watchers[w.id] = w
|
||||
t.Unlock()
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// sendEvent sends events to all subscribed watchers
|
||||
func (t *table) sendEvent(e *Event) {
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
|
||||
for _, w := range t.watchers {
|
||||
select {
|
||||
case w.resChan <- e:
|
||||
case <-w.done:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrRouteNotFound is returned when no route was found in the routing table
|
||||
ErrRouteNotFound = errors.New("route not found")
|
||||
// ErrDuplicateRoute is returned when the route already exists
|
||||
ErrDuplicateRoute = errors.New("duplicate route")
|
||||
)
|
@@ -9,6 +9,7 @@ func testSetup() (*table, Route) {
|
||||
Service: "dest.svc",
|
||||
Gateway: "dest.gw",
|
||||
Network: "dest.network",
|
||||
Router: "src.router",
|
||||
Link: "det.link",
|
||||
Metric: 10,
|
||||
}
|
||||
@@ -109,11 +110,13 @@ func TestQuery(t *testing.T) {
|
||||
svc := []string{"svc1", "svc2", "svc3"}
|
||||
net := []string{"net1", "net2", "net1"}
|
||||
gw := []string{"gw1", "gw2", "gw3"}
|
||||
rtr := []string{"rtr1", "rt2", "rt3"}
|
||||
|
||||
for i := 0; i < len(svc); i++ {
|
||||
route.Service = svc[i]
|
||||
route.Network = net[i]
|
||||
route.Gateway = gw[i]
|
||||
route.Router = rtr[i]
|
||||
if err := table.Create(route); err != nil {
|
||||
t.Errorf("error adding route: %s", err)
|
||||
}
|
||||
@@ -127,8 +130,9 @@ func TestQuery(t *testing.T) {
|
||||
t.Errorf("error looking up routes: %s", err)
|
||||
}
|
||||
|
||||
// query particular net
|
||||
query = NewQuery(QueryNetwork("net1"))
|
||||
// query routes particular network
|
||||
network := "net1"
|
||||
query = NewQuery(QueryNetwork(network))
|
||||
|
||||
routes, err = table.Query(query)
|
||||
if err != nil {
|
||||
@@ -139,7 +143,13 @@ func TestQuery(t *testing.T) {
|
||||
t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 2, len(routes))
|
||||
}
|
||||
|
||||
// query particular gateway
|
||||
for _, route := range routes {
|
||||
if route.Network != network {
|
||||
t.Errorf("incorrect route returned. Expected network: %s, found: %s", network, route.Network)
|
||||
}
|
||||
}
|
||||
|
||||
// query routes for particular gateway
|
||||
gateway := "gw1"
|
||||
query = NewQuery(QueryGateway(gateway))
|
||||
|
||||
@@ -156,11 +166,28 @@ func TestQuery(t *testing.T) {
|
||||
t.Errorf("incorrect route returned. Expected gateway: %s, found: %s", gateway, routes[0].Gateway)
|
||||
}
|
||||
|
||||
// query particular route
|
||||
network := "net1"
|
||||
// query routes for particular router
|
||||
router := "rtr1"
|
||||
query = NewQuery(QueryRouter(router))
|
||||
|
||||
routes, err = table.Query(query)
|
||||
if err != nil {
|
||||
t.Errorf("error looking up routes: %s", err)
|
||||
}
|
||||
|
||||
if len(routes) != 1 {
|
||||
t.Errorf("incorrect number of routes returned. Expected: %d, found: %d", 1, len(routes))
|
||||
}
|
||||
|
||||
if routes[0].Router != router {
|
||||
t.Errorf("incorrect route returned. Expected router: %s, found: %s", router, routes[0].Router)
|
||||
}
|
||||
|
||||
// query particular gateway and network
|
||||
query = NewQuery(
|
||||
QueryGateway(gateway),
|
||||
QueryNetwork(network),
|
||||
QueryRouter(router),
|
||||
)
|
||||
|
||||
routes, err = table.Query(query)
|
||||
@@ -180,7 +207,11 @@ func TestQuery(t *testing.T) {
|
||||
t.Errorf("incorrect network returned. Expected network: %s, found: %s", network, routes[0].Network)
|
||||
}
|
||||
|
||||
// bullshit route query
|
||||
if routes[0].Router != router {
|
||||
t.Errorf("incorrect route returned. Expected router: %s, found: %s", router, routes[0].Router)
|
||||
}
|
||||
|
||||
// non-existen route query
|
||||
query = NewQuery(QueryService("foobar"))
|
||||
|
||||
routes, err = table.Query(query)
|
@@ -6,6 +6,11 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
||||
ErrWatcherStopped = errors.New("watcher stopped")
|
||||
)
|
||||
|
||||
// EventType defines routing table event
|
||||
type EventType int
|
||||
|
||||
@@ -42,9 +47,6 @@ type Event struct {
|
||||
Route Route
|
||||
}
|
||||
|
||||
// WatchOption is used to define what routes to watch in the table
|
||||
type WatchOption func(*WatchOptions)
|
||||
|
||||
// Watcher defines routing table watcher interface
|
||||
// Watcher returns updates to the routing table
|
||||
type Watcher interface {
|
||||
@@ -56,7 +58,11 @@ type Watcher interface {
|
||||
Stop()
|
||||
}
|
||||
|
||||
// WatchOption is used to define what routes to watch in the table
|
||||
type WatchOption func(*WatchOptions)
|
||||
|
||||
// WatchOptions are table watcher options
|
||||
// TODO: expand the options to watch based on other criteria
|
||||
type WatchOptions struct {
|
||||
// Service allows to watch specific service routes
|
||||
Service string
|
||||
@@ -70,8 +76,10 @@ func WatchService(s string) WatchOption {
|
||||
}
|
||||
}
|
||||
|
||||
// tableWatcher implements routing table Watcher
|
||||
type tableWatcher struct {
|
||||
sync.RWMutex
|
||||
id string
|
||||
opts WatchOptions
|
||||
resChan chan *Event
|
||||
done chan struct{}
|
||||
@@ -112,8 +120,3 @@ func (w *tableWatcher) Stop() {
|
||||
close(w.done)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
||||
ErrWatcherStopped = errors.New("watcher stopped")
|
||||
)
|
@@ -1,9 +0,0 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/micro/go-micro/server/debug"
|
||||
)
|
||||
|
||||
func registerDebugHandler(s Server) {
|
||||
s.Handle(s.NewHandler(&debug.Debug{s.Options().DebugHandler}, InternalHandler(true)))
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
proto "github.com/micro/go-micro/server/debug/proto"
|
||||
)
|
||||
|
||||
// The debug handler represents an internal server handler
|
||||
// used to determine health, status and env info about
|
||||
// a service node. It's akin to Google's /statusz, /healthz,
|
||||
// and /varz
|
||||
type Handler interface {
|
||||
Health(ctx context.Context, req *proto.HealthRequest, rsp *proto.HealthResponse) error
|
||||
Stats(ctx context.Context, req *proto.StatsRequest, rsp *proto.StatsResponse) error
|
||||
}
|
||||
|
||||
// Our own internal handler
|
||||
type debug struct {
|
||||
started int64
|
||||
}
|
||||
|
||||
// We use this to wrap any debug handlers so we preserve the signature Debug.{Method}
|
||||
type Debug struct {
|
||||
Handler
|
||||
}
|
||||
|
||||
var (
|
||||
DefaultHandler Handler = newDebug()
|
||||
)
|
||||
|
||||
func newDebug() *debug {
|
||||
return &debug{
|
||||
started: time.Now().Unix(),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *debug) Health(ctx context.Context, req *proto.HealthRequest, rsp *proto.HealthResponse) error {
|
||||
rsp.Status = "ok"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *debug) Stats(ctx context.Context, req *proto.StatsRequest, rsp *proto.StatsResponse) error {
|
||||
var mstat runtime.MemStats
|
||||
runtime.ReadMemStats(&mstat)
|
||||
|
||||
rsp.Started = uint64(d.started)
|
||||
rsp.Uptime = uint64(time.Now().Unix() - d.started)
|
||||
rsp.Memory = mstat.Alloc
|
||||
rsp.Gc = mstat.PauseTotalNs
|
||||
rsp.Threads = uint64(runtime.NumGoroutine())
|
||||
return nil
|
||||
}
|
@@ -1,100 +0,0 @@
|
||||
// Code generated by protoc-gen-go.
|
||||
// source: github.com/micro/go-micro/server/debug/proto/debug.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package debug is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
github.com/micro/go-micro/server/debug/proto/debug.proto
|
||||
|
||||
It has these top-level messages:
|
||||
HealthRequest
|
||||
HealthResponse
|
||||
StatsRequest
|
||||
StatsResponse
|
||||
*/
|
||||
package debug
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
|
||||
type HealthRequest struct {
|
||||
}
|
||||
|
||||
func (m *HealthRequest) Reset() { *m = HealthRequest{} }
|
||||
func (m *HealthRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*HealthRequest) ProtoMessage() {}
|
||||
func (*HealthRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
|
||||
type HealthResponse struct {
|
||||
// default: ok
|
||||
Status string `protobuf:"bytes,1,opt,name=status" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *HealthResponse) Reset() { *m = HealthResponse{} }
|
||||
func (m *HealthResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*HealthResponse) ProtoMessage() {}
|
||||
func (*HealthResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
|
||||
type StatsRequest struct {
|
||||
}
|
||||
|
||||
func (m *StatsRequest) Reset() { *m = StatsRequest{} }
|
||||
func (m *StatsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatsRequest) ProtoMessage() {}
|
||||
func (*StatsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
|
||||
|
||||
type StatsResponse struct {
|
||||
// unix timestamp
|
||||
Started uint64 `protobuf:"varint,1,opt,name=started" json:"started,omitempty"`
|
||||
// in seconds
|
||||
Uptime uint64 `protobuf:"varint,2,opt,name=uptime" json:"uptime,omitempty"`
|
||||
// in bytes
|
||||
Memory uint64 `protobuf:"varint,3,opt,name=memory" json:"memory,omitempty"`
|
||||
// num threads
|
||||
Threads uint64 `protobuf:"varint,4,opt,name=threads" json:"threads,omitempty"`
|
||||
// in nanoseconds
|
||||
Gc uint64 `protobuf:"varint,5,opt,name=gc" json:"gc,omitempty"`
|
||||
}
|
||||
|
||||
func (m *StatsResponse) Reset() { *m = StatsResponse{} }
|
||||
func (m *StatsResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*StatsResponse) ProtoMessage() {}
|
||||
func (*StatsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*HealthRequest)(nil), "HealthRequest")
|
||||
proto.RegisterType((*HealthResponse)(nil), "HealthResponse")
|
||||
proto.RegisterType((*StatsRequest)(nil), "StatsRequest")
|
||||
proto.RegisterType((*StatsResponse)(nil), "StatsResponse")
|
||||
}
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 201 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x34, 0x8f, 0xbd, 0x6e, 0x83, 0x30,
|
||||
0x14, 0x85, 0x05, 0xa5, 0x54, 0xbd, 0x2a, 0x54, 0x62, 0xa8, 0x3c, 0x56, 0x4c, 0x2c, 0xc5, 0x43,
|
||||
0x97, 0x3e, 0x42, 0x67, 0xf2, 0x04, 0xfc, 0x5c, 0x19, 0xa4, 0x38, 0x26, 0xbe, 0xd7, 0x91, 0x32,
|
||||
0xe7, 0xc5, 0x03, 0xb6, 0xd9, 0xce, 0xf7, 0xd9, 0xe7, 0x48, 0x17, 0xfe, 0xd4, 0xc2, 0xb3, 0x1b,
|
||||
0xda, 0xd1, 0x68, 0xa9, 0x97, 0xd1, 0x1a, 0xa9, 0xcc, 0x4f, 0x08, 0x84, 0xf6, 0x86, 0x56, 0x4e,
|
||||
0x38, 0x38, 0x25, 0x57, 0x6b, 0xd8, 0x84, 0xdc, 0xfa, 0x5c, 0x7f, 0x42, 0xf1, 0x8f, 0xfd, 0x99,
|
||||
0xe7, 0x0e, 0xaf, 0x0e, 0x89, 0xeb, 0x06, 0xca, 0x43, 0xd0, 0x6a, 0x2e, 0x84, 0xd5, 0x17, 0xe4,
|
||||
0xc4, 0x3d, 0x3b, 0x12, 0xc9, 0x77, 0xd2, 0xbc, 0x77, 0x91, 0xea, 0x12, 0x3e, 0x4e, 0x5b, 0xa2,
|
||||
0xa3, 0xf9, 0x48, 0xa0, 0x88, 0x22, 0x36, 0x05, 0xbc, 0x6d, 0x7f, 0x2d, 0xe3, 0xe4, 0xab, 0x59,
|
||||
0x77, 0xe0, 0xbe, 0xe9, 0x56, 0x5e, 0x34, 0x8a, 0xd4, 0x3f, 0x44, 0xda, 0xbd, 0x46, 0x6d, 0xec,
|
||||
0x5d, 0xbc, 0x04, 0x1f, 0x68, 0x5f, 0xe2, 0xd9, 0x62, 0x3f, 0x91, 0xc8, 0xc2, 0x52, 0xc4, 0xaa,
|
||||
0x84, 0x54, 0x8d, 0xe2, 0xd5, 0xcb, 0x2d, 0x0d, 0xb9, 0xbf, 0xeb, 0xf7, 0x19, 0x00, 0x00, 0xff,
|
||||
0xff, 0xc6, 0x75, 0x51, 0x35, 0x13, 0x01, 0x00, 0x00,
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user