

Pub/Sub system events for post-action tasks in Rails - urbanautomaton
http://techblog.tribesports.com/blog/2012/08/21/pub-sub-system-events-for-post-action-tasks/

======
pselbert
While I like the idea of cleaning up unrelated activities I don't think
observers or subscribers are an ideal solution. In a system of non trivial
size, or even a system where you haven't worked in a particular model for a
while it can become difficult to track down what is acting and when.

When you need to bundle activity together a much better approach is to move it
out of the controller and into a dedicated class. It isn't practical to test a
controller in isolation, but quite simple to test a PORO.

When you extract the activities into a class you are forced to name the
behavior outside the context of some controllers "create" action. Testing,
readability, and complexity wins.

~~~
urbanautomaton
I agree that using Observers (at least as embodied in Rails' implementation)
can lead to a fearful (and hard-to-debug) mess. I feel that our approach
differs, though, in forcing the notification to be explicit, as opposed to
tied to object lifecycle callbacks. It's plain to see in our controller what
event is being announced, and trivial to find all listeners that respond to
that event. No familiarity with the model being manipulated is required,
because it's got nothing to do with either the event announcement or the
responses to it. And by providing a centralised event dispatch system, there's
a simple point of entry for debugging.

We did consider the service object approach, as detailed early in the blog -
for me, though, it feels wrong to end up with a bunch of service objects, each
with a semi-random grab-bag of dependencies and responsibilities. One of our
main aims was to reduce the random scattering throughout our app of various
calls, because the coupling was making it hard to reliably effect change when
necessary. Service objects don't address this, unfortunately. We still make
use of them, but to my mind a CommentCreationService should only be concerned
with creating valid comments - not with emailing or rewarding users.

------
xentronium
Implementing such system is a very tough call, actually. As complexity of your
application increases, you stop understanding what happens when. The arguments
for and against pub/sub callbacks are basically the same as with rails
Observers and Sweepers.

I personally felt that their original code was not that bad.

~~~
urbanautomaton
It's a trade-off, really. As mentioned in the blog post, we had considerably
more complex actions, and many more types of post-action task than were shown.

You're quite right, in the original code it's easier to see at a glance what
happens in that particular action. However, over the span of the whole
application it's much more difficult to see, say, all circumstances in which
an activity update is triggered, or all the ways a user might get a
gamification reward for doing something on the site. It was precisely the
growing complexity of our app that motivated this change; we were losing the
ability to keep control of (and test) whole important features of our site,
such as mailout logic, gamification, etc. and so forth.

As I say at the end, I certainly don't recommend this as a catch-all approach;
you've got to know your app and be aware of the advantages and disadvantages.

