Baratine on GitHub

Event Service

event: Service

When a subscriber wants to receive event updates from a publisher, but wants a loosely-coupled relationship, use the event service.

The event service is an API-based publish/subscribe broker. Publishers send events using application APIs. Subscribers receive events with the same API.

The address for an event node is application-defined. By convention, the classname of the API can be used as the node name.

Example Code

The subscriber registers with the event service using the event class as a key and a callback to handle the results. (A string key is also allowed.)

When the publisher calls its proxy to the event, the event broker will pass along the method call to any subscribers.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Startup
@Service
public void MyServiceSubscriber
{
  @Inject EventService _events;

  @OnInit
  void onInit()
  {
    _event.subscriber(MyEvent.class, new MyEventImpl(), Result.ignore());
  }

  class MyEventImpl implements MyEvent
  {
    public void onMyEvent(String msg)
    {
      // handle the event
    }
  }
}

public interface MyEvent
{
  public void onMyEvent(String msg);
}

One the publisher creates its event proxy, it can call methods on the proxy like any other java class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
@Startup
@Service
public void MyServicePublisher
{
  MyEvent _myEvent;

  @OnInit
  void onInit()
  {
    Services manager = Services.current();
    EventServiceSync events = manager.service(EventServiceSync.class);

    _myEvent = events.publishers(MyEvent.class);
  }

  public void myMethod()
  {
    _myEvent.onMyEvent("called myMethod");
  }
}

EventService API

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
  @Service("event://")
  public interface EventService
  {
    <T> void publisherPath(String path, Class<T> api, @Pin Result<T> result);
    <T> void publisher(Class<T> api, @Pin Result<T> result);

    <T> void subscriber(String path, Class<T> api, Result<CancelT> result);
    <T> void subscriber(Class<T> api, @Pin T consumer, Result<Cancel> result);

    <T> void consumer(String path, Class<T> api, Result<CancelT> result);
    <T> void consumer(Class<T> api, @Pin T consumer, Result<Cancel> result);
  }

Application Event API

The application’s event API can be any Java interface. While Baratine doesn’t restrict the interface, using JDK-8 @FunctionalInterface to allow lambda subscribers is a useful pattern to follow.

1
2
3
4
public interface MyEvent
{
  void onEvent(String msg);
}

Publisher

Since an event publisher is a proxy to the event scheme, it can be created and used in any context.

MyPub.java:

public void MyPub
{
  @Inject @Service("event://{class}")
  MyEvent _pubEvent;

  void execute()
  {
    _pub.onEvent("test message");
  }
}

Subscriber

Subscribers are typically Baratine services. Subscription should occur in an @OnInit method, because the callback needs to be in the service context. Subscribers may typically be @Startup services to register their subscriptions when the pod starts.

The callback for a message occurs in the service context that called the subscribe() method. Because services expect their callbacks to be in their own context, they should subscribe in an @OnInit method.

MySub.java:

@Service("/my-sub")
@Startup
public class MySub
{
  @OnInit
  private void onInit()
  {
    Services manager = Services.current();

    EventService events = manager.service(EventService.class);

    events.subscribe(MyEvent.class, msg->onMessage(msg), Result.ignore());
  }

  private void onMessage(String msg)
  {
    System.out.println("Message: " + msg);
  }
}

public interface MyEvent {
  void myEvent(String msg);
}