Closed thrawn01 closed 7 months ago
This is ready for review. @udhos, @gedw99 @Tochemey @Jvb182 @Baliedge
I've created a repo for discovery mechanisms anyone should wish to add. https://github.com/groupcache/discovery-go
can we put the
data
package into theinternal
package? Are we planning to offer some custom serialization?
@thrawn01 never mind. I have seen the reason why we cannot put into an internal package.
@thrawn01 if you are ok I can pull the PR and made some changes. However I hope my recommendations on the PR make sense.
@thrawn01 I cannot find the discovery interface and how it is used.
The discovery implementations will just call SetPeers()
when the peer topology changes.
I took the feed back about the data package and figured out way to remove it. Now a typical user will only need the groupcache
and transport
packages to use groupcache.
I like this new package layout much more than what I had previously!
@thrawn01 kindly merge it. LGTM
I've implemented all the feed back I give a 👍 to and added comments to others. Thank you all for the your time and great comments!
@thrawn01 is there anything we need before merging the PR? If I can help, kindly let me know
I was hoping for the other interested parties to review. If I don't get anything after Monday I'll merge. However I want to make one more follow up change to add support for different cache implementations before releasing V3.
I've been testing https://maypok86.github.io/otter/ and have been impressed with its performance. We should provide an option to use such implementations in groupcache.
yeah I have seen Otter. Thanks for looking at it. So you want to add some of sort of API to allow custom cache implementation. That will be a great feature.
@thrawn01. I have been thinking lately about how does the V3 handle network topology changes. Are we planning to support split-brain syndrome? Is there any plan for rebalancing?.
Discovery, split brain and rebalancing is beyond the scope of groupcache core.
However, If some third-party wanted to support such a thing it would be possible using the new transport interface and discovery.
Purpose
Implementation
Instance
struct which represents a single groupcache instance. In this way, a single application can instantiate multiple instances. An instance encapsulates cache state, unlike v2 of groupcache which stored everything in global state.cluster
package to simplify running an instance of groupcache and to act as an in code example of how to start and run an instance of groupcache withHTTP
as the transport.log/slog
the library will only support golang version1.21
and above.RegisterServerStart()
,RegisterNewGroupHook
andRegisterPerGroupPeerPicker
as I couldn't find a single instance on github of anyone using these functions.panic()
where it makes senseconsistenthash
topeer
as a place for all shared peer codePeerPicker()
intopeer
so consistent hash lookups avoid and additional map lookup after finding the key in the hash. This also allows calls toSetPeer()
to endure blocking calls toTransport.NewClient()
without locking the groupcache instance until a new picker is instantiated and ready.cluster
package to start and stop groupcache clusters for testingslog
for loggingexample_pb_test.go
CHANGELOG
in favor of github release notesbuf
to generate protobuf files; removedproto.sh
groupcachepb
totransport/pb
transport
packagetransport
package, movedByteView
andSink
to thetransport
package.transport.ByteViewFrom()
method to simplify instantiation of aByteView
without providing public access toByteView.e
andByteView.b
variables. As opposed to creatingNewByteView()
which implies the created byte view is a pointer to a New instance on the heap. NOTE:ByteView
is intended to be used by value and not by reference.transport.GroupCacheInstance
andtransport.Group
interfaces to provide access to methodstransport
needs access too, but should not be accessed by users.groupcache.go
into several different files.See #1
Example Usage
Code Map
This is also available in the README.md
groupcache.Instance
Represents an instance of groupcache. With the instance, you can create new groups and add other instances to your cluster by calling
Instance.SetPeers()
. Each instance communicates with other peers through the transport that is passed in during creation. TheInstance.SetPeers()
callsTransport.NewClient()
for eachpeer.Info
struct provided toSetPeers()
. It is up to the transport implementation to create a client which is appropriate for communicating with the peer described by the providedpeer.Info
struct.It is up to the caller to ensure
Instance.SetPeers()
is called with a valid set of peers. Callers may want to use a peer discovery mechanism to discover and update when the peer topology changes.SetPeers()
is designed to be called at any point duringgroupcache.Instance
operation as peers leave or join the cluster.If
SetPeers()
is not called, then thegroupcache.Instance
will operate as a local only cache.groupcache.Daemon
This is a convenience struct which encapsulates a
groupcache.Instance
to simplify starting and stopping an instance and the associated transport. Callinggroupcache.SpawnDaemon()
callsTransport.SpawnTransport()
on the provided transport to listen for incoming requests.groupcache.Group
Holds the cache that makes up the "group" which can be shared with other instances of group cache. Each
groupcache.Instance
must create the same group using the same group name. Group names are how a "group" cache is accessed by other peers in the cluster.transport.Transport
Is an interface which is used to communicate with other peers in the cluster. The groupcache project provides
transport.HttpTransport
which is used by groupcache when no other custom transport is provided. Custom transports must implement thetransport.Transport
andpeer.Client
interfaces. Thetransport.Transport
implementation can then be passed into thegroupcache.New()
method to register the transport. Thepeer.Client
implementation is used bygroupcache.Instance
andpeer.Picker
to communicate with othergroupcache.Instance
in the cluster using the server started by the transport whenTransport.SpawnServer()
is called. It is the responsibility of the caller to ensureTransport.SpawnServer()
is called successfully, else thegroupcache.Instance
will not be able to receive any remote calls from peers in the cluster.transport.Sink
Sink is a collection of functions and structs which marshall and unmarshall strings, []bytes, and protobuf structs for use in transporting data from one instance to another.
peer.Picker
Is a consistent hash ring which holds an instantiated client for each peer in the cluster. It is used by
groupcache.Instance
to choose which peer in the cluster owns a key in the selected "group" cache.peer.Info
Is a struct which holds information used to identify each peer in the cluster. The
peer.Info
struct which represents the current instance MUST be correctly identified by settingIsSelf = true
. Without this, groupcache would send its self hash ring requests via the transport. To avoid accidentally creating a cluster without correctly identifying which peer in the cluster is our instance,Instance.SetPeers()
will return an error if at least one peer withIsSelf
is not set totrue
.cluster package
Is a convenience package containing functions to easily spawn and shutdown a cluster of groupcache instances (called daemons).
Start() and StartWith() starts a local cluster of groupcache daemons suitable for testing. Users who wish to test groupcache in their own project test suites can use these methods to start and stop clusters. See
cluster_test.go
for more examples.