Skip to content

Orchestrators

Scott Mansfield edited this page Mar 8, 2017 · 1 revision

Overview

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) Orca

The 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.

Error handling

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.

Implementations

Rend comes with several implementations of the orcas.Orca interface:

  1. L1Only: a simple pass-thru to a single handler, no transformations or weird handling.
  2. 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.
  3. L1L2Batch: assumes passive data management, treats L1 as a passive element; writes to L2 while maintaining L1.
  4. Locked: A wrapper around another orcas.Orca that implements per-key Mutex or RWMutex semantics.

Implementing your own Orca

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.

Clone this wiki locally