Threading Policies

21 views
Skip to first unread message

Stefan Weber

unread,
Nov 11, 2009, 9:53:15 AM11/11/09
to actorom-discussions
Hi,

I'm working on an application that is supposed to serve as an adapter
to a 3rd party product. The communication to the latter happens with
ASCII messages over TCP/IP and I found that dispatching the incoming
messages to their handlers seems like a good case to try Actorom. It
actually works very good, I hardly had to restructure the application
and could get rid of a lot of code. So thanks for that :)

I chose the OS threads over the green threads to allow for more
concurrency between the processing of the different message types I'm
getting from the 3rd party app (i.e. there is one separate actor for
most of the message types I need to handle).

However, since the OSMessageDispatcher ensures that messages handled
by the same actor run sequentially I have some worries when the
handler takes longer (I need to parse potentially big ASCII message,
for example) than the inter arrival time of its messages.
If I understand the actors model correctly, this is to ensure that the
actor does not need to worry about synchronization. However, if the
handler is state less, it seems like it should be no problem for this
actor to accept messages concurrently.

What is your thought on this? Do you discourage this upfront or do you
think it could make sense?

I was thinking to implement a MessageDispatcher myself that does the
same thing as the OSMessageDispatcher but allowing concurrent handling
on the same actor if it has the @ThreadSafe annotation.

Thanks,

Stefan

Sergio Bossa

unread,
Nov 11, 2009, 10:10:08 AM11/11/09
to Stefan Weber, actorom-discussions
On Wed, Nov 11, 2009 at 3:53 PM, Stefan Weber <stefan...@gmail.com> wrote:

> I'm working on an application that is supposed to serve as an adapter
> to a 3rd party product. The communication to the latter happens with
> ASCII messages over TCP/IP and I found that dispatching the incoming
> messages to their handlers seems like a good case to try Actorom. It
> actually works very good, I hardly had to restructure the application
> and could get rid of a lot of code. So thanks for that :)

Great to know about your use case, thanks for sharing :)

> However, since the OSMessageDispatcher ensures that messages handled
> by the same actor run sequentially I have some worries when the
> handler takes longer (I need to parse potentially big ASCII message,
> for example) than the inter arrival time of its messages.
> If I understand the actors model correctly, this is to ensure that the
> actor does not need to worry about synchronization. However, if the
> handler is state less, it seems like it should be no problem for this
> actor to accept messages concurrently.
>
> What is your thought on this? Do you discourage this upfront or do you
> think it could make sense?

I didn't implement "concurrent" actors because of two main reasons:
1) They break the principles of the actors model itself.
2) They could be misused, leading people to use actors in wrong ways.

That said, I'm not saying to be completely *against* such a use case:
just let's discuss it and see if there's some better way of doing the
same thing.

> I was thinking to implement a MessageDispatcher myself that does the
> same thing as the OSMessageDispatcher but allowing concurrent handling
> on the same actor if it has the @ThreadSafe annotation.

Another way to offload actors for stateless tasks could be to use an
external thread pool and schedule those tasks on it: by doing so,
actors would be used only to represent the messaging abstraction,
while the actual computation would be executed on another thread
(launched by the actor who received the related message).
What do you think?
Just let me know if you need more details about this solution.

Cheers,

Sergio B.

--
Sergio Bossa
Software Passionate and Open Source Enthusiast.
URL: http://www.linkedin.com/in/sergiob

Stefan Weber

unread,
Nov 12, 2009, 3:14:46 AM11/12/09
to Sergio Bossa, actorom-discussions
I didn't implement "concurrent" actors because of two main reasons:
1) They break the principles of the actors model itself.
2) They could be misused, leading people to use actors in wrong ways.

That said, I'm not saying to be completely *against* such a use case:
just let's discuss it and see if there's some better way of doing the
same thing.

I understand this reasoning and think it makes sense. To be honest, the suggestion I made to allow concurrent handlers if the @ThreadSafe annotation is not very clean.
 
