In This Section
Overview
State Replication is the simpler of Talon's two High Availability models. With State Replication, Talon replicates changes to state and the outbound messages emitted by your application's message handlers. In the event of a failover to a backup or a cold start recovery from a transaction log your application's state is available at the same point where processing left off, and the engine will retransmit any outbound messages that were left in doubt as a result of the failure. This section discusses the anatomy of an application using State Replication.
Coding For State Replication
A basic state replication application is straightforward. A quick way to get started is to use the nvx-talon-sr-processor-archetype described in Talon Maven Archetypes. The general flow for creating a state replication application involves:
- Modeling Messages and State
- Declaring a main class annotated with HAPolicy of StateReplication
- Providing Talon with a state factory for creating your application state
- Writing message handlers to perform business logic.
A Basic App
Model Application State
The steps outlined below assume that you have already modeled some messages and state for your application to use. See the Modeling Message and State sections to get started.
When modeling application state, Xbuf encoding is not yet recommended, Protobuf encoding should be used instead (Xbuf currently has a higher memory footprint than Protobuf generated entities).
Annotate App Main for State Replication
Provide a StateFactory
An AepEngine is application state agnostic: it deals with your application's state as a collection of plain old java objects organized into a state tree with a single object root. Given the root object for your application's state, the underlying store will track changes made to fields on the root (and its descendants) and replicate or persist those changes. As such, an AepEngine needs to be able to create a new application state during when your application is initialized. This is done by finding a method on your main application class annotated with @AppStateFactoryAccessor. The state factory accessor returns a newly initialized set of state for the engine to manage. As messages are processed the engine will pass the relevant state root back into the application to be operated upon.
As your application makes changes to this root object (setting fields etc), the engine will monitor the root and replicate deltas to backup members or disk.
The state factory should return an empty, uninitialized object. The platform will invoke the state factory during application initialization with a null argument to determine the type of the application's root state, and will subsequently invoke the state factory on receipt of a MessageView when state has not already been created for the application. The application should not store a reference to the application state that it returns ... it is the job of the platform to manage the state tree once it has been created by either passing the state root into an EventHandler or returning it via a call to AepEngine.getApplicationState(final MessageView message)
Inject Message Sender
If your application will send messages, it can add an injection point for the underlying AepEngine to inject a message sender.
Declare Message Handlers
When working with an application using StateReplication, the underlying AepEngine will pass in the root object for your application state along with the message. Outbound message sends and state changes are managed by Talon as an atomic unit of work.
Configuring the Engine
Register Object Factories
When working with state replication both the ADM and message and state object factories need to be registered with the runtime. Registering the state factory allows the underlying state replication machinery to deserialize replicated state objects based on the ids encoded in the replication stream. The message factories allow are used for deserializing replicated outbound messages as well as messages received from message buses. The state factories can be declared in your config.xml or programmatically:
Enable Storage
To actually achieve high availability storage must be configured for the application. The primary means of storage is for Talon apps is through clustered replication to a backup instance. Talon also logs state changes to a disk-based transaction log as a fallback mechanism. Storage and persistence can be enabled in the application's configuration XML.
Enabling clustering allows 2 applications of the same name to discover one another and form an HA cluster. When one or more instances of an application connect to one another one instance is elected as the primary via a leadership election algorithm. The primary member will establish messaging connections and begin invoking message handlers in your application.
Enabling persistence causes the replication stream that is sent to backup instances to also be logged locally on disk to a transaction log file. The transaction log file can be used to recover application state from a cold start and is also used to initialize new cluster members that connect to it so when clustering is enabled, persistence must be enabled as well.
There are many configuration knobs that can be used to customize the store's behavior and performance. See DDL Config Reference for a listing of configuration knobs for storage.
Limitations and Upcoming Enhancements
See State Tree Limitations for a discussion of current state tree limitations.