4

I have come to a point, in building a services oriented architecture (on top of Thrift), that I need to expose events and allow listeners.

My initial thought was, "create an EventService" to handle publishing and subscribing to events. That EventService can use whatever implementation it desires to actually distribute the events. My client automatically round-robins service requests to available service hosts which are determined using Zookeeper-based service discovery. So, I'd probably use JMS inside of EventService mainly for the purpose of persisting messages (in the event that a service host for EventService goes down before it can distribute the message to all of the available listeners).

When I started considering this, I began looking into the differences between Queues and Topics. Topics unfortunately won't work for me, because (at least for now), all listeners must receive the message (even if they were down at the time the event was pushed, or hadn't made a subscription yet because they haven't completed startup (during deployment, for example) - messages should be queued until the service is available).

However, I don't want EventService to be responsible for handling all of the events. I don't think it should have the code to react to events inside of it. Each of the services should do what it needs with a given event. This would indicate that each service would need a JMS connection, which questions the value of having EventService at all (as the services could individually publish and subscribe to JMS directly). However, it also couples all of the services to JMS (when I'd rather that there be a single service that's responsible for determining how to distribute events).

What I had thought was to publish an event to EventService, which pulls a configuration of listeners from some configuration source (database, flat file, irrelevant for now). It replicates the message and pushes each one back into a queue with information specific to that listener (so, if there are 3 listeners, 1 event would become 3 events in JMS). Then, another thread in EventService (which is replicated, running on multiple hots) would be pulling from the queue, attempting to make the service call to the "listener", and returning the message to the queue (if the service is down), or discarding the message (if the listener completed successfully).

tl;dr

If I have an EventService that is responsible for receiving events and delegating service calls to "event listeners," (which are really just endpoints on other services), how should it know how to craft the service call? Should I create a generic "Event" object that is shared among all services? Then, the EventService can just construct this object and pass it to the service call. Or is there a better answer to this problem entirely?

11
  • 3
    I think you have some good questions here, but maybe you could break them up into a few questions on this site? Or ask one particular one at a time and see where that leads you? This kind of sounds like you're asking for someone to give you an architecture rather than asking a question.. or if there's a question in there, I can't find it? Commented Jun 24, 2013 at 15:31
  • 1
    @JimmyHoffa Sorry, I have updated the question to include what I'm really trying to ask at the end. But I am leaving the option on the table for someone to suggest that I'm going about this the wrong way entirely.
    – Colin M
    Commented Jun 24, 2013 at 15:34
  • Don't worry about leaving options open, if an engineer thinks you're doing something wrong they don't usually keep their mouths shut, do they? :) Commented Jun 24, 2013 at 15:37
  • @JimmyHoffa Fair point. We tend to be part of the "brutally honest" crowd. Something along the lines of: "your entire design sucks. Do it again."
    – Colin M
    Commented Jun 24, 2013 at 15:38
  • You might think about this generic service just passing around the serialized forms of whatever messages it gets. Then it doesn't care about the type, it's up to publishers and subscribers to be sure they have a common language. Your delegator just passes what it's given. You may not need to even worry about serializer stuff, working in ActiveMQ with NMS there's built in message objects from the NMS framework, I presume JMS similarly has a general message object you can receive and forward. Commented Jun 24, 2013 at 15:38

2 Answers 2

1

If the service must receive the message, even though it is unaware of its existence, then the publish/subscribe pattern is not the answer. Publishers are not supposed to know about their subscribers. The subscriber is supposed to care, not the publisher.

If the "publisher" is responsible for maintaining messages, then what you want is polling.

1
  • Thats why messaging middleware exists. Durable subscriptions makes sure that all publications gets through without polling. Commented Dec 19, 2014 at 5:53
0

First of all, this Event Service introduces some kind of orchestration. This service is tightly coupled with all the services it interacts with, resulting in a chatty communication, very likely implemented with synchronous request-reply, which is probably the biggest evil of all.

Think of this service when it will orchestrate 100 services. It sounds pretty scary.

Besides that, the logic is inevitably spread over two services: the central governing service and invoked service because of a problem I’ve just mentioned -- synchronous communication nature between them.

After all, this looks like a smart pipes approach. Definitely not good.

Here is a good and more detailed overview of this approach.

Or is there a better answer to this problem entirely?

I think there is. Let all your services listen to events they are interested in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.