Another way to offload actors for stateless tasks could be to use an
external thread pool and schedule those tasks on it: by doing so,
actors would be used only to represent the messaging abstraction,
while the actual computation would be executed on another thread
(launched by the actor who received the related message).
What do you think?

I think this is a good idea and had it in mind as well. I was a bit reluctant to do this because it would push some of the concurrency burden that I could get rid of with Actorom back to the application. But given that you also suggest to do it this way I will try this.

Actually, I had to ideas how to implement it:

1. The handler class has a concurrent queue as a member and all the handler method does is push the incoming message into this queue. Then have a number of worker threads in the handler class that process the queue.

2. In the handler method, create a new Runnable and pass it to the ExecutorService (very similar to what you do in OSMessageDispatcher.dispatch).

I prefer solution 2 because it is simpler. The only small doubt I have is that I have to create a new Runnable for every message. I don't have enough experience to guess how expensive this will be in practice but I assume it will be easy to spot in case it really becomes a bottleneck. What do you think?

Cheers,

Stefan

Sergio Bossa

unread,
Nov 12, 2009, 3:32:19 AM11/12/09
to Stefan Weber, actorom-discussions
On Thu, Nov 12, 2009 at 9:14 AM, Stefan Weber <stefan...@gmail.com> wrote:

> I understand this reasoning and think it makes sense. To be honest, the
> suggestion I made to allow concurrent handlers if the @ThreadSafe annotation
> is not very clean.

Glad you agree :)

> I think this is a good idea and had it in mind as well. I was a bit
> reluctant to do this because it would push some of the concurrency burden
> that I could get rid of with Actorom back to the application. But given that
> you also suggest to do it this way I will try this.

I know, I know, that's why I was recently considering to add to
Actorom a bunch of commonly used handler implementation, such as
"BalancingActor", "OffloadingActor" and so on ... do you think it
could be a worthy addition?

> Actually, I had to ideas how to implement it:
> [CUT]
> I prefer solution 2 because it is simpler.

Agree: and #2 actually does what you describe in #1 under the hood, so
don't reinvent the wheel :)

> The only small doubt I have is
> that I have to create a new Runnable for every message. I don't have enough
> experience to guess how expensive this will be in practice but I assume it
> will be easy to spot in case it really becomes a bottleneck. What do you
> think?

Absolutely agree: I don't think creating Runnable objects would be a
problem and just in case you may want to tune your garbage collection
to accommodate the large number of short-lived objects (by tuning the
eden space) ... anyways, go with it and keep me posted.

Sergio Bossa

unread,
Nov 12, 2009, 5:06:46 AM11/12/09
to Stefan Weber, actorom-discussions
On Thu, Nov 12, 2009 at 9:14 AM, Stefan Weber <stefan...@gmail.com> wrote:

> I prefer solution 2 because it is simpler. The only small doubt I have is
> that I have to create a new Runnable for every message. I don't have enough
> experience to guess how expensive this will be in practice but I assume it
> will be easy to spot in case it really becomes a bottleneck. What do you
> think?

As a side note, you may have your own message object implement
Runnable, and directly schedule it without having to do any wrapping.

Stefan Weber

unread,
Nov 12, 2009, 7:58:13 AM11/12/09
to Sergio Bossa, actorom-discussions
On Thu, Nov 12, 2009 at 9:32 AM, Sergio Bossa <sergio...@gmail.com> wrote:

I know, I know, that's why I was recently considering to add to
Actorom a bunch of commonly used handler implementation, such as
"BalancingActor", "OffloadingActor" and so on ... do you think it
could be a worthy addition?

Yes, I think this would be great. In case I'm really running into problems with the sequantial execution of handlers, I'll try to implement something in this direction and keep you updated of course.

Another idea I had: for my use case it would be nice to have more flexibility regarding the selection of the handler method on the actor. Currently, there is always the CoreHandler used internally but it would be nice to plug in custom logic there.

For example, it would be very useful to have something along these lines:

