In This Section
Overview
The Talon programming model is quite straightforward: all business logic in a Talon application is performed by event handlers that are invoked by Talon on response to received messages. The event handlers update state and generate outbound messages to interact with the outside world as a result of the business logic processing. There are several general high level rules that developers must follow when working with the platform which make sense to discuss before taking a look at more detailed code.
Messaging
Talon's messaging APIs are discussed in more depth in sections on Working with Messaging later in this manual. In the meantime keep the following rules in mind.
Inbound Messages
An application may not modify inbound messages. Aside from being good practice, the platform relies on this immutability to do background journalling and replication of the message in parallel with your message handlers.
Outbound Messages
Once an application sends an outbound message, it must not attempt to modify or reuse the message. This implies that any particular message instance can only be sent once. Applications may copy a message that has been sent and send it elsewhere. The reason for this is that the platform may concurrently serialize the message for replication or persistence purposes in parallel with your application logic.
Messages Scoped to Handlers
In general, it is bad practice to hold onto a message or its embedded entity fields beyond the scope of a message handler. This is because the platform pools these messages and their underlying contents can be reset after return from a handler. This means that if applications intend to hold onto a message or a portion of the message in application state, the safest approach is to copy them (or their contents) into application state.
In advanced use cases where an application must hold onto a message or one of its embedded entities for a short period of time, copy can be avoided by acquiring a reference to the message via a call to its acquire()
method,
See Working with Advanced Features for more information.
Threading
Single Threaded State
Micro app and micro service models espouse a model where state is private to the application. One of the primary motivators behind this model is that it avoids scalability bottlenecks that can arise from multiple processes contending to update state. Talon applications take this concept even further by making application state private to a single application processing thread. This restriction is key to Talon's ability to perform and scale by avoids thread contention and best utilizes processors' cpu caches.
This means:
- Accessing an application's state objects outside of a message handler is forbidden. Any change to an application's state must be performed for the underlying dispatch thread in an application event handler triggered by either receipt or injection of a message.
- Applications should be designed to scale horizontally by partitioning state.
No Blocking In Handlers
Talon micro apps are optimized for stream oriented message processing. This means that message handlers should never perform blocking operations. Additionally, since Talon applications have a single threaded state model, Talon is not optimized for long running, compute intensive operations.
In practice this is generally not an issue for the class of applications targeted by Talon.
- Talon handles I/O operations for applications, so applications should not be working with blocking I/O resources.
- If an application needs to make a blocking callout to interact with a remote resource, that interaction should be done asynchronously via messaging.
- For compute intensive tasks triggered by processing a message, applications may schedule the work on another thread and inject the results back into the engine to update application state.
Event Sourcing Considerations
Of Talon's two High Availability models (State Replication and Event Sourcing), the more advanced is Event Sourcing. The Event Sourcing model is best suited to applications that require very low latency, but it does impose some additional programming restrictions. An application using Event Sourcing must be able to exactly reconstruct the same state and outbound messaging stream by replying the same sequence of inbound events. This implies that business logic that updates state must not rely on any environmental state when making updates to its recoverable state or outbound messages. For example, setting the system time in an outbound message would not produce the same outbound message when the event stream is replayed at a later date or on a different system.
See Working with Event Sourcing and Environment Replication