Local handling
Fluxzero supports both asynchronous and local (synchronous) message handling. Local handlers process messages in the same thread that published them, bypassing the message dispatch infrastructure entirely. This typically results in faster response times and is ideal for simple or time-sensitive use cases.
To define a local handler, annotate the handler method, class, or its enclosing package with @LocalHandler:
@LocalHandler(logMetrics = true)public class SomeLocalHandler { @HandleEvent void handle(ApplicationStarted event) { // do something }}@LocalHandler(logMetrics = true)class SomeLocalHandler { @HandleEvent fun handle(event: ApplicationStarted) { // do something }}Require local handling
Section titled “Require local handling”Use @LocalOnly sparingly on a payload or package when external publication would cross a security boundary. Fluxzero
then invokes local handlers only, suppresses logMessage, returns a failed future for an unhandled request and quietly
completes an unhandled non-request. Parent packages include their children; @LocalOnly(false) restores normal
fallback for a more specific package or payload type.
Self-handling messages
Section titled “Self-handling messages”Instead of defining message handlers externally, you can embed handler logic directly in the message payload. This is often useful for queries or simple commands.
public class GetUserProfile { String userId;
@HandleQuery UserProfile handle() { // fetch the user profile and return }}class GetUserProfile(val userId: String) {
@HandleQuery fun handle(): UserProfile { // fetch the user profile and return }}By default, such handlers are treated as local. To process them asynchronously (i.e., as part of a consumer), annotate the class with @TrackSelf:
@TrackSelf@Consumer(name = "user-management")public class GetUserProfile { String userId;
@HandleQuery UserProfile handle() { // async handler }}@TrackSelf@Consumer(name = "user-management")class GetUserProfile(val userId: String) {
@HandleQuery fun handle(): UserProfile { // async handler }}When component-scanned (e.g., via Spring), @TrackSelf classes will be automatically discovered and registered. This works even if the annotation is placed on an interface rather than the concrete class—allowing for reusable handler patterns.
For example, a generic command handler interface can be tracked and reused:
@TrackSelfpublic interface UserUpdate { @HandleCommand default void handle() { // default behavior }}@TrackSelfinterface UserUpdate { @HandleCommand fun handle() { // default behavior }}Implementations of this interface will then be handled asynchronously, using the configured consumer (or the default one if unspecified).
© 2026 Fluxzero