class MyHandler {

@OnMessage(type = Message.class)
void handleFooMessage(Message msg) {...} // handles messages of type foo


@OnMessage(type = Message.class)
void handleBarMessage(Message msg) {...} // handles messages of type bar
 
}

The current implementation of course does not know which handler to call here, so I am using more specific types in the @OnMessage annotation. However, since I get a generic Message from the 3rd party app, I had to plug in a factory that creates a more specific Message from the generic Message before calling the send method on the actor (but in many cases, I don't need this more specific Message later on).

so I would need to inject a CoreHandler when spawning the new actors (e.g. something called MyCoreHandler that extends CoreHandler and overrides handleOnMessage). I could then analyze the method name with reflection, compare it with the message type of the currently processed message and then dispatch based on this.

Could I make myself clear? :) What do you think? Does this make sense?

Best,

Stefan

Stefan Weber

unread,
Nov 12, 2009, 8:01:30 AM11/12/09
to Sergio Bossa, actorom-discussions
On Thu, Nov 12, 2009 at 11:06 AM, Sergio Bossa <sergio...@gmail.com> wrote:
As a side note, you may have your own message object implement
Runnable, and directly schedule it without having to do any wrapping. 

Thanks for the hint. I need to look at how my app evolves (I have the feeling that this could clutter the Message classes). Will see :)

Sergio Bossa

unread,
Nov 12, 2009, 8:56:46 AM11/12/09
to Stefan Weber, actorom-discussions
On Thu, Nov 12, 2009 at 1:58 PM, Stefan Weber <stefan...@gmail.com> wrote:

> Yes, I think this would be great. In case I'm really running into problems
> with the sequantial execution of handlers, I'll try to implement something
> in this direction and keep you updated of course.

Great, thanks for the feedback.

> Another idea I had: for my use case it would be nice to have more
> flexibility regarding the selection of the handler method on the actor.
> Currently, there is always the CoreHandler used internally but it would be
> nice to plug in custom logic there.
> [CUT]
> However, since I get a generic Message from the 3rd party app, I had to plug
> in a factory that creates a more specific Message from the generic Message
> before calling the send method on the actor (but in many cases, I don't need
> this more specific Message later on).
>
> so I would need to inject a CoreHandler when spawning the new actors (e.g.
> something called MyCoreHandler that extends CoreHandler and overrides
> handleOnMessage). I could then analyze the method name with reflection,
> compare it with the message type of the currently processed message and then
> dispatch based on this.

I've lost you there: even if you get a generic Message instance,
CoreHandler works by reflection and you don't need to do any wrapping.
In other words, if you get a generic Message whose actual type is
BarMessage, and you annotate your handler object with
@OnMessage(type=BarMessage.class), CoreHandler will call the correct
method.

Does it make sense for your use case, or am I getting it wrong?

Stefan Weber

unread,
Nov 12, 2009, 9:08:08 AM11/12/09
to Sergio Bossa, actorom-discussions
On Thu, Nov 12, 2009 at 2:56 PM, Sergio Bossa <sergio...@gmail.com> wrote:
I've lost you there: even if you get a generic Message instance,
CoreHandler works by reflection and you don't need to do any wrapping.
In other words, if you get a generic Message whose actual type is
BarMessage, and you annotate your handler object with
@OnMessage(type=BarMessage.class), CoreHandler will call the correct
method.

Does it make sense for your use case, or am I getting it wrong?

It makes sense, but unfortunately not for my use case ;)

In short: the dynamic type of the Message I'm getting is NOT BarMessage.

Example: I get an ASCII string from the network and wrap it in a Message. Then I call getMessageType on it and Message will parse the ASCII string and return the message type. Only then I know what specific message it is.

Sergio Bossa

unread,
Nov 12, 2009, 9:14:32 AM11/12/09
to Stefan Weber, actorom-discussions
On Thu, Nov 12, 2009 at 3:08 PM, Stefan Weber <stefan...@gmail.com> wrote:

