Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document go-basic go-micro interfaces #1749

Closed
butonic opened this issue Mar 2, 2021 · 6 comments
Closed

Document go-basic go-micro interfaces #1749

butonic opened this issue Mar 2, 2021 · 6 comments

Comments

@butonic
Copy link
Member

butonic commented Mar 2, 2021

The basic interfaces that describe how clients and servers interact in go-micro are: Service, Server, Client, Registry and Selector:

@startuml
namespace server {
    interface server.Server  {
        + Handle( Handler) error
        + NewHandler( <font color=blue>interface</font>{},  ...HandlerOption) Handler
        + NewSubscriber( string,  <font color=blue>interface</font>{},  ...SubscriberOption) Subscriber
        + Subscribe( Subscriber) error
        + Start() error
        + Stop() error
    }
}
namespace registry {
    interface registry.Registry  {
    }
    class registry.Service << (S,Aquamarine) >> {
        + Name string
        + Version string
        + Metadata <font color=blue>map</font>[string]string

    }
    class registry.Node << (S,Aquamarine) >> {
        + Id string
        + Address string
        + Metadata <font color=blue>map</font>[string]string

    }
    "registry.Registry" "1" *-- "many" "registry.Service"
    "registry.Service" "1" *-- "many" "registry.Node"
}
namespace service {
    interface service.Service  {
        + Name() string
        + Run() error
    }
}
namespace client {
    interface client.Client  {
        + NewMessage(topic string, msg <font color=blue>interface</font>{}, opts ...MessageOption) Message
        + NewRequest(service string, endpoint string, req <font color=blue>interface</font>{}, reqOpts ...RequestOption) Request
        + Call(ctx context.Context, req Request, rsp <font color=blue>interface</font>{}, opts ...CallOption) error
        + Stream(ctx context.Context, req Request, opts ...CallOption) (Stream, error)
        + Publish(ctx context.Context, msg Message, opts ...PublishOption) error
    }
}
namespace selector {
    interface selector.Selector  {
        + Select(service string, opts ...SelectOption) (selector.Next, error)
        + Mark(service string, node *registry.Node, err error) 
        + Reset(service string) 
    }
    class selector.Next << (T, #FF7700) >>  {
    }
    class "<font color=blue>func</font>() (*registry.Node, error)" as fontcolorbluefuncfontregistryNodeerror {
        'This class was created so that we can correctly have an alias pointing to this name. Since it contains dots that can break namespaces
    }
    "selector.fontcolorbluefuncfontregistryNodeerror" #.. "selector.Next"
    
    "selector.Selector" o-- "selector.Next" 
}
"server.Server" o-- "registry.Registry"
"client.Client" o-- "registry.Registry"
"client.Client" o-- "selector.Selector"
"selector.Selector" o-- "registry.Registry"
"service.Service" o-- "client.Client"
"service.Service" o-- "server.Server"

@enduml

interfaces

When you want to make a call to a Server you would instantiate a Service by name and then call Client() on it. When making a Call() the Client then uses the Selector s Next() to look up the actual Node in the Registry. It contains the address and port to which the request should actually be made.

When starting a Server you would instantiate a Service by name and then call Server() on it. This will initialize the Server with a Registry that is used to register the Service when Start()ing it. The Service also has an Address and an Advertise option. When ´Advertise´ is present it will be used as the Address that is registered in the registry, allowing the service lo listen on Address=0.0.0.0:1234 while registering Advertise=1.2.3.4:1234 as the Address in the registry. This solves the problem of differentiating between the listen address and the host:port other services should connect to.

The go-micro interface cover way more aspects of a microservice architecture, eg. Broker, Publisher, Subscribe or more fine granular things like Codecs and Transports.

@ishank011
Copy link
Contributor

@butonic thanks a lot for this!

The Service also has an Address and an Advertise option.

The nodes should have these options, right? And the service would have a 1-many relationship with the nodes.

@butonic
Copy link
Member Author

butonic commented Mar 3, 2021

There are two sides to the service registry:

A Server uses the Address option as the listen address. It will use the Advertise options to register itself with the Registry if it is given. Otherwise it will fall back to Address.

In the Registry a registry.Service has a 1-many relationship with registry.Nodes. While every Node represents a Server, it only has an Address field that is used by other Client to connect to it.

So, Servers are not really aware of other Nodes. They could look them up using the registry if they wanted to, though.

@dragotin
Copy link
Contributor

dragotin commented Mar 3, 2021

This is great work, thanks for it.

I would love to have an addition that explains the used terms Service, Server, Client, Selector and such in one sentence. That will ease understanding big times.

@stale
Copy link

stale bot commented Jul 10, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 10 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status:Stale label Jul 10, 2021
@stale stale bot closed this as completed Jul 20, 2021
@stale stale bot removed the Status:Stale label Jul 21, 2021
@stale
Copy link

stale bot commented Sep 19, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 10 days if no further activity occurs. Thank you for your contributions.

@kobergj
Copy link
Collaborator

kobergj commented Jun 7, 2024

Outdated. Closing.

@kobergj kobergj closed this as completed Jun 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants