Go-micro: registry configuration with flags

Created on 8 Jul 2017  路  9Comments  路  Source: asim/go-micro

How do we use flags in conjunction with using NewService?

If I define flags in NewService() and registry hostname (consul's location) in Registry() I can't use EnvVar in Registry(), since cli/env arguments will only be parsed after Init().

Am I right?

The flow is: Define default options, check cli/env vars, define registry and then define a new service.

package main

import (
        "fmt"
        cli "github.com/micro/cli"
        micro "github.com/micro/go-micro"
        registry "github.com/micro/go-micro/registry"
)

func main() {
        fmt.Println("vim-go")

        flags := micro.Flags(
                cli.StringFlag{
                        Name:   "consul-hostname",
                        Value:  "127.0.0.1",
                        Usage:  "Consul registry client host name",
                        EnvVar: "CROWD_CONSUL_HOSTNAME",
                },
        )

        opts := registry.Option(func(opts *registry.Options) {
                // I'd like to set Addrs according to Flags above.
                opts.Addrs = []string{"consul"}
        })

        service := micro.NewService(
                micro.Name("foo"),
                micro.Version("alpha"),
                micro.Registry(registry.NewRegistry(opts)),
                flags,
        )

        service.Init()

        if err := service.Run(); err != nil {
                fmt.Println(err)
        }
}

Should I use Context from Options given from micro.Flags above?

All 9 comments

Why are you defining a new consul registry? That's the question. Consul is the default registry. You can quite simply use --registry_address flag and it will create a new registry within your service with the address set.

In the case of using flags see an example here https://github.com/micro/examples

@asim Very good, thanks!!!

@asim: Should we be able to also set env var MICRO_REGISTRY_ADDRESS instead of calling --registry_address?

I need this usecase for tests, since registry_address doesn't pass into the test for a go-micro client.

Tried MICRO_REGISTRY_ADDRESS=0.0.0.2 go test -v ./tests, but it still looks at 127.0.0.1.

Also, tried with a client code from the examples:

package main

import (
    "fmt"

    proto "github.com/micro/examples/service/proto"
    micro "github.com/micro/go-micro"
    "golang.org/x/net/context"
)

func main() {
    // Create a new service. Optionally include some options here.
    service := micro.NewService(micro.Name("greeter.client"))

    // Create new greeter client
    greeter := proto.NewGreeterClient("greeter", service.Client())

    // Call the greeter
    rsp, err := greeter.Hello(context.TODO(), &proto.HelloRequest{Name: "John"})
    if err != nil {
        fmt.Println(err)
    }

    // Print response
    fmt.Println(rsp.Greeting)
}

go run client.go --registry_address 192.68.2.2 still looks at 127.0.0.1

The env var is just another way of setting the flag. https://github.com/micro/go-micro/blob/master/cmd/cmd.go#L126L130. The library should pick this up and set it. Your client example is not calling service.Init. Flags or env vars are not parsed unless you call service.Init

Thanks. I would like to do something like this:

package main

import (
        "testing"

        micro "github.com/micro/go-micro"
        "golang.org/x/net/context"
)

var service micro.Service

func init() {
        service = micro.NewService(micro.Name("mysrv.client"))
        service.Init()
}

func TestCheck(t *testing.T) {
        c := check.NewCheckClient("mysrv", service.Client())

        rsp, err := c.Ping(context.TODO(), &check.PingRequest{})
        if err != nil {
                t.Fatal(err)
        }

        // Print response
        if rsp.Pong != "All good." {
                t.Fatal("Service check response not okay.")
        }
}

func TestSubscribersGetAll(t *testing.T) {
        s := subs.NewSubscribersClient("mysrv", service.Client())

        rsp, err := s.GetAll(context.TODO(), &subs.Request{})
        if err != nil {
                t.Fatal(err)
        }

        // Print response
        if rsp.List != "1234" {
                t.Fatal("Subscribers GetAll response not okay.")
        }
}

I get "Incorrect Usage." out. I cannot initialize a new service for each test, either.
What's the way to do that?

Doesn't work if I use this, either:

var service = micro.NewService(micro.Name("mysrv.client"))

func TestMain(m *testing.M) {
    service.Init(
        micro.Action(func(c *cli.Context) {
            log.Println(c)
        }),
    )

    if err := service.Run(); err != nil {
        log.Fatal(err)
    }

    os.Exit(m.Run())
}

Edit: Seems like there is an issue if I run go test with a verbose flag (go test -v ./tests). If I run without it, go test just hangs.

Edit 2: First example using func init works correctly if I run test without verbose! I guess -v passes through somehow to micro's cli and that's the problem...

There's probably some sort of overlap between the go flag parse, the micro cli parser and the fact that its a test. I'm not really looking to support this use case. In the case of an actual service, flags, init and env vars should all work. Closing.

Yeah, right now I'm having trouble because of this, since I need verbose. I'm TDDing with docker-compose. Nothing is tested against a host machine. The only way for me to test and develop is running dockers and debugging my code while developing. Something I'd normally use curl or something else for. But I don't want to curl anymore. :)

Right now I can't really debug anything because -v is not getting through, which leaves me with running the container, execing into it and running my app with the verbose flag be the only option, and yet that one seems dirty.

What I'm saying is that I can't run fmt.Println or t.Log in my tests easily to see what I have around the code anymore.
What's good about this approach, though, is that I am forced to pay more attention to types and patiently read the docs, hehe. :)

asim ,please i did go run main.go --registery=consul...all it was ok i find the service in the consul but i did find both consul and service in mico services ????

Was this page helpful?
0 / 5 - 0 ratings