Channels ▼

Arnon Rotem-Gal-Oz

Dr. Dobb's Bloggers

Remove the business context from your services

July 19, 2009

A lot have been written and said about multiple use (or reuse depending on your definition) of services. I want to touch one aspect of this with this post.

As a general rule, the more something is generic or small the easier it is to use it in different contexts, for example Hash tables are used all over the place in a lot of programs. The Hash table is a generic container and carries very little in terms of business context so it is very easy to use it. A corollary to the above mentioned rule is that the more specific is something the harder it is to use it in different contexts. Unfortunately (from the “use” point of view) specific domain logic is exactly what we strive to have with SOA.  The value of services is derived from the business value they can generate. To add insult to injury, there’s also a limitation on how small we’d want a service to be. The fact that  communicating with  a service requires communication over a network means that if we’ll make it too small, the overhead in getting to it (serialization, network traffic, security etc.) can out weight its utility (an anti-pattern I call nano-services)

Well, one thing you can try to do is remove the business context from the services. before you flame me about  how this matches my previous statement that services’ value comes from the business value or domain know how they provide, you should note that I said “business context” and not business logic.

Let me try to clarify this with a concrete example from my current system. At xsights we provide image identification services for mobile devices. for instance when you see a movie ad, you can take a picture with your mobile, send it to us, via MMS, a specific client or video call, and we provide related information such as the trailer, where to buy tickets etc. Our initial offering supported only video calls (for business reasons irrelevant for this post). In a video call you have a constant stream of incoming video from the handset (10-15 frames per second) so we (try to) identify frames as they come. We mostly use event driven architecture over SOA so (a partial) flow looks something like the following (the events occur in the context of a saga). An extractor service listens on an RTP stream, extract and preprocess images and raises a FrameArrived event on each new frame. An Identification GW decides how to handle an incoming frame and directs it to one or more algorithmic workers (this isn’t event driven). After a successful identification the Identification GW raises a LinkFound event. And a Call Flow service takes it from there:

image 

if we didn’t get an identification within a timeout we can ask the user to better aim the camera or whatnot (behavior controlled by the CallFlow service)

When we first added support for MMS  we wanted to use the same identification logic – there’s a slight difference though: in a video call you have a constant stream of low-quality images where as in an MMS you get a single high(er) quality shot. To add support for MMS we needed to add some logic to the identifier so that it will know whether the origin of the image is an MMS message or a video call. If it is the first then the Identifier needs to raise a “failed to identify” even when it finished processing the image (the video call can use a timeout instead)

But that’s the wrong way to do it – since now we need to know which sagas are MMS sagas and which are Video call ones. Not to mention we would probably need some other “special” logic to handle clients (which indeed we needed) . If we go down this lane and add more and more business context to the identifier we make it less autonomous – even though we are using events they are no longer about the business of the service events (like “FrameArrived” from the extractor) they are system context events (“MMSIdentificationFailed”) our identifier is gaining more and more “reasons to change” and is becoming tightly couples to specific contexts. So yes, we using it over and over again but the costs for that are getting higher with each such reuse

What’s a better way? Remove the business context from the service and focus on keeping the business logic and rules. In this case that would be a NoMatchForFrame event for each failed frame. In an MMS related saga there would be a service that listens to this event, in a video call related saga no service will listen on the event*. Once the business context is removed our identification GW focuses only on its core business activity (routing images to algorithmic workers and notifying the world on success/failure. Adding support for client behavior becomes much easier in this can, in fact the identification GW doesn’t need any changes to support this scenario.

To sum this post – if you want to increase the chance to use services in different contexts you should strive to remove the context specific bits outside of the services. This will simplify the services themselves as well as increase their autonomy


* Out communications framework allows for different event wiring (or route) depending on the saga “type” so actually the event won’t even fire in a video call  as our communication framework will identify there aren’t any subscribers. This is very good from the service point of view as it allows it to fire events and letting the the communications framework worry about the context. The saga initiator is the only place where the context has to be specified (I’ll expand on this in another post)
        

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video