> Example: I get an ASCII string from the network and wrap it in a Message.
> Then I call getMessageType on it and Message will parse the ASCII string and
> return the message type. Only then I know what specific message it is.

So, you'd like to implement some kind of custom routing logic: that
is, rather than routing on the message type, you may want to route on
some kind of message property, is that correct?

If so, the correct way to solve this would be IMO to enhance the
annotation processing, i.e. by adding some kind of predicate to test
on received messages, something like:

@OnMessage(type = Message.class, predicate = FooPredicate.class)
void handleFooMessage(Message msg) {...} // handles messages of type foo

public class FooPredicate implements Predicate<Message> {

public boolean accept(Message msg) { ... }
}

What do you think?

Stefan Weber

unread,
Nov 12, 2009, 2:09:08 PM11/12/09
to Sergio Bossa, actorom-discussions
On Thu, Nov 12, 2009 at 3:14 PM, Sergio Bossa <sergio...@gmail.com> wrote:
So, you'd like to implement some kind of custom routing logic: that
is, rather than routing on the message type, you may want to route on
some kind of message property, is that correct?

Correct :)
 
If so, the correct way to solve this would be IMO to enhance the
annotation processing, i.e. by adding some kind of predicate to test
on received messages, something like:

@OnMessage(type = Message.class, predicate = FooPredicate.class)
void handleFooMessage(Message msg) {...} // handles messages of type foo

public class FooPredicate implements Predicate<Message> {

   public boolean accept(Message msg) { ... }
}

What do you think?

This looks very nice! Much cleaner than the solution I tried to described!

Cheers,

Stefan

Sergio Bossa

unread,
Nov 13, 2009, 1:11:08 AM11/13/09
to Stefan Weber, actorom-discussions
On Thu, Nov 12, 2009 at 8:09 PM, Stefan Weber <stefan...@gmail.com> wrote:

> This looks very nice! Much cleaner than the solution I tried to described!
> Cheers,

Great, see: http://code.google.com/p/actorom/issues/detail?id=15

Stefan Weber

unread,
Nov 13, 2009, 3:06:47 AM11/13/09
to Sergio Bossa, actorom-discussions
On 13.11.2009, at 07:11, Sergio Bossa <sergio...@gmail.com> wrote:

> Great, see: http://code.google.com/p/actorom/issues/detail?id=15
>

Thanks, looking forward :)

Cheers,

Stefan

Sergio Bossa

unread,
Nov 13, 2009, 3:15:19 AM11/13/09
to Stefan Weber, actorom-discussions
On Fri, Nov 13, 2009 at 9:06 AM, Stefan Weber <stefan...@gmail.com> wrote:

>> Great, see: http://code.google.com/p/actorom/issues/detail?id=15

I'm very busy these days, but I'll try to get it into trunk in a few weeks.
Contributions are obviously welcome, and as you may know, I'm also
seeking for committers, if you're interested ... ;)

Cheers,

Sergio B.

Stefan Weber

unread,
Nov 13, 2009, 3:45:24 AM11/13/09
to Sergio Bossa, actorom-discussions
Tried to access the read-only repo but svn complained that it cannot connect to the server.

Is there an alternative way?

Cheers

Sergio Bossa

unread,
Nov 13, 2009, 3:57:11 AM11/13/09
to Stefan Weber, actorom-discussions
On Fri, Nov 13, 2009 at 9:45 AM, Stefan Weber <stefan...@gmail.com> wrote:

> Tried to access the read-only repo but svn complained that it cannot connect
> to the server.

What command did you issue?

Sergio Bossa

unread,
Nov 13, 2009, 3:57:52 AM11/13/09
to Stefan Weber, actorom-discussions
Anyways, please open an new thread for unrelated problems ... thanks :)

Scott Pfister

unread,
Dec 14, 2009, 4:53:24 PM12/14/09
to actorom-discussions
Stefan,

I've begun working on this and hope to have something you can check
out in the trunk in the next couple of days.

Best,

--Scott

On Nov 13, 2:06 am, Stefan Weber <stefan.we...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages