Actions and Action Handlers

Head over to GrainContext API to get a more detailed view of the context API.

What are Actions and Action Handlers?

An Action is a message that can be processed by Action Handlers. These messages can be topic events, API calls, or Grain to Grain messages. The entire list of the types of Actions can be found here.

An Action Handler is a method that contains user defined behavior to handle Actions. Action Handlers can contain two types of methods:

Grainite provides the following platform guarantees (and constraints) while processing each Action:

  • Actions are processed in order, per Key (action source). There is no ordering across keys.

  • The action handler has single threaded access to the Grain’s state.

  • The action handler can read/modify the Grain's state.

  • The action handler can send asynchronous messages to other grains or topics.

  • The action handler can access external systems, make queries, calls etc. In case of failure, the handler could be re-executed, and any external side effects repeated.

  • All side effects: changes to self-state, and async messages sent out; are atomic - either all will (eventually) happen, or none will.

Side-effects to external systems are excluded from atomicity guarantee.

Defining a Single Action Handler

Action Handler methods may be per-action, or batch-oriented. Here is the method signature for a per-action handler named handlerMethodName:

public ActionResult handlerMethodName(Action action, GrainContext context) {
    ...
}

Defining a Batch Action Handler

Here is the method signature for a batch action handler named handlerMethodName:

public List<ActionResult> handlerMethodName(List<Action> actions, 
                                            GrainContext context) {
    ...
}

Requirements for batch Action Handlers:

  1. ActionResults must be returned in the same order as actions order.

  2. EITHER full results are returned, with no ActionResult.defers in the results, OR partial results are returned, and only the last entry is a ActionResult.defer.

Accessing Grain value and updating it within the Action Handler

// Grain value type.
public GrainValue implements Serializable {
  ...
}

public ActionResult handlerMethodName(Action action, GrainContext context) {
  // If no previous value exists, this will create a default GrainValue.
  GrainValue currentValue = context.getValue().asType(GrainValue.class);

  // Process the action and make changes to the currentValue object.
  ...

  // Finally write the currentValue object back to the Grain.
  context.setValue(Value.of(currentValue));
}

Last updated