Skip to content

Event Dispatcher

As mentiond in the architecture section, Athena is an event based framework utilizing the Event Dispatcher component.

Basic Usage#

An event listener is defined by registering a service that includes AED::EventListenerInterface. The type should also define a self.subscribed_events method that represents what events it should be listening on.

require "athena"

@[ADI::Register]
class CustomListener
  include AED::EventListenerInterface

  # Specify that we want to listen on the `Response` event.
  # The value of the hash represents this listener's priority;
  # the higher the value the sooner it gets executed.
  def self.subscribed_events : AED::SubscribedEvents
    AED::SubscribedEvents{ART::Events::Response => 25}
  end

  def call(event : ART::Events::Response, dispatcher : AED::EventDispatcherInterface) : Nil
    event.response.headers["FOO"] = "BAR"
  end
end

class ExampleController < ART::Controller
  get "/" do
    "Hello World"
  end
end

ART.run

# GET / # => Hello World (with `FOO => BAR` header)

Tip

A single event listener may listen on multiple events. Instance variables can be used to share state between the events.

Custom Events#

Custom events can also be defined and dispatched; either within a listener, or in another service by injecting AED::EventDispatcherInterface and calling #dispatch.

require "athena"

# Define a custom event
class MyEvent < AED::Event
  property value : Int32

  def initialize(@value : Int32); end
end

# Define a listener that listens our the custom event.
@[ADI::Register]
class CustomEventListener
  include AED::EventListenerInterface

  def self.subscribed_events : AED::SubscribedEvents
    AED::SubscribedEvents{MyEvent => 0}
  end

  def call(event : MyEvent, dispatcher : AED::EventDispatcherInterface) : Nil
    event.value *= 10
  end
end

# Register a controller as a service,
# injecting the event dispatcher to handle processing our value.
@[ADI::Register(public: true)]
class ExampleController < ART::Controller
  def initialize(@event_dispatcher : AED::EventDispatcherInterface); end

  @[ARTA::Get("/:value")]
  def get_value(value : Int32) : Int32
    event = MyEvent.new value

    @event_dispatcher.dispatch event

    event.value
  end
end

ART.run

# GET /10 # => 100