Skip to content
/ etcdseq Public

Etcdseq is an lightweight library to support sequence nodes via etcd.

License

Notifications You must be signed in to change notification settings

WqyJh/etcdseq

Repository files navigation

etcdseq GoDoc

Etcdseq is an lightweight library to support sequence nodes via etcd.

Sequence nodes can be achieved by other ways, such as:

  • Zookeeper sequence nodes
  • K8S StatefulSet

However, if you're using etcd rather than zookeeper and using K8S Deployment rather than StatefulSet, etcdseq can help.

What's more, etcdseq provides index/count pair as node info, which is useful when you need the number of total nodes. Zookeeper and K8S only provide index.

Design

Assume you have 3 nodes, every nodes would be assigned with an index/count pair.

  • node1: index=0 count=3
  • node2: index=1 count=3
  • node3: index=2 count=3

When new nodes added, count would change.

  • node1: index=0 count=4
  • node2: index=1 count=4
  • node3: index=2 count=4
  • node4: index=3 count=4

When nodes removed, indexes of the later nodes would change, and count would change too.

  • node1: index=0 count=3
  • node3: index=1 count=3
  • node4: index=2 count=3

Usage

Simply use an ChanHandler to recieve the node change event sequentially.

    // first create an etcd connection
    etcdClient, err := clientv3.New(clientv3.Config{
		Endpoints: []string{"http://localhost:2379"},
	})

    // create an channel to receive events
    ch := make(chan etcdseq.Info, 100)

    // key is the identifier of the nodes group
    key := "service-group"

    // create an EtcdSeq
    seq := etcdseq.NewEtcdSeq(etcdClient, key, etcdseq.NewChanHandler(ch))

    // start EtcdSeq service
	err = seq.Start()

    // make sure you stop EtcdSeq after you no longer need it.
    seq.Stop()

Use the following structure of code to handle the node change event. The key point is startService(info) which means you start your own service and allocate the resources according to the index/count pair. And remember using stopService to release the resources when node changed. If info.Invalid(), then there's no node alive anymore, just stop your service.

func run(ctx context.Context) {
    var oldInfo etcdseq.Info
	for {
		select {
		case <-ctx.Done():
			stopService()
			return
		case info := <-ch:
			// drain for the latest (it's an optional optimization)
			for i := 0; i < len(ch); i++ {
				info = <-ch
			}
			if info.Invalid() {
				stopService()
				continue
			}
			if oldInfo.Equal(info) {
                // remain unchanged (it's an optional optimization)
				continue
			}
            stopService()
            startService(info)
            oldInfo = info
		}
	}
}

License

Released under the MIT License.

About

Etcdseq is an lightweight library to support sequence nodes via etcd.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages