canonical / microcluster

dqlite cluster management using go-dqlite
GNU Affero General Public License v3.0
19 stars 20 forks source link

Allow storing application specific data in `state.State` #134

Open markylaing opened 1 month ago

markylaing commented 1 month ago

Clients of microcluster will need to store data in memory. It would be useful for this to be integrated with microcluster so that it is possible to access data via the state.State.

As an example, the oidc.Verifier for LXD is stored as a field on the Daemon. This needs to persist in memory, otherwise cookie encryption keys will rotate on every request and OIDC authentication will fail. LXD site manager needs to use a similar pattern, but can only do so using a package level variable (either in isolation or via a field in another package level variable). Package level variables are generally not ideal for unit testing or readability.

I think it would be nice if state.State provided an API for getting/setting data that is application specific. A simple way to do this would be a map[string]any defined on Daemon with a mutex and getter/setter functions provided via the state parameter (e.g. (state.State).GetAppConfig[T](string) (T, error), (state.State).SetAppConfig(string, T)).

masnax commented 1 month ago

The way MicroCloud handles this is by having a different state struct that is defined by MicroCloud. rest.Endpoints are defined as functions instead of global variables like in LXD.

Then when the list of endpoints is passed to microcluster.Start, these functions are supplied with the MicroCloud state handler (we call this service.Handler):

here is where we define the set of endpoints passed to `microcluster.Start

here is the implementation of one such endpoint

here is the underlying endpoint handler, able to access both the service.Handler and state.State