Skip to content

Latest commit

 

History

History
80 lines (66 loc) · 2.85 KB

README.md

File metadata and controls

80 lines (66 loc) · 2.85 KB

ETCD Adapter

ETCD Adapter mimics the ETCD V3 APIs best effort. It incorporates the kine as the Server side implementation, and it develops a totally in-memory watchable backend.

Not all features in ETCD V3 APIs supported, this is designed for Apache APISIX, so it's inherently not a generic solution.

How to use it

It's easy to create an etcd adapter instance. The use of this instance contains two parts, the first thing is you should prepare a network listener and let it run. ETCD adapter launches a gRPC service (with a built-in gRPC Gateway, so that HTTP Restful requests can also be handled), you can try to access this service with the etcdctl tool.

The another thing is you should feed some events to this instance, so that data changes can be applied to the instance and ultimately it affects the end-user of this gRPC service.

package main

import (
        "context"
        "fmt"
        "math/rand"
        "net"
        "time"

        adapter "github.com/api7/etcd-adapter"
)

func init() {
        rand.Seed(time.Now().UnixNano())
}

func main() {
        a := adapter.NewEtcdAdapter(nil)
        ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Hour)
        defer cancel()
        go produceEvents(ctx, a)

        ln, err := net.Listen("tcp", "127.0.0.1:12379")
        if err != nil {
                panic(err)
        }
        go func() {
                if err := a.Serve(context.Background(), ln); err != nil {
                        panic(err)
                }
        }()
        <-ctx.Done()
        if err := a.Shutdown(context.TODO()); err != nil {
                panic(err)
        }
}

func produceEvents(ctx context.Context, a adapter.Adapter) {
        ticker := time.NewTicker(time.Second)
        for {
                select {
                case <-ctx.Done():
                        return
                case <-ticker.C:
                        break
                }
                event := &adapter.Event{
                        Type: adapter.EventType(rand.Intn(3) + 1),
                        Key:  fmt.Sprintf("/key/part/%d", rand.Int()),
                }
                if event.Type != adapter.EventDelete {
                        event.Value = []byte(fmt.Sprintf("value-%d", rand.Int()))
                }
                a.EventCh() <- []*adapter.Event{event}
        }
}

The above example shows a simple usage about the etcd adapter.

Note, get keys by prefix constrained strictly as the key format has to be path-like, for instance, keys can be /apisix/routes/1, apisix/upstreams/2, and you can get them with the prefix /apisix, or /apisix/routes, /apisix/upstreams perspective.