diff --git a/README.md b/README.md index 1795aad1..21fa002e 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ You can schedule sending messages to actor that will be acted upon in the future #### Cron Expression Format | Field | Required | Allowed Values | Allowed Special Characters | -|--------------|----------|-----------------|----------------------------| +| ------------ | -------- | --------------- | -------------------------- | | Seconds | yes | 0-59 | , - * / | | Minutes | yes | 0-59 | , - * / | | Hours | yes | 0-23 | , - * / | @@ -382,7 +382,7 @@ const ( applicationName = "accounts" actorSystemName = "AccountsSystem" gossipPortName = "gossip-port" - clusterPortName = "cluster-port" + peersPortName = "peers-port" remotingPortName = "remoting-port" ) // define the discovery config @@ -392,7 +392,7 @@ config := kubernetes.Config{ Namespace: namespace, GossipPortName: gossipPortName, RemotingPortName: remotingPortName, - ClusterPortName: clusterPortName, + PeersPortName: peersPortName, } // instantiate the k8 discovery provider diff --git a/actors/actor_system.go b/actors/actor_system.go index 888765bb..dd70e240 100644 --- a/actors/actor_system.go +++ b/actors/actor_system.go @@ -35,6 +35,7 @@ import ( "connectrpc.com/connect" "connectrpc.com/otelconnect" + "github.com/alphadose/haxmap" "github.com/google/uuid" "github.com/pkg/errors" "go.opentelemetry.io/otel/codes" @@ -180,10 +181,11 @@ type actorSystem struct { // define the number of partitions to shard the actors in the cluster partitionsCount uint64 // cluster mode - cluster cluster.Interface - clusterChan chan *internalpb.WireActor - clusterPort int - gossipPort int + cluster cluster.Interface + clusterChan chan *internalpb.WireActor + peersPort int + gossipPort int + minimumPeersQuorum uint16 partitionHasher hash.Hasher @@ -214,6 +216,8 @@ type actorSystem struct { registry types.Registry reflection reflection + + peersCache *haxmap.Map[string, []byte] } // enforce compilation error when all methods of the ActorSystem interface are not implemented @@ -230,7 +234,7 @@ func NewActorSystem(name string, opts ...Option) (ActorSystem, error) { } system := &actorSystem{ - actors: newPIDMap(10), + actors: newPIDMap(1_000), // TODO need to check with memory footprint here since we change the map engine clusterChan: make(chan *internalpb.WireActor, 10), name: name, logger: log.DefaultLogger, @@ -250,6 +254,8 @@ func NewActorSystem(name string, opts ...Option) (ActorSystem, error) { eventsChan: make(chan *cluster.Event, 1), registry: types.NewRegistry(), clusterSyncStopSig: make(chan types.Unit, 1), + minimumPeersQuorum: 1, + peersCache: haxmap.New[string, []byte](100), // TODO need to check with memory footprint here since we change the map engine } system.started.Store(false) @@ -754,9 +760,6 @@ func (x *actorSystem) Start(ctx context.Context) error { if err := x.enableClustering(spanCtx); err != nil { return err } - // start cluster synchronization - // TODO: revisit this - // go x.runClusterSync() } x.scheduler.Start(spanCtx) @@ -828,6 +831,7 @@ func (x *actorSystem) Stop(ctx context.Context) error { } } + x.actors.close() x.reset() return nil } @@ -864,11 +868,11 @@ func (x *actorSystem) RemoteAsk(ctx context.Context, stream *connect.BidiStream[ } for { - switch ctx.Err() { - case context.Canceled: - return connect.NewError(connect.CodeCanceled, ctx.Err()) - case context.DeadlineExceeded: - return connect.NewError(connect.CodeDeadlineExceeded, ctx.Err()) + switch err := ctx.Err(); { + case errors.Is(err, context.Canceled): + return connect.NewError(connect.CodeCanceled, err) + case errors.Is(err, context.DeadlineExceeded): + return connect.NewError(connect.CodeDeadlineExceeded, err) } request, err := stream.Receive() @@ -1074,16 +1078,17 @@ func (x *actorSystem) enableClustering(ctx context.Context) error { Name: x.name, Host: x.remotingHost, GossipPort: x.gossipPort, - ClusterPort: x.clusterPort, + PeersPort: x.peersPort, RemotingPort: int(x.remotingPort), } - cluster, err := cluster.NewNode(x.Name(), + cluster, err := cluster.NewEngine(x.Name(), x.discoveryProvider, &hostNode, cluster.WithLogger(x.logger), cluster.WithPartitionsCount(x.partitionsCount), cluster.WithHasher(x.partitionHasher), + cluster.WithMinimumPeersQuorum(x.minimumPeersQuorum), ) if err != nil { x.logger.Error(errors.Wrap(err, "failed to initialize cluster engine")) @@ -1193,19 +1198,6 @@ func (x *actorSystem) reset() { x.cluster = nil } -// broadcast publishes newly created actor into the cluster when cluster is enabled -func (x *actorSystem) broadcast(ctx context.Context) { - for wireActor := range x.clusterChan { - if x.cluster != nil { - if err := x.cluster.PutActor(ctx, wireActor); err != nil { - x.logger.Error(err.Error()) - // TODO: stop or continue - return - } - } - } -} - // housekeeper time to time removes dead actors from the system // that helps free non-utilized resources func (x *actorSystem) housekeeper() { @@ -1256,13 +1248,25 @@ func (x *actorSystem) registerMetrics() error { return err } +// broadcast publishes newly created actor into the cluster when cluster is enabled +func (x *actorSystem) broadcast(ctx context.Context) { + for wireActor := range x.clusterChan { + if x.cluster != nil { + // set the actor in the cluster + if err := x.cluster.PutActor(ctx, wireActor); err != nil { + x.logger.Panic(err.Error()) + } + } + } +} + // broadcastClusterEvents listens to cluster events and send them to the event streams func (x *actorSystem) broadcastClusterEvents() { for event := range x.eventsChan { if x.clusterEnabled.Load() { if event != nil && event.Payload != nil { // first need to resync actors map back to the cluster - x.clusterSync() + x.syncActors() // push the event to the event stream message, _ := event.Payload.UnmarshalNew() if x.eventsStream != nil { @@ -1275,12 +1279,12 @@ func (x *actorSystem) broadcastClusterEvents() { } } -// clusterSync synchronizes the node' actors map to the cluster. -func (x *actorSystem) clusterSync() { - typesMap := x.actors.props() - if len(typesMap) != 0 { +// syncActors synchronizes the node' actors map to the cluster. +func (x *actorSystem) syncActors() { + props := x.actors.props() + if len(props) != 0 { x.logger.Info("syncing node actors map to the cluster...") - for actorID, prop := range typesMap { + for actorID, actorProp := range props { actorPath := NewPath(actorID, NewAddress(x.name, "", -1)) if x.remotingEnabled.Load() { actorPath = NewPath(actorID, NewAddress(x.name, x.remotingHost, int(x.remotingPort))) @@ -1294,32 +1298,9 @@ func (x *actorSystem) clusterSync() { ActorName: actorID, ActorAddress: actorPath.RemoteAddress(), ActorPath: actorPath.String(), - ActorType: prop.rtype.Name(), + ActorType: actorProp.rtype.Name(), } } x.logger.Info("node actors map successfully synced back to the cluster.") } } - -// runClusterSync runs time to time cluster synchronization -// by populating the given node actors map to the cluster for availability -func (x *actorSystem) runClusterSync() { - x.logger.Info("cluster synchronization has started...") - ticker := time.NewTicker(5 * time.Minute) - tickerStopSig := make(chan types.Unit, 1) - go func() { - for { - select { - case <-ticker.C: - x.clusterSync() - case <-x.clusterSyncStopSig: - tickerStopSig <- types.Unit{} - return - } - } - }() - - <-tickerStopSig - ticker.Stop() - x.logger.Info("cluster synchronization has stopped...") -} diff --git a/actors/actor_system_test.go b/actors/actor_system_test.go index feecd719..8f186f04 100644 --- a/actors/actor_system_test.go +++ b/actors/actor_system_test.go @@ -182,7 +182,7 @@ func TestActorSystem(t *testing.T) { WithLogger(logger), WithReplyTimeout(time.Minute), WithRemoting(host, int32(remotingPort)), - WithClustering(provider, 9, gossipPort, clusterPort)) + WithClustering(provider, 9, 1, gossipPort, clusterPort)) require.NoError(t, err) provider.EXPECT().ID().Return("testDisco") @@ -947,7 +947,7 @@ func TestActorSystem(t *testing.T) { WithLogger(logger), WithReplyTimeout(time.Minute), WithRemoting(host, int32(remotingPort)), - WithClustering(provider, 9, gossipPort, clusterPort)) + WithClustering(provider, 9, 1, gossipPort, clusterPort)) require.NoError(t, err) provider.EXPECT().ID().Return("testDisco") @@ -1172,7 +1172,7 @@ func TestActorSystem(t *testing.T) { WithLogger(logger), WithReplyTimeout(time.Minute), WithRemoting(host, int32(remotingPort)), - WithClustering(provider, 9, gossipPort, clusterPort)) + WithClustering(provider, 9, 1, gossipPort, clusterPort)) require.NoError(t, err) provider.EXPECT().ID().Return("testDisco") diff --git a/actors/actor_test.go b/actors/actor_test.go index 252f2051..1d1362a2 100644 --- a/actors/actor_test.go +++ b/actors/actor_test.go @@ -444,7 +444,7 @@ func startClusterSystem(t *testing.T, nodeName, serverAddr string) (ActorSystem, Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -458,7 +458,7 @@ func startClusterSystem(t *testing.T, nodeName, serverAddr string) (ActorSystem, WithLogger(logger), WithReplyTimeout(time.Minute), WithRemoting(host, int32(remotingPort)), - WithClustering(provider, 10, gossipPort, clusterPort)) + WithClustering(provider, 10, 1, gossipPort, clusterPort)) require.NotNil(t, system) require.NoError(t, err) diff --git a/actors/option.go b/actors/option.go index 9cf26c78..6b2036cb 100644 --- a/actors/option.go +++ b/actors/option.go @@ -113,14 +113,15 @@ func WithRemoting(host string, port int32) Option { }) } -// WithClustering enables clustering on the actor system. -func WithClustering(provider discovery.Provider, partitionCount uint64, gossipPort, clusterPort int) Option { +// WithClustering enables the cluster mode. +func WithClustering(provider discovery.Provider, partitionCount uint64, minimumPeersQuorum uint16, gossipPort, peersPort int) Option { return OptionFunc(func(a *actorSystem) { a.clusterEnabled.Store(true) a.partitionsCount = partitionCount a.discoveryProvider = provider - a.clusterPort = clusterPort + a.peersPort = peersPort a.gossipPort = gossipPort + a.minimumPeersQuorum = minimumPeersQuorum }) } diff --git a/actors/pid_map.go b/actors/pid_map.go index 434d8aa5..60d51dbf 100644 --- a/actors/pid_map.go +++ b/actors/pid_map.go @@ -26,8 +26,8 @@ package actors import ( "reflect" - "sync" - "sync/atomic" + + "github.com/alphadose/haxmap" "github.com/tochemey/goakt/internal/types" ) @@ -38,38 +38,32 @@ type prop struct { } type pidMap struct { - mu *sync.RWMutex - size atomic.Int64 - propsMap map[string]*prop + mappings *haxmap.Map[string, *prop] } func newPIDMap(cap int) *pidMap { return &pidMap{ - mu: &sync.RWMutex{}, - propsMap: make(map[string]*prop, cap), + mappings: haxmap.New[string, *prop](uintptr(cap)), } } // len returns the number of PIDs func (m *pidMap) len() int { - return int(m.size.Load()) + return int(m.mappings.Len()) } // get retrieves a pid by its address func (m *pidMap) get(path *Path) (pid PID, ok bool) { - m.mu.RLock() - prop, ok := m.propsMap[path.String()] + prop, ok := m.mappings.Get(path.String()) if prop != nil { pid = prop.pid ok = true } - m.mu.RUnlock() return } // set sets a pid in the map func (m *pidMap) set(pid PID) { - m.mu.Lock() if pid != nil { var rtype reflect.Type handle := pid.ActorHandle() @@ -77,37 +71,43 @@ func (m *pidMap) set(pid PID) { rtype = types.RuntimeTypeOf(handle) } - m.propsMap[pid.ActorPath().String()] = &prop{ + m.mappings.Set(pid.ActorPath().String(), &prop{ pid: pid, rtype: rtype, - } - m.size.Add(1) - m.mu.Unlock() + }) } } // delete removes a pid from the map func (m *pidMap) delete(addr *Path) { - m.mu.Lock() - delete(m.propsMap, addr.String()) - m.size.Add(-1) - m.mu.Unlock() + m.mappings.Del(addr.String()) } // pids returns all actors as a slice func (m *pidMap) pids() []PID { - m.mu.Lock() var out []PID - for _, prop := range m.propsMap { + m.mappings.ForEach(func(_ string, prop *prop) bool { + if len(out) == int(m.mappings.Len()) { + return false + } out = append(out, prop.pid) - } - m.mu.Unlock() + return true + }) return out } func (m *pidMap) props() map[string]*prop { - m.mu.Lock() - out := m.propsMap - m.mu.Unlock() + out := make(map[string]*prop, m.mappings.Len()) + m.mappings.ForEach(func(key string, prop *prop) bool { + if len(out) == int(m.mappings.Len()) { + return false + } + out[key] = prop + return true + }) return out } + +func (m *pidMap) close() { + m.mappings.Clear() +} diff --git a/actors/scheduler_test.go b/actors/scheduler_test.go index 601869ec..1275ee7e 100644 --- a/actors/scheduler_test.go +++ b/actors/scheduler_test.go @@ -73,7 +73,8 @@ func TestScheduler(t *testing.T) { time.Sleep(time.Second) typedSystem := newActorSystem.(*actorSystem) - keys := typedSystem.scheduler.quartzScheduler.GetJobKeys() + keys, err := typedSystem.scheduler.quartzScheduler.GetJobKeys() + require.NoError(t, err) assert.Empty(t, keys) assert.EqualValues(t, 1, actor.counter.Load()) assert.EqualValues(t, 1, actor.counter.Load()) @@ -152,7 +153,8 @@ func TestScheduler(t *testing.T) { time.Sleep(time.Second) typedSystem := newActorSystem.(*actorSystem) // for test purpose only - keys := typedSystem.scheduler.quartzScheduler.GetJobKeys() + keys, err := typedSystem.scheduler.quartzScheduler.GetJobKeys() + require.NoError(t, err) assert.Empty(t, keys) assert.EqualValues(t, 1, actor.counter.Load()) assert.EqualValues(t, 1, actor.counter.Load()) diff --git a/discovery/kubernetes/config.go b/discovery/kubernetes/config.go index b04542ad..4046c88f 100644 --- a/discovery/kubernetes/config.go +++ b/discovery/kubernetes/config.go @@ -38,8 +38,8 @@ type Config struct { GossipPortName string // RemotingPortName specifies the remoting port name RemotingPortName string - // ClusterPortName specifies the cluster port name - ClusterPortName string + // PeersPortName specifies the cluster port name + PeersPortName string // ActorSystemName specifies the given actor system name ActorSystemName string } @@ -50,7 +50,7 @@ func (x Config) Validate() error { AddValidator(validation.NewEmptyStringValidator("Namespace", x.Namespace)). AddValidator(validation.NewEmptyStringValidator("ApplicationName", x.ApplicationName)). AddValidator(validation.NewEmptyStringValidator("GossipPortName", x.GossipPortName)). - AddValidator(validation.NewEmptyStringValidator("ClusterPortName", x.ClusterPortName)). + AddValidator(validation.NewEmptyStringValidator("PeersPortName", x.PeersPortName)). AddValidator(validation.NewEmptyStringValidator("RemotingPortName", x.RemotingPortName)). AddValidator(validation.NewEmptyStringValidator("ActorSystemName", x.ActorSystemName)). Validate() diff --git a/discovery/kubernetes/config_test.go b/discovery/kubernetes/config_test.go index 5683ff94..d156672b 100644 --- a/discovery/kubernetes/config_test.go +++ b/discovery/kubernetes/config_test.go @@ -37,7 +37,7 @@ func TestConfig(t *testing.T) { ApplicationName: "applicationName", GossipPortName: "gossipName", RemotingPortName: "remotingName", - ClusterPortName: "clusterPortName", + PeersPortName: "peersPortName", ActorSystemName: "actorSys", } assert.NoError(t, config.Validate()) @@ -48,7 +48,7 @@ func TestConfig(t *testing.T) { ApplicationName: "applicationName", GossipPortName: "", RemotingPortName: "remotingName", - ClusterPortName: "clusterPortName", + PeersPortName: "peersPortName", ActorSystemName: "actorSys", } assert.Error(t, config.Validate()) diff --git a/discovery/kubernetes/discovery.go b/discovery/kubernetes/discovery.go index 0d01af89..b0244e07 100644 --- a/discovery/kubernetes/discovery.go +++ b/discovery/kubernetes/discovery.go @@ -147,7 +147,7 @@ func (d *Discovery) DiscoverPeers() ([]string, error) { return nil, err } - validPortNames := []string{d.config.ClusterPortName, d.config.GossipPortName, d.config.RemotingPortName} + validPortNames := []string{d.config.PeersPortName, d.config.GossipPortName, d.config.RemotingPortName} // define the addresses list addresses := goset.NewSet[string]() diff --git a/discovery/kubernetes/discovery_test.go b/discovery/kubernetes/discovery_test.go index 93fd1f3a..53e37b45 100644 --- a/discovery/kubernetes/discovery_test.go +++ b/discovery/kubernetes/discovery_test.go @@ -41,7 +41,7 @@ import ( const ( gossipPortName = "gossip-port" - clusterPortName = "cluster-port" + peersPortName = "peers-port" remotingPortName = "remoting-port" ) @@ -79,7 +79,7 @@ func TestDiscovery(t *testing.T) { ApplicationName: "test", GossipPortName: gossipPortName, RemotingPortName: remotingPortName, - ClusterPortName: clusterPortName, + PeersPortName: peersPortName, } // create some bunch of mock pods @@ -103,7 +103,7 @@ func TestDiscovery(t *testing.T) { ContainerPort: 3379, }, { - Name: clusterPortName, + Name: peersPortName, ContainerPort: 3380, }, { @@ -147,7 +147,7 @@ func TestDiscovery(t *testing.T) { ContainerPort: 3379, }, { - Name: clusterPortName, + Name: peersPortName, ContainerPort: 3380, }, { @@ -215,7 +215,7 @@ func TestDiscovery(t *testing.T) { ApplicationName: applicationName, GossipPortName: gossipPortName, RemotingPortName: remotingPortName, - ClusterPortName: clusterPortName, + PeersPortName: peersPortName, } // create the instance of provider diff --git a/discovery/nats/discovery_test.go b/discovery/nats/discovery_test.go index 78aa40c5..cb137d00 100644 --- a/discovery/nats/discovery_test.go +++ b/discovery/nats/discovery_test.go @@ -87,7 +87,7 @@ func newPeer(t *testing.T, serverAddr string) *Discovery { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -131,7 +131,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -175,7 +175,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } // create the instance of provider @@ -215,7 +215,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -260,7 +260,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -301,7 +301,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -343,7 +343,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -444,7 +444,7 @@ func TestDiscovery(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } diff --git a/discovery/node.go b/discovery/node.go index c451b689..82f61493 100644 --- a/discovery/node.go +++ b/discovery/node.go @@ -37,15 +37,15 @@ type Node struct { Host string // GossipPort GossipPort int - // ClusterPort - ClusterPort int + // PeersPort + PeersPort int // RemotingPort RemotingPort int } -// ClusterAddress returns address the node's peers will use to connect to -func (n Node) ClusterAddress() string { - return net.JoinHostPort(n.Host, strconv.Itoa(n.ClusterPort)) +// PeersAddress returns address the node's peers will use to connect to +func (n Node) PeersAddress() string { + return net.JoinHostPort(n.Host, strconv.Itoa(n.PeersPort)) } // GossipAddress returns the node discovery address diff --git a/examples/actor-cluster/dnssd/cmd/run.go b/examples/actor-cluster/dnssd/cmd/run.go index 9f7a9cfc..d1fbf796 100644 --- a/examples/actor-cluster/dnssd/cmd/run.go +++ b/examples/actor-cluster/dnssd/cmd/run.go @@ -140,7 +140,7 @@ var runCmd = &cobra.Command{ goakt.WithActorInitMaxRetries(3), goakt.WithTracing(), goakt.WithRemoting(host, int32(config.RemotingPort)), - goakt.WithClustering(disco, 20, config.GossipPort, config.ClusterPort)) + goakt.WithClustering(disco, 20, 1, config.GossipPort, config.PeersPort)) // handle the error if err != nil { logger.Panic(err) diff --git a/examples/actor-cluster/dnssd/service/config.go b/examples/actor-cluster/dnssd/service/config.go index 2cd4c9a4..15fc16d5 100644 --- a/examples/actor-cluster/dnssd/service/config.go +++ b/examples/actor-cluster/dnssd/service/config.go @@ -33,7 +33,7 @@ type Config struct { ActorSystemName string `env:"SYSTEM_NAME"` TraceURL string `env:"TRACE_URL"` GossipPort int `env:"GOSSIP_PORT"` - ClusterPort int `env:"CLUSTER_PORT"` + PeersPort int `env:"CLUSTER_PORT"` RemotingPort int `env:"REMOTING_PORT"` } diff --git a/examples/actor-cluster/k8s/cmd/run.go b/examples/actor-cluster/k8s/cmd/run.go index ed5ba359..18eb9846 100644 --- a/examples/actor-cluster/k8s/cmd/run.go +++ b/examples/actor-cluster/k8s/cmd/run.go @@ -45,7 +45,7 @@ const ( applicationName = "accounts" actorSystemName = "AccountsSystem" gossipPortName = "gossip-port" - clusterPortName = "cluster-port" + peersPortName = "peers-port" remotingPortName = "remoting-port" ) @@ -84,7 +84,7 @@ var runCmd = &cobra.Command{ Namespace: namespace, GossipPortName: gossipPortName, RemotingPortName: remotingPortName, - ClusterPortName: clusterPortName, + PeersPortName: peersPortName, }) // get the port config @@ -100,7 +100,7 @@ var runCmd = &cobra.Command{ goakt.WithLogger(logger), goakt.WithActorInitMaxRetries(3), goakt.WithRemoting(host, int32(config.RemotingPort)), - goakt.WithClustering(disco, 20, config.GossipPort, config.ClusterPort)) + goakt.WithClustering(disco, 20, 1, config.GossipPort, config.ClusterPort)) // handle the error if err != nil { logger.Panic(err) diff --git a/examples/actor-cluster/k8s/k8s.yaml b/examples/actor-cluster/k8s/k8s.yaml index ba42efa5..2374145f 100644 --- a/examples/actor-cluster/k8s/k8s.yaml +++ b/examples/actor-cluster/k8s/k8s.yaml @@ -59,7 +59,7 @@ spec: name: gossip-port protocol: TCP - containerPort: 3320 - name: cluster-port + name: peers-port protocol: TCP env: - name: NODE_NAME @@ -72,7 +72,7 @@ spec: fieldPath: status.podIP - name: GOSSIP_PORT value: "3322" - - name: CLUSTER_PORT + - name: PEERS_PORT value: "3320" - name: REMOTING_PORT value: "50052" diff --git a/go.mod b/go.mod index b9923f68..a79ca79c 100644 --- a/go.mod +++ b/go.mod @@ -3,41 +3,42 @@ module github.com/tochemey/goakt go 1.21 require ( - connectrpc.com/connect v1.16.1 + connectrpc.com/connect v1.16.2 connectrpc.com/otelconnect v0.7.0 - github.com/buraksezer/olric v0.5.6-0.20240205222928-c5efb0d4b5ea + github.com/alphadose/haxmap v1.4.0 + github.com/buraksezer/olric v0.5.6-0.20240510193155-81e12546eb39 github.com/caarlos0/env/v11 v11.0.0 - github.com/cespare/xxhash/v2 v2.3.0 github.com/deckarep/golang-set/v2 v2.6.0 github.com/flowchartsman/retry v1.2.0 github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/grandcat/zeroconf v1.0.0 github.com/joho/godotenv v1.5.1 - github.com/nats-io/nats-server/v2 v2.10.14 - github.com/nats-io/nats.go v1.34.1 + github.com/nats-io/nats-server/v2 v2.10.15 + github.com/nats-io/nats.go v1.35.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/redis/go-redis/v9 v9.5.1 - github.com/reugn/go-quartz v0.11.2 + github.com/reugn/go-quartz v0.12.0 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 github.com/travisjeffery/go-dynaport v1.0.0 - go.opentelemetry.io/otel v1.25.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 - go.opentelemetry.io/otel/exporters/prometheus v0.47.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 - go.opentelemetry.io/otel/metric v1.25.0 - go.opentelemetry.io/otel/sdk v1.25.0 - go.opentelemetry.io/otel/sdk/metric v1.25.0 - go.opentelemetry.io/otel/trace v1.25.0 + github.com/zeebo/xxh3 v1.0.2 + go.opentelemetry.io/otel v1.26.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 + go.opentelemetry.io/otel/exporters/prometheus v0.48.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 + go.opentelemetry.io/otel/metric v1.26.0 + go.opentelemetry.io/otel/sdk v1.26.0 + go.opentelemetry.io/otel/sdk/metric v1.26.0 + go.opentelemetry.io/otel/trace v1.26.0 go.uber.org/atomic v1.11.0 go.uber.org/goleak v1.3.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/net v0.24.0 + golang.org/x/net v0.25.0 golang.org/x/sync v0.7.0 - google.golang.org/protobuf v1.33.0 + google.golang.org/protobuf v1.34.1 k8s.io/api v0.29.4 k8s.io/apimachinery v0.29.4 k8s.io/client-go v0.29.4 @@ -45,55 +46,56 @@ require ( ) require ( - github.com/RoaringBitmap/roaring v1.7.0 // indirect + github.com/RoaringBitmap/roaring v1.9.3 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/buraksezer/consistent v0.10.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect + github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-sockaddr v1.0.6 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/memberlist v0.5.0 // indirect + github.com/hashicorp/memberlist v0.5.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.59 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/nats-io/jwt/v2 v2.5.5 // indirect + github.com/nats-io/jwt/v2 v2.5.7 // indirect github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.15.0 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -102,26 +104,26 @@ require ( github.com/tidwall/redcon v1.6.2 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect - go.opentelemetry.io/proto/otlp v1.1.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/oauth2 v0.17.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.17.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect - google.golang.org/grpc v1.63.0 // indirect + golang.org/x/tools v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect + google.golang.org/grpc v1.64.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index e0e33793..58f9faaf 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -connectrpc.com/connect v1.16.1 h1:rOdrK/RTI/7TVnn3JsVxt3n028MlTRwmK5Q4heSpjis= -connectrpc.com/connect v1.16.1/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw= +connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE= +connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc= connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY= connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= @@ -7,12 +7,14 @@ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy86 github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/RoaringBitmap/roaring v1.6.0/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= -github.com/RoaringBitmap/roaring v1.7.0 h1:OZF303tJCER1Tj3x+aArx/S5X7hrT186ri6JjrGvG68= -github.com/RoaringBitmap/roaring v1.7.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90= +github.com/RoaringBitmap/roaring v1.9.3 h1:t4EbC5qQwnisr5PrP9nt0IRhRTb9gMUgQF4t4S2OByM= +github.com/RoaringBitmap/roaring v1.9.3/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alphadose/haxmap v1.4.0 h1:1yn+oGzy2THJj1DMuJBzRanE3sMnDAjJVbU0L31Jp3w= +github.com/alphadose/haxmap v1.4.0/go.mod h1:rjHw1IAqbxm0S3U5tD16GoKsiAd8FWx5BJ2IYqXwgmM= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= @@ -32,8 +34,8 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buraksezer/consistent v0.10.0 h1:hqBgz1PvNLC5rkWcEBVAL9dFMBWz6I0VgUCW25rrZlU= github.com/buraksezer/consistent v0.10.0/go.mod h1:6BrVajWq7wbKZlTOUPs/XVfR8c0maujuPowduSpZqmw= -github.com/buraksezer/olric v0.5.6-0.20240205222928-c5efb0d4b5ea h1:iThz84rs8fghn9bRJLMxJjT6CAjIa6uCr/B2H6+qocY= -github.com/buraksezer/olric v0.5.6-0.20240205222928-c5efb0d4b5ea/go.mod h1:b1aCKANfqosRKIeYR5NPETD8/VnxcVdlbYGMZ97GPNA= +github.com/buraksezer/olric v0.5.6-0.20240510193155-81e12546eb39 h1:ZB2KxErCucUiYTz9gZlujrurj4WcOe+j4t1sB1okuGw= +github.com/buraksezer/olric v0.5.6-0.20240510193155-81e12546eb39/go.mod h1:b1aCKANfqosRKIeYR5NPETD8/VnxcVdlbYGMZ97GPNA= github.com/caarlos0/env/v11 v11.0.0 h1:ZIlkOjuL3xoZS0kmUJlF74j2Qj8GMOq3CDLX/Viak8Q= github.com/caarlos0/env/v11 v11.0.0/go.mod h1:2RC3HQu8BQqtEK3V4iHPxj0jOdWdbPpWJ6pOueeU1xM= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -47,7 +49,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -55,10 +56,10 @@ github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80N github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= +github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/flowchartsman/retry v1.2.0 h1:qDhlw6RNufXz6RGr+IiYimFpMMkt77SUSHY5tgFaUCU= github.com/flowchartsman/retry v1.2.0/go.mod h1:+sfx8OgCCiAr3t5jh2Gk+T0fRTI+k52edaYxURQxY64= @@ -67,30 +68,26 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -100,23 +97,22 @@ github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvR github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 h1:gpptm606MZYGaMHMsB4Srmb6EbW/IVHnt04rcMXnkBQ= -github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grandcat/zeroconf v1.0.0 h1:uHhahLBKqwWBV6WZUDAT71044vwOTL+McW0mBJvo6kE= github.com/grandcat/zeroconf v1.0.0/go.mod h1:lTKmG1zh86XyCoUeIHSA4FJMBwCJiQmGfcP2PdzytEs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -125,8 +121,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= @@ -142,8 +138,9 @@ github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iP github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/memberlist v0.5.1 h1:mk5dRuzeDNis2bi6LLoQIXfMH7JQvAzt3mQD0vNZZUo= +github.com/hashicorp/memberlist v0.5.1/go.mod h1:zGDXV6AqbDTKTM6yxW0I4+JtFzZAJVoIPvss4hV8F24= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -160,12 +157,13 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -180,8 +178,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= +github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= @@ -200,20 +198,20 @@ github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOl github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt/v2 v2.5.5 h1:ROfXb50elFq5c9+1ztaUbdlrArNFl2+fQWP6B8HGEq4= -github.com/nats-io/jwt/v2 v2.5.5/go.mod h1:ZdWS1nZa6WMZfFwwgpEaqBV8EPGVgOTDHN/wTbz0Y5A= -github.com/nats-io/nats-server/v2 v2.10.14 h1:98gPJFOAO2vLdM0gogh8GAiHghwErrSLhugIqzRC+tk= -github.com/nats-io/nats-server/v2 v2.10.14/go.mod h1:a0TwOVBJZz6Hwv7JH2E4ONdpyFk9do0C18TEwxnHdRk= -github.com/nats-io/nats.go v1.34.1 h1:syWey5xaNHZgicYBemv0nohUPPmaLteiBEUT6Q5+F/4= -github.com/nats-io/nats.go v1.34.1/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= +github.com/nats-io/jwt/v2 v2.5.7 h1:j5lH1fUXCnJnY8SsQeB/a/z9Azgu2bYIDvtPVNdxe2c= +github.com/nats-io/jwt/v2 v2.5.7/go.mod h1:ZdWS1nZa6WMZfFwwgpEaqBV8EPGVgOTDHN/wTbz0Y5A= +github.com/nats-io/nats-server/v2 v2.10.15 h1:O/l+ZT91ltMiiRJKjWLQJcGg7ypzjlb/bC5bFIRVw3M= +github.com/nats-io/nats-server/v2 v2.10.15/go.mod h1:ul+pGt5I7e4U+nI09ZFDG4vqM+6Ce2Tou7UbVSnLiIw= +github.com/nats-io/nats.go v1.35.0 h1:XFNqNM7v5B+MQMKqVGAyHwYhyKb48jrenXNxIU20ULk= +github.com/nats-io/nats.go v1.35.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -227,8 +225,8 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -236,20 +234,20 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek= +github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk= github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= -github.com/reugn/go-quartz v0.11.2 h1:+jc54Ji06n/D/endEPmc+CuG/Jc8466nda1oxtFRrks= -github.com/reugn/go-quartz v0.11.2/go.mod h1:no4ktgYbAAuY0E1SchR8cTx1LF4jYIzdgaQhzRPSkpk= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/reugn/go-quartz v0.12.0 h1:RsrklW++R5Swc7mCPYseXM06PTWN4N7/f1rsYkhHiww= +github.com/reugn/go-quartz v0.12.0/go.mod h1:no4ktgYbAAuY0E1SchR8cTx1LF4jYIzdgaQhzRPSkpk= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -276,7 +274,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -297,27 +294,30 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= -go.opentelemetry.io/otel/exporters/prometheus v0.47.0 h1:OL6yk1Z/pEGdDnrBbxSsH+t4FY1zXfBRGd7bjwhlMLU= -go.opentelemetry.io/otel/exporters/prometheus v0.47.0/go.mod h1:xF3N4OSICZDVbbYZydz9MHFro1RjmkPUKEvar2utG+Q= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= -go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= -go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw= -go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= -go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= -go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= +go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 h1:Waw9Wfpo/IXzOI8bCB7DIk+0JZcqqsyn1JFnAc+iam8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo= +go.opentelemetry.io/otel/exporters/prometheus v0.48.0 h1:sBQe3VNGUjY9IKWQC6z2lNqa5iGbDSxhs60ABwK4y0s= +go.opentelemetry.io/otel/exporters/prometheus v0.48.0/go.mod h1:DtrbMzoZWwQHyrQmCfLam5DZbnmorsGbOtTbYHycU5o= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58= +go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= +go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= +go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/sdk/metric v1.26.0 h1:cWSks5tfriHPdWFnl+qpX3P681aAYqlZHcAyHw5aU9Y= +go.opentelemetry.io/otel/sdk/metric v1.26.0/go.mod h1:ClMFFknnThJCksebJwz7KIyEDHO+nTB6gK8obLy8RyE= +go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= +go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= +go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -333,16 +333,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -351,21 +351,18 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -383,25 +380,20 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -411,27 +403,20 @@ golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= -golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= -google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291 h1:4HZJ3Xv1cmrJ+0aFo304Zn79ur1HMxptAE7aCPNLSqc= +google.golang.org/genproto/googleapis/api v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -456,15 +441,15 @@ k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q= k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= k8s.io/client-go v0.29.4 h1:79ytIedxVfyXV8rpH3jCBW0u+un0fxHDwX5F9K8dPR8= k8s.io/client-go v0.29.4/go.mod h1:kC1thZQ4zQWYwldsfI088BbK6RkxK+aF5ebV8y9Q4tk= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/hash/hasher.go b/hash/hasher.go index e0228e04..de89003c 100644 --- a/hash/hasher.go +++ b/hash/hasher.go @@ -25,7 +25,7 @@ package hash import ( - "github.com/cespare/xxhash/v2" + "github.com/zeebo/xxh3" ) // Hasher defines the hashcode generator interface. @@ -40,7 +40,7 @@ var _ Hasher = defaultHasher{} // HashCode implementation func (x defaultHasher) HashCode(key []byte) uint64 { - return xxhash.Sum64(key) + return xxh3.Hash(key) } // DefaultHasher returns the default hasher diff --git a/internal/cluster/node.go b/internal/cluster/engine.go similarity index 77% rename from internal/cluster/node.go rename to internal/cluster/engine.go index 9455feab..a6c14b4d 100644 --- a/internal/cluster/node.go +++ b/internal/cluster/engine.go @@ -73,9 +73,9 @@ type Event struct { // Interface defines the Node interface type Interface interface { - // Start starts the Node engine + // Start starts the cluster engine Start(ctx context.Context) error - // Stop stops the Node engine + // Stop stops the cluster engine Stop(ctx context.Context) error // NodeHost returns the cluster startNode host address NodeHost() string @@ -99,14 +99,20 @@ type Interface interface { // AdvertisedAddress returns the cluster node cluster address that is known by the // peers in the cluster AdvertisedAddress() string + // Peers returns a channel containing the list of peers at a given time + Peers(ctx context.Context) ([]*Peer, error) } -// Node represents the Node -type Node struct { +// Engine represents the Engine +type Engine struct { // specifies the total number of partitions // the default values is 20 partitionsCount uint64 + // specifies the minimum number of cluster members + // the default values is 1 + minimumPeersQuorum uint16 + // specifies the logger logger log.Logger @@ -142,12 +148,12 @@ type Node struct { } // enforce compilation error -var _ Interface = &Node{} +var _ Interface = &Engine{} -// NewNode creates an instance of cluster Node -func NewNode(name string, disco discovery.Provider, host *discovery.Node, opts ...Option) (*Node, error) { +// NewEngine creates an instance of cluster Engine +func NewEngine(name string, disco discovery.Provider, host *discovery.Node, opts ...Option) (*Engine, error) { // create an instance of the Node - node := &Node{ + engine := &Engine{ partitionsCount: 20, logger: log.DefaultLogger, name: name, @@ -160,30 +166,31 @@ func NewNode(name string, disco discovery.Provider, host *discovery.Node, opts . events: make(chan *Event, 20), messagesReaderChan: make(chan types.Unit, 1), messagesChan: make(chan *redis.Message, 1), + minimumPeersQuorum: 1, } // apply the various options for _, opt := range opts { - opt.Apply(node) + opt.Apply(engine) } // set the host startNode - node.host = host + engine.host = host - return node, nil + return engine, nil } -// Start starts the Node. -func (n *Node) Start(ctx context.Context) error { +// Start starts the Engine. +func (n *Engine) Start(ctx context.Context) error { logger := n.logger - logger.Infof("Starting GoAkt cluster Node service on (%s)....🤔", n.host.ClusterAddress()) + logger.Infof("Starting GoAkt cluster Engine service on host=(%s)....🤔", n.host.PeersAddress()) conf := n.buildConfig() conf.Hasher = &hasherWrapper{n.hasher} m, err := config.NewMemberlistConfig("lan") if err != nil { - logger.Error(errors.Wrap(err, "failed to configure the cluster Node memberlist.💥")) + logger.Error(errors.Wrap(err, "failed to configure the cluster Engine members list.💥")) return err } @@ -213,7 +220,7 @@ func (n *Node) Start(ctx context.Context) error { eng, err := olric.New(conf) if err != nil { - logger.Error(errors.Wrapf(err, "failed to start the cluster Node=(%s).💥", n.name)) + logger.Error(errors.Wrapf(err, "failed to start the cluster Engine on host=(%s)", n.name)) return err } @@ -225,7 +232,7 @@ func (n *Node) Start(ctx context.Context) error { logger.Panic(e) } // the expectation is to exit the application - logger.Fatal(errors.Wrapf(err, "failed to start the cluster Node=(%s).💥", n.name)) + logger.Fatal(errors.Wrapf(err, "failed to start the cluster Engine on host=(%s)", n.name)) } }() @@ -236,7 +243,7 @@ func (n *Node) Start(ctx context.Context) error { n.client = n.server.NewEmbeddedClient() dmp, err := n.client.NewDMap(n.name) if err != nil { - logger.Error(errors.Wrapf(err, "failed to start the cluster Node=(%s).💥", n.name)) + logger.Error(errors.Wrapf(err, "failed to start the cluster Engine on host=(%s)", n.name)) return n.server.Shutdown(ctx) } @@ -245,7 +252,7 @@ func (n *Node) Start(ctx context.Context) error { // create a subscriber to consume to cluster events ps, err := n.client.NewPubSub() if err != nil { - logger.Error(errors.Wrapf(err, "failed to start the cluster Node=(%s).💥", n.name)) + logger.Error(errors.Wrapf(err, "failed to start the cluster Engine on host=(%s)", n.name)) return n.server.Shutdown(ctx) } @@ -253,12 +260,12 @@ func (n *Node) Start(ctx context.Context) error { n.messagesChan = n.pubSub.Channel() go n.consume() - logger.Infof("GoAkt cluster Node=(%s) successfully started. 🎉", n.name) + logger.Infof("GoAkt cluster Engine=(%s) successfully started.", n.name) return nil } -// Stop stops the Node gracefully -func (n *Node) Stop(ctx context.Context) error { +// Stop stops the Engine gracefully +func (n *Engine) Stop(ctx context.Context) error { // create a cancellation context of 1 second timeout ctx, cancelFn := context.WithTimeout(ctx, n.shutdownTimeout) defer cancelFn() @@ -271,19 +278,19 @@ func (n *Node) Stop(ctx context.Context) error { // close the events listener if err := n.pubSub.Close(); err != nil { - logger.Error(errors.Wrap(err, "failed to shutdown the cluster events listener.💥")) + logger.Error(errors.Wrap(err, "failed to shutdown the cluster events listener")) return err } // close the Node client if err := n.client.Close(ctx); err != nil { - logger.Error(errors.Wrapf(err, "failed to shutdown the cluster Node=(%s).💥", n.name)) + logger.Error(errors.Wrapf(err, "failed to shutdown the cluster engine=(%s)", n.name)) return err } // let us stop the server if err := n.server.Shutdown(ctx); err != nil { - logger.Error(errors.Wrapf(err, "failed to Shutdown GoAkt cluster Node=(%s)....💥", n.name)) + logger.Error(errors.Wrapf(err, "failed to shutdown the cluster engine=(%s)", n.name)) return err } @@ -293,59 +300,59 @@ func (n *Node) Stop(ctx context.Context) error { // signal we are stopping listening to events n.messagesReaderChan <- types.Unit{} - logger.Infof("GoAkt cluster Node=(%s) successfully stopped.🎉", n.name) + logger.Infof("GoAkt cluster Node=(%s) successfully stopped.", n.name) return nil } // NodeHost returns the Node Host -func (n *Node) NodeHost() string { +func (n *Engine) NodeHost() string { return n.host.Host } // NodeRemotingPort returns the Node remoting port -func (n *Node) NodeRemotingPort() int { +func (n *Engine) NodeRemotingPort() int { return n.host.RemotingPort } // AdvertisedAddress returns the cluster node cluster address that is known by the // peers in the cluster -func (n *Node) AdvertisedAddress() string { - return n.host.ClusterAddress() +func (n *Engine) AdvertisedAddress() string { + return n.host.PeersAddress() } // PutActor replicates onto the Node the metadata of an actor -func (n *Node) PutActor(ctx context.Context, actor *internalpb.WireActor) error { +func (n *Engine) PutActor(ctx context.Context, actor *internalpb.WireActor) error { ctx, cancelFn := context.WithTimeout(ctx, n.writeTimeout) defer cancelFn() logger := n.logger - logger.Infof("replicating actor (%s).🤔", actor.GetActorName()) + logger.Infof("replicating actor (%s)", actor.GetActorName()) data, err := encode(actor) if err != nil { - logger.Error(errors.Wrapf(err, "failed to persist actor=%s data in the cluster.💥", actor.GetActorName())) + logger.Error(errors.Wrapf(err, "failed to persist actor=%s data in the cluster", actor.GetActorName())) return errors.Wrapf(err, "failed to persist actor=%s data in the cluster", actor.GetActorName()) } err = n.kvStore.Put(ctx, actor.GetActorName(), data) if err != nil { - logger.Error(errors.Wrapf(err, "failed to replicate actor=%s record.💥", actor.GetActorName())) + logger.Error(errors.Wrapf(err, "failed to replicate actor=%s record", actor.GetActorName())) return err } - logger.Infof("actor (%s) successfully replicated in the cluster.🎉", actor.GetActorName()) + logger.Infof("actor (%s) successfully replicated in the cluster", actor.GetActorName()) return nil } // GetActor fetches an actor from the Node -func (n *Node) GetActor(ctx context.Context, actorName string) (*internalpb.WireActor, error) { +func (n *Engine) GetActor(ctx context.Context, actorName string) (*internalpb.WireActor, error) { ctx, cancelFn := context.WithTimeout(ctx, n.readTimeout) defer cancelFn() logger := n.logger - logger.Infof("retrieving actor (%s) from the cluster.🤔", actorName) + logger.Infof("retrieving actor (%s) from the cluster", actorName) resp, err := n.kvStore.Get(ctx, actorName) if err != nil { @@ -353,69 +360,69 @@ func (n *Node) GetActor(ctx context.Context, actorName string) (*internalpb.Wire logger.Warnf("actor=%s is not found in the cluster", actorName) return nil, ErrActorNotFound } - logger.Error(errors.Wrapf(err, "failed to get actor=%s record.💥", actorName)) + logger.Error(errors.Wrapf(err, "failed to get actor=%s record", actorName)) return nil, err } bytea, err := resp.Byte() if err != nil { - logger.Error(errors.Wrapf(err, "failed to read the record at:{%s}.💥", actorName)) + logger.Error(errors.Wrapf(err, "failed to read the record at:{%s}", actorName)) return nil, err } actor, err := decode(bytea) if err != nil { - logger.Error(errors.Wrapf(err, "failed to decode actor=%s record.💥", actorName)) + logger.Error(errors.Wrapf(err, "failed to decode actor=%s record", actorName)) return nil, err } - logger.Infof("actor (%s) successfully retrieved from the cluster.🎉", actor.GetActorName()) + logger.Infof("actor (%s) successfully retrieved from the cluster", actor.GetActorName()) return actor, nil } // RemoveActor removes a given actor from the cluster. // An actor is removed from the cluster when this actor has been passivated. -func (n *Node) RemoveActor(ctx context.Context, actorName string) error { +func (n *Engine) RemoveActor(ctx context.Context, actorName string) error { logger := n.logger - logger.Infof("removing actor (%s).🤔", actorName) + logger.Infof("removing actor (%s)", actorName) _, err := n.kvStore.Delete(ctx, actorName) if err != nil { - logger.Error(errors.Wrapf(err, "failed to remove actor=%s record.💥", actorName)) + logger.Error(errors.Wrapf(err, "failed to remove actor=%s record", actorName)) return err } - logger.Infof("actor (%s) successfully removed from the cluster.🎉", actorName) + logger.Infof("actor (%s) successfully removed from the cluster", actorName) return nil } // SetKey sets a given key to the cluster -func (n *Node) SetKey(ctx context.Context, key string) error { +func (n *Engine) SetKey(ctx context.Context, key string) error { ctx, cancelFn := context.WithTimeout(ctx, n.writeTimeout) defer cancelFn() logger := n.logger - logger.Infof("replicating key (%s).🤔", key) + logger.Infof("replicating key (%s)", key) if err := n.kvStore.Put(ctx, key, true); err != nil { logger.Error(errors.Wrapf(err, "failed to replicate key=%s record.💥", key)) return err } - logger.Infof("key (%s) successfully replicated.🎉", key) + logger.Infof("key (%s) successfully replicated", key) return nil } // KeyExists checks the existence of a given key -func (n *Node) KeyExists(ctx context.Context, key string) (bool, error) { +func (n *Engine) KeyExists(ctx context.Context, key string) (bool, error) { ctx, cancelFn := context.WithTimeout(ctx, n.readTimeout) defer cancelFn() logger := n.logger - logger.Infof("checking key (%s) existence in the cluster.🤔", key) + logger.Infof("checking key (%s) existence in the cluster", key) resp, err := n.kvStore.Get(ctx, key) if err != nil { @@ -424,14 +431,14 @@ func (n *Node) KeyExists(ctx context.Context, key string) (bool, error) { return false, nil } - logger.Error(errors.Wrapf(err, "failed to check key=%s existence.💥", key)) + logger.Error(errors.Wrapf(err, "failed to check key=%s existence", key)) return false, err } return resp.Bool() } // GetPartition returns the partition where a given actor is stored -func (n *Node) GetPartition(actorName string) int { +func (n *Engine) GetPartition(actorName string) int { key := []byte(actorName) hkey := n.hasher.HashCode(key) partition := int(hkey % n.partitionsCount) @@ -440,13 +447,31 @@ func (n *Node) GetPartition(actorName string) int { } // Events returns a channel where cluster events are published -func (n *Node) Events() <-chan *Event { +func (n *Engine) Events() <-chan *Event { return n.events } +// Peers returns a channel containing the list of peers at a given time +func (n *Engine) Peers(ctx context.Context) ([]*Peer, error) { + members, err := n.client.Members(ctx) + if err != nil { + n.logger.Error(errors.Wrap(err, "failed to read cluster peers")) + return nil, err + } + + peers := make([]*Peer, 0, len(members)) + for _, member := range members { + if member.Name != n.AdvertisedAddress() { + n.logger.Debugf("node=(%s) has found peer=(%s)", n.AdvertisedAddress(), member.Name) + peers = append(peers, &Peer{Address: member.Name, Leader: member.Coordinator}) + } + } + return peers, nil +} + // consume reads to the underlying cluster events // and emit the event -func (n *Node) consume() { +func (n *Engine) consume() { for { select { case <-n.messagesReaderChan: @@ -518,7 +543,7 @@ func (n *Node) consume() { } // buildConfig builds the Node configuration -func (n *Node) buildConfig() *config.Config { +func (n *Engine) buildConfig() *config.Config { // define the log level logLevel := "INFO" switch n.logger.LogLevel() { @@ -535,12 +560,12 @@ func (n *Node) buildConfig() *config.Config { // create the config and return it conf := &config.Config{ BindAddr: n.host.Host, - BindPort: n.host.ClusterPort, + BindPort: n.host.PeersPort, ReadRepair: true, - ReplicaCount: config.MinimumReplicaCount, - WriteQuorum: config.DefaultWriteQuorum, - ReadQuorum: config.DefaultReadQuorum, - MemberCountQuorum: config.DefaultMemberCountQuorum, + ReplicaCount: int(n.minimumPeersQuorum), + WriteQuorum: int(n.minimumPeersQuorum), + ReadQuorum: int(n.minimumPeersQuorum), + MemberCountQuorum: int32(n.minimumPeersQuorum), Peers: []string{}, DMaps: &config.DMaps{}, KeepAlivePeriod: config.DefaultKeepAlivePeriod, @@ -554,6 +579,7 @@ func (n *Node) buildConfig() *config.Config { LogOutput: newLogWriter(n.logger), EnableClusterEventsChannel: true, Hasher: hasher.NewDefaultHasher(), + TriggerBalancerInterval: config.DefaultTriggerBalancerInterval, } // set verbosity when debug is enabled diff --git a/internal/cluster/node_test.go b/internal/cluster/engine_test.go similarity index 92% rename from internal/cluster/node_test.go rename to internal/cluster/engine_test.go index 01676a7e..578fa278 100644 --- a/internal/cluster/node_test.go +++ b/internal/cluster/engine_test.go @@ -79,12 +79,12 @@ func TestSingleNode(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } logger := log.New(log.ErrorLevel, os.Stdout) - cluster, err := NewNode("test", provider, &hostNode, WithLogger(logger)) + cluster, err := NewEngine("test", provider, &hostNode, WithLogger(logger)) require.NotNil(t, cluster) require.NoError(t, err) @@ -134,11 +134,11 @@ func TestSingleNode(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } - cluster, err := NewNode("test", provider, &hostNode) + cluster, err := NewEngine("test", provider, &hostNode) require.NotNil(t, cluster) require.NoError(t, err) @@ -204,11 +204,11 @@ func TestSingleNode(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } - cluster, err := NewNode("test", provider, &hostNode) + cluster, err := NewEngine("test", provider, &hostNode) require.NotNil(t, cluster) require.NoError(t, err) @@ -267,12 +267,12 @@ func TestSingleNode(t *testing.T) { Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } logger := log.New(log.WarningLevel, os.Stdout) - cluster, err := NewNode("test", provider, &hostNode, WithLogger(logger)) + cluster, err := NewEngine("test", provider, &hostNode, WithLogger(logger)) require.NotNil(t, cluster) require.NoError(t, err) @@ -314,14 +314,14 @@ func TestMultipleNodes(t *testing.T) { srv := startNatsServer(t) // create a cluster node1 - node1, sd1 := startNode(t, "node1", srv.Addr().String()) + node1, sd1 := startEngine(t, "node1", srv.Addr().String()) require.NotNil(t, node1) // wait for the node to start properly time.Sleep(2 * time.Second) // create a cluster node1 - node2, sd2 := startNode(t, "node2", srv.Addr().String()) + node2, sd2 := startEngine(t, "node2", srv.Addr().String()) require.NotNil(t, node2) node2Addr := node2.AdvertisedAddress() @@ -353,6 +353,10 @@ L: require.True(t, ok) require.NotNil(t, nodeJoined) require.Equal(t, node2Addr, nodeJoined.GetAddress()) + peers, err := node1.Peers(context.TODO()) + require.NoError(t, err) + require.Len(t, peers, 1) + require.Equal(t, node2Addr, peers[0].Address) // wait for some time time.Sleep(time.Second) @@ -419,7 +423,7 @@ func startNatsServer(t *testing.T) *natsserver.Server { return serv } -func startNode(t *testing.T, nodeName, serverAddr string) (*Node, discovery.Provider) { +func startEngine(t *testing.T, nodeName, serverAddr string) (*Engine, discovery.Provider) { // create a context ctx := context.TODO() @@ -448,7 +452,7 @@ func startNode(t *testing.T, nodeName, serverAddr string) (*Node, discovery.Prov Name: host, Host: host, GossipPort: gossipPort, - ClusterPort: clusterPort, + PeersPort: clusterPort, RemotingPort: remotingPort, } @@ -456,13 +460,13 @@ func startNode(t *testing.T, nodeName, serverAddr string) (*Node, discovery.Prov provider := nats.NewDiscovery(&config, &hostNode) // create the startNode - node, err := NewNode(nodeName, provider, &hostNode) + engine, err := NewEngine(nodeName, provider, &hostNode) require.NoError(t, err) - require.NotNil(t, node) + require.NotNil(t, engine) // start the node - require.NoError(t, node.Start(ctx)) + require.NoError(t, engine.Start(ctx)) // return the cluster startNode - return node, provider + return engine, provider } diff --git a/internal/cluster/hasher.go b/internal/cluster/hasher.go index a9cb4672..a25dc23f 100644 --- a/internal/cluster/hasher.go +++ b/internal/cluster/hasher.go @@ -35,7 +35,7 @@ type hasherWrapper struct { } // enforce compilation error -var _ hasher.Hasher = &hasherWrapper{} +var _ hasher.Hasher = (*hasherWrapper)(nil) // Sum64 implementation func (x hasherWrapper) Sum64(key []byte) uint64 { diff --git a/internal/cluster/option.go b/internal/cluster/option.go index 8b9ba59c..f1f4fe0c 100644 --- a/internal/cluster/option.go +++ b/internal/cluster/option.go @@ -34,59 +34,66 @@ import ( // Option is the interface that applies a configuration option. type Option interface { // Apply sets the Option value of a config. - Apply(cl *Node) + Apply(cl *Engine) } var _ Option = OptionFunc(nil) // OptionFunc implements the Option interface. -type OptionFunc func(cl *Node) +type OptionFunc func(eng *Engine) // Apply applies the Node's option -func (f OptionFunc) Apply(c *Node) { +func (f OptionFunc) Apply(c *Engine) { f(c) } // WithPartitionsCount sets the total number of partitions func WithPartitionsCount(count uint64) Option { - return OptionFunc(func(cl *Node) { - cl.partitionsCount = count + return OptionFunc(func(eng *Engine) { + eng.partitionsCount = count }) } // WithLogger sets the logger func WithLogger(logger log.Logger) Option { - return OptionFunc(func(cl *Node) { - cl.logger = logger + return OptionFunc(func(eng *Engine) { + eng.logger = logger }) } // WithWriteTimeout sets the Node write timeout. // This timeout specifies the timeout of a data replication func WithWriteTimeout(timeout time.Duration) Option { - return OptionFunc(func(cl *Node) { - cl.writeTimeout = timeout + return OptionFunc(func(eng *Engine) { + eng.writeTimeout = timeout }) } // WithReadTimeout sets the Node read timeout. // This timeout specifies the timeout of a data retrieval func WithReadTimeout(timeout time.Duration) Option { - return OptionFunc(func(cl *Node) { - cl.readTimeout = timeout + return OptionFunc(func(eng *Engine) { + eng.readTimeout = timeout }) } // WithShutdownTimeout sets the Node shutdown timeout. func WithShutdownTimeout(timeout time.Duration) Option { - return OptionFunc(func(cl *Node) { - cl.shutdownTimeout = timeout + return OptionFunc(func(eng *Engine) { + eng.shutdownTimeout = timeout }) } // WithHasher sets the custom hasher func WithHasher(hasher hash.Hasher) Option { - return OptionFunc(func(cl *Node) { - cl.hasher = hasher + return OptionFunc(func(eng *Engine) { + eng.hasher = hasher + }) +} + +// WithMinimumPeersQuorum sets the minimum number of nodes to form a quorum +func WithMinimumPeersQuorum(count uint16) Option { + return OptionFunc(func(eng *Engine) { + eng.minimumPeersQuorum = count }) } diff --git a/internal/cluster/option_test.go b/internal/cluster/option_test.go index 92837082..cae15696 100644 --- a/internal/cluster/option_test.go +++ b/internal/cluster/option_test.go @@ -39,43 +39,49 @@ func TestOptions(t *testing.T) { testCases := []struct { name string option Option - expected Node + expected Engine }{ { name: "WithPartitionsCount", option: WithPartitionsCount(2), - expected: Node{partitionsCount: 2}, + expected: Engine{partitionsCount: 2}, }, { name: "WithLogger", option: WithLogger(log.DefaultLogger), - expected: Node{logger: log.DefaultLogger}, + expected: Engine{logger: log.DefaultLogger}, }, { name: "WithWriteTimeout", option: WithWriteTimeout(2 * time.Minute), - expected: Node{writeTimeout: 2 * time.Minute}, + expected: Engine{writeTimeout: 2 * time.Minute}, }, { name: "WithReadTimeout", option: WithReadTimeout(2 * time.Minute), - expected: Node{readTimeout: 2 * time.Minute}, + expected: Engine{readTimeout: 2 * time.Minute}, }, { name: "WithShutdownTimeout", option: WithShutdownTimeout(2 * time.Minute), - expected: Node{shutdownTimeout: 2 * time.Minute}, + expected: Engine{shutdownTimeout: 2 * time.Minute}, }, { name: "WithHasher", option: WithHasher(mockHasher), - expected: Node{hasher: mockHasher}, + expected: Engine{hasher: mockHasher}, + }, + + { + name: "WithMinimumNodes", + option: WithMinimumPeersQuorum(3), + expected: Engine{minimumPeersQuorum: 3}, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - var cl Node + var cl Engine tc.option.Apply(&cl) assert.Equal(t, tc.expected, cl) }) diff --git a/internal/cluster/peer.go b/internal/cluster/peer.go new file mode 100644 index 00000000..8473f800 --- /dev/null +++ b/internal/cluster/peer.go @@ -0,0 +1,35 @@ +/* + * MIT License + * + * Copyright (c) 2022-2024 Tochemey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package cluster + +// Peer defines the peer info +type Peer struct { + // Address represents the peer address. It is also the host:port of the peer + Address string + // Leader states that the given peer is the leader not. + // A peer is a leader when it is the oldest node in the cluster + Leader bool +} diff --git a/internal/types/registry.go b/internal/types/registry.go index 9acb85a8..5d0ba23f 100644 --- a/internal/types/registry.go +++ b/internal/types/registry.go @@ -27,11 +27,9 @@ package types import ( "reflect" "strings" - "sync" -) -// Map defines mapping between a type name and its runtime type -type Map map[string]reflect.Type + "github.com/alphadose/haxmap" +) // Registry defines the types registry interface type Registry interface { @@ -42,7 +40,7 @@ type Registry interface { // Exists return true when a given object is in the registry Exists(v any) bool // TypesMap returns the list of registered at any point in time - TypesMap() Map + TypesMap() map[string]reflect.Type // Type returns the type of object Type(v any) (reflect.Type, bool) // TypeOf returns the type of an object name @@ -50,8 +48,7 @@ type Registry interface { } type registry struct { - typesMap Map - mu *sync.RWMutex + typesMap *haxmap.Map[string, reflect.Type] } var _ Registry = (*registry)(nil) @@ -59,58 +56,53 @@ var _ Registry = (*registry)(nil) // NewRegistry creates a new types registry func NewRegistry() Registry { return ®istry{ - typesMap: Map{}, - mu: new(sync.RWMutex), + // TODO need to check with memory footprint here since we change the map engine + typesMap: haxmap.New[string, reflect.Type](100), } } // Deregister removes the registered object from the registry func (r *registry) Deregister(v any) { - r.mu.Lock() name, _ := nameAndTypeOf(v) - delete(r.typesMap, name) - r.mu.Unlock() + r.typesMap.Del(name) } // Exists return true when a given object is in the registry func (r *registry) Exists(v any) bool { - r.mu.RLock() name, _ := nameAndTypeOf(v) - _, ok := r.typesMap[name] - r.mu.RUnlock() + _, ok := r.typesMap.Get(name) return ok } // TypesMap returns the list of registered at any point in time -func (r *registry) TypesMap() Map { - r.mu.Lock() - out := r.typesMap - r.mu.Unlock() +func (r *registry) TypesMap() map[string]reflect.Type { + out := make(map[string]reflect.Type, r.typesMap.Len()) + r.typesMap.ForEach(func(s string, t reflect.Type) bool { + if len(out) == int(r.typesMap.Len()) { + return false + } + out[s] = t + return true + }) return out } // Register an object func (r *registry) Register(v any) { - r.mu.Lock() name, rtype := nameAndTypeOf(v) - r.typesMap[name] = rtype - r.mu.Unlock() + r.typesMap.Set(name, rtype) } // Type returns the type of object func (r *registry) Type(v any) (reflect.Type, bool) { - r.mu.RLock() name, _ := nameAndTypeOf(v) - out, ok := r.typesMap[name] - r.mu.RUnlock() + out, ok := r.typesMap.Get(name) return out, ok } // TypeOf returns the type of an object name func (r *registry) TypeOf(name string) (reflect.Type, bool) { - r.mu.RLock() - out, ok := r.typesMap[strings.ToLower(name)] - r.mu.RUnlock() + out, ok := r.typesMap.Get(strings.ToLower(name)) return out, ok } diff --git a/mocks/cluster/interface.go b/mocks/cluster/interface.go index 99ab3cce..e1c2d385 100644 --- a/mocks/cluster/interface.go +++ b/mocks/cluster/interface.go @@ -340,6 +340,60 @@ func (_c *Interface_NodeRemotingPort_Call) RunAndReturn(run func() int) *Interfa return _c } +// Peers provides a mock function with given fields: ctx +func (_m *Interface) Peers(ctx context.Context) ([]*internalcluster.Peer, error) { + ret := _m.Called(ctx) + + var r0 []*internalcluster.Peer + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*internalcluster.Peer, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []*internalcluster.Peer); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*internalcluster.Peer) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Interface_Peers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Peers' +type Interface_Peers_Call struct { + *mock.Call +} + +// Peers is a helper method to define mock.On call +// - ctx context.Context +func (_e *Interface_Expecter) Peers(ctx interface{}) *Interface_Peers_Call { + return &Interface_Peers_Call{Call: _e.mock.On("Peers", ctx)} +} + +func (_c *Interface_Peers_Call) Run(run func(ctx context.Context)) *Interface_Peers_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *Interface_Peers_Call) Return(_a0 []*internalcluster.Peer, _a1 error) *Interface_Peers_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Interface_Peers_Call) RunAndReturn(run func(context.Context) ([]*internalcluster.Peer, error)) *Interface_Peers_Call { + _c.Call.Return(run) + return _c +} + // PutActor provides a mock function with given fields: ctx, actor func (_m *Interface) PutActor(ctx context.Context, actor *internalpb.WireActor) error { ret := _m.Called(ctx, actor) diff --git a/mocks/cluster/option.go b/mocks/cluster/option.go index cedc8e36..18b8e368 100644 --- a/mocks/cluster/option.go +++ b/mocks/cluster/option.go @@ -21,7 +21,7 @@ func (_m *Option) EXPECT() *Option_Expecter { } // Apply provides a mock function with given fields: cl -func (_m *Option) Apply(cl *internalcluster.Node) { +func (_m *Option) Apply(cl *internalcluster.Engine) { _m.Called(cl) } @@ -31,14 +31,14 @@ type Option_Apply_Call struct { } // Apply is a helper method to define mock.On call -// - cl *internalcluster.Node +// - cl *internalcluster.Engine func (_e *Option_Expecter) Apply(cl interface{}) *Option_Apply_Call { return &Option_Apply_Call{Call: _e.mock.On("Apply", cl)} } -func (_c *Option_Apply_Call) Run(run func(cl *internalcluster.Node)) *Option_Apply_Call { +func (_c *Option_Apply_Call) Run(run func(cl *internalcluster.Engine)) *Option_Apply_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*internalcluster.Node)) + run(args[0].(*internalcluster.Engine)) }) return _c } @@ -48,7 +48,7 @@ func (_c *Option_Apply_Call) Return() *Option_Apply_Call { return _c } -func (_c *Option_Apply_Call) RunAndReturn(run func(*internalcluster.Node)) *Option_Apply_Call { +func (_c *Option_Apply_Call) RunAndReturn(run func(*internalcluster.Engine)) *Option_Apply_Call { _c.Call.Return(run) return _c } diff --git a/mocks/cluster/option_func.go b/mocks/cluster/option_func.go index c8ba57a7..a028f2bf 100644 --- a/mocks/cluster/option_func.go +++ b/mocks/cluster/option_func.go @@ -20,9 +20,9 @@ func (_m *OptionFunc) EXPECT() *OptionFunc_Expecter { return &OptionFunc_Expecter{mock: &_m.Mock} } -// Execute provides a mock function with given fields: cl -func (_m *OptionFunc) Execute(cl *internalcluster.Node) { - _m.Called(cl) +// Execute provides a mock function with given fields: eng +func (_m *OptionFunc) Execute(eng *internalcluster.Engine) { + _m.Called(eng) } // OptionFunc_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute' @@ -31,14 +31,14 @@ type OptionFunc_Execute_Call struct { } // Execute is a helper method to define mock.On call -// - cl *internalcluster.Node -func (_e *OptionFunc_Expecter) Execute(cl interface{}) *OptionFunc_Execute_Call { - return &OptionFunc_Execute_Call{Call: _e.mock.On("Execute", cl)} +// - eng *internalcluster.Engine +func (_e *OptionFunc_Expecter) Execute(eng interface{}) *OptionFunc_Execute_Call { + return &OptionFunc_Execute_Call{Call: _e.mock.On("Execute", eng)} } -func (_c *OptionFunc_Execute_Call) Run(run func(cl *internalcluster.Node)) *OptionFunc_Execute_Call { +func (_c *OptionFunc_Execute_Call) Run(run func(eng *internalcluster.Engine)) *OptionFunc_Execute_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*internalcluster.Node)) + run(args[0].(*internalcluster.Engine)) }) return _c } @@ -48,7 +48,7 @@ func (_c *OptionFunc_Execute_Call) Return() *OptionFunc_Execute_Call { return _c } -func (_c *OptionFunc_Execute_Call) RunAndReturn(run func(*internalcluster.Node)) *OptionFunc_Execute_Call { +func (_c *OptionFunc_Execute_Call) RunAndReturn(run func(*internalcluster.Engine)) *OptionFunc_Execute_Call { _c.Call.Return(run) return _c } diff --git a/protos/internal/remoting.proto b/protos/internal/remoting.proto index 8354d703..d4e161e1 100644 --- a/protos/internal/remoting.proto +++ b/protos/internal/remoting.proto @@ -11,6 +11,8 @@ option go_package = "github.com/tochemey/goakt/internal/internalpb;internalpb"; // With remoting one can: // - send messages to actors // - lookup actor remotely +// - spawn actor remotely +// - stop actor remotely service RemotingService { // RemoteAsk is used to send a message to an actor remotely and expect a response immediately. rpc RemoteAsk(stream RemoteAskRequest) returns (stream RemoteAskResponse);