In This Section

Overview

The previous sections discussed the flow for receiving messages from a message bus. The AepEngine also supports the ability for applications to inject message creating within the application's process. This can be useful for an application to schedule defered work (from an event handler), or when an external thread would like to schedule work against an application (as only events dispatched from an AepEngine are permitted to interact with an application's state). 

Injecting Messages

The below code snippet demonstrates using injection to schedule MessageB to be dispatched to the application in the future.

public void onMessageA(MessageA message) {
  // schedule MessageB to processed in 1 second:
  MessageB messageB= MessageB.create();
  engine.injectMessage(messageB, true, 1000); 
}
 
public void onMessageB(MessageB message) {
}

Injection from an Event/Message Handler

Important: Injection of messages from an event handler does not result in the Message being added to the current transaction. Consequently a failure of the engine prior to it being dispatched will result in the message being discarded. See HA Considerations below.

Delayed or Priority Injection

The value of the delay parameter is interpreted as follows:

Behavior when not in HA Active Role

The message will only be injected on Started engines operating in the Primary role. Calls to inject are ignored on backup instances, since it is expected that the injected message will be replicated from the primary. Calls made while an engine is replaying from a transaction log (e.g. State.Starting) are similarly ignored as those calls would interfere with the stream being replayed. An application that injects messages from an external source may call AepEngine.waitForMessagingToStart() to avoid an injected message being discarded while an engine is transitioning to a started, primary role. It is important to note that message injection is thus effectively a BestEffort operation because injections of message that are in the event multiplexer queue at the time of failure will be lost. Reliable injection can be archived via scheduleMessage(IRogMessage, int, com.neeve.aep.AepScheduleEvent.HAPolicy) though fault tolerant scheduling incurs slight higher overhead.

Message Pooling Considerations

The engine inject methods transfer ownership of the message to the platform. The method caller must not modify the message subsequent to this call. The platform will call dispose() on the message once it has been dispatched, so an application must call MessageView.acquire() if it will hold on to a (read-only) reference to the message.

Blocking vs. Non Blocking Considerations

Care must be taken when considering whether to use using blocking or non-blocking injection. If the injecting thread is injecting to a engine multiplexer that may itself block on a resource held by the thread trying to inject, it can cause a deadlock. Conversely, using non-blocking dispatch can result in excessive memory growth, increased latency, and fairness issues. Therefore, if the injecting thread is drawing events from an external source, blocking dispatch is generally the right choice, but if injection is being performed from a message handler, non-blocking should be used.