-
Notifications
You must be signed in to change notification settings - Fork 90
Orchestrators
The orchestrator is the piece that handles all of the higher level logic to fulfill a request. It is the piece that decides where to sent what commands and on what handlers. It's responsible for managing the L1 / L2 cache relationship based on what kind of connection it is and what requirements the application has. Since the orchestrators are defined by an interface and constructed with a function by the server listener they are conducive to decoration.
The orcas.Orca interface has a very un-go-like large interface with methods for each of the types of requests Rend can process, plus a special Error function:
type Orca interface {
Set(req common.SetRequest) error
Add(req common.SetRequest) error
Replace(req common.SetRequest) error
Append(req common.SetRequest) error
Prepend(req common.SetRequest) error
Delete(req common.DeleteRequest) error
Touch(req common.TouchRequest) error
Get(req common.GetRequest) error
GetE(req common.GetRequest) error
Gat(req common.GATRequest) error
Noop(req common.NoopRequest) error
Quit(req common.QuitRequest) error
Version(req common.VersionRequest) error
Unknown(req common.Request) error
Error(req common.Request, reqType common.RequestType, err error)
}The constructor function is telling in terms of what the orchestrator implementations are expected to make use of:
type OrcaConst func(l1, l2 handlers.Handler, res common.Responder) OrcaThe server listener will create the handler instances from their respective constructor functions and pass it to the OrcaConst. The constructor also gets an instance of a responder, which is an interface that represents the protocol-specific ways of responding to all of the different types of requests. The only current implementations of this interface are in the textprot and binprot packages.
The Error function exists as a catch-all when there is an error returned from the orchestrator. It's normally used when things go well but there is an error completing the operation, e.g. when you send an add request but the key already exists that is represented as an error. The server implementation will take errors and pass them into the Error function to properly respond with an error format for that protocol. In general the Orca implementation will implement the happy path and return errors which the Error function then takes care of in a second call into the orchestrator. This interaction is a bit odd but also allows the implementations of the rest of the functions to be simpler than they otherwise would be.
Rend comes with several implementations of the orcas.Orca interface:
-
L1Only: a simple pass-thru to a single handler, no transformations or weird handling. -
L1L2: assumes active data management, manages L1 as a true subset of l2; e.g. on a miss in L1 it reads from L2 writes to L1. -
L1L2Batch: assumes passive data management, treats L1 as a passive element; writes to L2 while maintaining L1. -
Locked: A wrapper around anotherorcas.Orcathat implements per-key Mutex or RWMutex semantics.
It is recommended to start an orchestrator implementation by copying an existing implementation and modifying it to fit any custom needs you have. There has been a lot of thought put into the implementations and the order of operations in each of the implementations, so they are good starting points. Any clean implementations will need to ensure they track all of the metrics necessary, which are all defined in the types.go file in the orcas package.