Skip to content

Instantly share code, notes, and snippets.

@mjpitz
Last active January 26, 2021 03:46
Show Gist options
  • Save mjpitz/7c1f15f1ee0ef1804b662e91a6e1d042 to your computer and use it in GitHub Desktop.
Save mjpitz/7c1f15f1ee0ef1804b662e91a6e1d042 to your computer and use it in GitHub Desktop.

Shows how to connect Hashicorp's memberlist to Golang's groupcache for dynamic cluster membership. Memberlist gossip can be encrypted by setting the SecretKey or Keyring attributes on cfg.

package main
import (
"github.com/golang/groupcache"
"github.com/hashicorp/memberlist"
"log"
"net"
"net/http"
"time"
)
func main() {
mux := http.DefaultServeMux
port := "8080"
httpAddress := func(ip string) string {
return net.JoinHostPort(ip, port)
}
// sets up UDP/TCP server on 0.0.0.0:7946
cfg := memberlist.DefaultLocalConfig()
list, err := memberlist.Create(cfg)
if err != nil {
log.Fatal("cannot start memberlist servers", err)
}
// join existing members
_, err = list.Join([]string{"discovery.address"})
if err != nil {
log.Fatal("cannot join memberlist server", err)
}
self := httpAddress(list.LocalNode().Addr.String())
opts := &groupcache.HTTPPoolOptions{BasePath: "/_groupcache/"}
pool := groupcache.NewHTTPPoolOpts(self, opts)
mux.Handle(opts.BasePath, pool)
// setup background worker
go func() {
for {
// update groupcache peers based on memberlist every 5 seconds
<- time.Tick(5 * time.Second)
members := list.Members()
peers := make([]string, 0, len(members))
for _, member := range members {
peer := httpAddress(member.Addr.String())
if peer != self {
peers = append(peers, self)
}
}
pool.Set(peers...)
}
}()
// cache of 64MB
group := groupcache.NewGroup("name", 64 << 20, groupcache.GetterFunc(
func(ctx context.Context, key string, dest Sink) error {
// cache miss
// dest.SetString(str)
// dest.SetProto(msg)
return nil
}
))
// err := group.Get(ctx, "key", groupcache.StringSink(&str))
// err := group.Get(ctx, "key", groupcache.ProtoSink(msg))
// sets up HTTP server on 0.0.0.0:8080
if err := http.ListenAndServe(httpAddress("0.0.0.0"), mux); err != nil {
log.Fatal("cannot start http server", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment