Akka 2.0-M4: how can I run every new actor on a dedicated thread

143 views
Skip to first unread message

Vasil Remeniuk

unread,
Feb 13, 2012, 1:49:49 AM2/13/12
to Akka User List
Hello, Hakkers!

I'm trying out Akka 2.0-M4 at one of my old Java projects.
My aim is to run every actor an a dedicated thread, so that the thread
is tied to actor's lifecycle (created, when the actor is started, and
destroyed, when the actor is removed).

In Akka 1.3 I can assign every new actor it's own single threaded
dispatcher:

class MyActor extends UntypedActor {
public MyActor() {

getContext().setDispatcher(Dispatchers.newThreadBasedDispatcher(getContext()));
}
...
}

In Akka 2.0 dispatchers are created through config, and assigned to
actors via Props:

private static Config BOT_DISPATCHER_CONFIG =
ConfigFactory.parseString(String.format("%s {\n" +
" executor = \"thread-pool-executor\"\n" +
" type = PinnedDispatcher\n" +
"}", BOT_DISPATCHER));

public static ActorSystem actorSystem =
ActorSystem.create("botActorSystem",
ConfigFactory.load(BOT_DISPATCHER_CONFIG));

ActorRef bot = actorSystem.actorOf(new Props(new
UntypedActorFactory() {
public UntypedActor create() {
return new Bot(playerLogin, "123456", 2,
clientEmulator);
}
}).withDispatcher(BotManager.BOT_DISPATCHER),
playerLogin);

In my tests I expect to see actors running at their own threads, but
what's happening however is that all actors are sharing one thread.
How can I achieve 1.3-like behavior, assigning new dispatcher to every
new actor?

Brg,
Vasil

Roland Kuhn

unread,
Feb 13, 2012, 2:27:20 AM2/13/12
to akka...@googlegroups.com
Hi Vasil,

On 13 feb 2012, at 07:49, Vasil Remeniuk <vasil.r...@gmail.com> wrote:

> Hello, Hakkers!
>
> I'm trying out Akka 2.0-M4 at one of my old Java projects.
> My aim is to run every actor an a dedicated thread, so that the thread
> is tied to actor's lifecycle (created, when the actor is started, and
> destroyed, when the actor is removed).
>

This is not strictly true even in 1.3, since the thread will be released after the shutdown-timeout (and recreated on demand).

That is not currently possible, because it is hard to imagine a valid use case for this kind of setup. What is the problem that this solves and which is not solvable otherwise?

Regards,

Roland Kuhn
Typesafe — The software stack for applications that scale
twitter: @rolandkuhn

Vasil Remeniuk

unread,
Feb 13, 2012, 3:01:04 AM2/13/12
to Akka User List
Hi Roland,

>> This is not strictly true even in 1.3, since the thread will be released after the shutdown-timeout (and recreated on demand).

As far as I understand, from the documentation, dispatcher releases
the thread, only when the actor goes down (unregisters itself). I can
live with it :)

>> That is not currently possible, because it is hard to imagine a valid use case for this kind of setup. What is the problem that this solves and which is not solvable otherwise?

I'm trying to implement bots, for a quite sophisticated game server,
with actors. I don't quite understand (and don't actually want to :) )
all the chemistry that happens inside the server, but the server
doesn't allow bots/actors to share one thread.

In the legacy, bots were straighforwardly running on a dedicated
threads (new Thread(...).start()).

Thanks,
Vasil

On Feb 13, 10:27 am, Roland Kuhn <goo...@rkuhn.info> wrote:
> Hi Vasil,
>

rkuhn

unread,
Feb 13, 2012, 3:13:16 AM2/13/12
to akka...@googlegroups.com
Hi Vasil,


Am Montag, 13. Februar 2012 09:01:04 UTC+1 schrieb Vasil Remeniuk:
Hi Roland,

>> This is not strictly true even in 1.3, since the thread will be released after the shutdown-timeout (and recreated on demand).

As far as I understand, from the documentation, dispatcher releases
the thread, only when the actor goes down (unregisters itself). I can
live with it :)


Ah, sorry, you are right, of course.
 
>> That is not currently possible, because it is hard to imagine a valid use case for this kind of setup. What is the problem that this solves and which is not solvable otherwise?

I'm trying to implement bots, for a quite sophisticated game server,
with actors. I don't quite understand (and don't actually want to :) )
all the chemistry that happens inside the server, but the server
doesn't allow bots/actors to share one thread.

So, what you’re saying is that you are calling from the actors into an API which keeps thread-local state across calls. Normally my reaction would be “ditch it!”, but I can guess your answer ;-)
 
In the legacy, bots were straighforwardly running on a dedicated
threads (new Thread(...).start()).

I’m curious to know what the key features were of Akka which made you use it for this very peculiar project.

On the solution front, it might be a bit more involved than it seems at first sight.

Regards,

Roland

Vasil Remeniuk

unread,
Feb 13, 2012, 3:35:25 AM2/13/12
to Akka User List
>>I’m curious to know what the key features were of Akka which made you use it for this very peculiar project.

The problem with current implementation of bots is that once they are
started (vie new Thread(...).start()), you completely lose control
over them. I can certainly, manually add a queue/mailbox to every
thread, add my own message system, etc., to make bots more interactive
and controllable, but I'd prefer to use Akka API that I've got used
to :)

Thanks for your help! I think, I'll try to downgrade to 1.3.

Thanks,
Vasil

√iktor Ҡlang

unread,
Feb 13, 2012, 3:46:36 AM2/13/12
to akka...@googlegroups.com
using a PinnedDispatcher for your actors should given them their own threads.
If you need to configure further you need to tweak the shutdown timeout and the allow-core-timeout.

Cheers,


--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.




--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

rkuhn

unread,
Feb 13, 2012, 4:10:45 AM2/13/12
to akka...@googlegroups.com


Am Montag, 13. Februar 2012 09:35:25 UTC+1 schrieb Vasil Remeniuk:
>>I’m curious to know what the key features were of Akka which made you use it for this very peculiar project.

The problem with current implementation of bots is that once they are
started (vie new Thread(...).start()), you completely lose control
over them. I can certainly, manually add a queue/mailbox to every
thread, add my own message system, etc., to make bots more interactive
and controllable, but I'd prefer to use Akka API that I've got used
to :)

Okay, that’s what I thought, but good to confirm assumptions from time to time ;-)
 
Thanks for your help! I think, I'll try to downgrade to 1.3.

Hold on a second, Viktor just showed me that the code is indeed intended to work as you expect. Could you share a failing test case?

Regards,

Roland

Vasil Remeniuk

unread,
Feb 13, 2012, 4:42:48 AM2/13/12
to Akka User List
>> Could you share a failing test case?

Sure, will do later -- will take some time to extract it from the
code.

But, generally, I'm not doing anything special:

1) I create an actor:
private static Config BOT_DISPATCHER_CONFIG =
ConfigFactory.parseString(String.format("%s {\n" +
" executor = \"thread-pool-executor\"\n" +
" type = PinnedDispatcher\n" +
"}", BOT_DISPATCHER));

ActorRef bot = BotManager.actorSystem.actorOf(new
Props(new UntypedActorFactory() {
public UntypedActor create() {
return new Bot(playerLogin, "123456", 2,
clientEmulator);
}
}).withDispatcher(BotManager.BOT_DISPATCHER),
playerLogin);

2) In actor's constructor I create a login message, and send it to
`self`:

public Bot(String login, String password, int operatorId,
ClientEmulator clientEmulator) {
this.login = login;
this.password = password;
this.operatorId = operatorId;
this.clientEmulator = clientEmulator;
self().tell(new BotEvent.Login());
}

3) When I process the login message, I see that the thread is same for
all actors:

final private Procedure<Object> IDLE_BEHAVIOR = new
Procedure<Object>() {
@Override
public void apply(Object o) {
if (o instanceof BotEvent.Login) login();
//...
else unhandled(o);
}
};

@Override
public void onReceive(Object o) throws Exception {
IDLE_BEHAVIOR.apply(o);
}

public void login() {
//....
LOG.info(String.format("%s: %s\t[%sms]",
Thread.currentThread().getName(), // <-- prints
the same thread for all actors
Thread.currentThread().getStackTrace()
[3].getMethodName(),
stopwatch.stop().elapsedMillis()));
}

Thanks for the help, again!

--Vasil

√iktor Ҡlang

unread,
Feb 13, 2012, 4:49:00 AM2/13/12
to akka...@googlegroups.com
How do you know it's the same thread? Have you've checked JConsole?

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.




--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Vasil Remeniuk

unread,
Feb 13, 2012, 4:58:24 AM2/13/12
to Akka User List
I print `Thread.currentThread().getName()` to the logs, when actor
processes the message, and always see the same thread name.
When I use another dispatcher (any event-based), thread names in the
log are different.

On Feb 13, 12:49 pm, √iktor Ҡlang <viktor.kl...@gmail.com> wrote:
> How do you know it's the same thread? Have you've checked JConsole?
>
> On Mon, Feb 13, 2012 at 10:42 AM, Vasil Remeniuk
> <vasil.remen...@gmail.com>wrote:
> Typesafe <http://www.typesafe.com/> - The software stack for applications
> that scale
>
> Twitter: @viktorklang

√iktor Ҡlang

unread,
Feb 13, 2012, 5:05:52 AM2/13/12
to akka...@googlegroups.com
On Mon, Feb 13, 2012 at 10:58 AM, Vasil Remeniuk <vasil.r...@gmail.com> wrote:
I print `Thread.currentThread().getName()` to the logs, when actor
processes the message, and always see the same thread name.
When I use another dispatcher (any event-based), thread names in the
log are different.

So what you're saying is that it is threads with  the same name, could you please verify that it is the _same_ thread.



--
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Vasil Remeniuk

unread,
Feb 13, 2012, 5:20:52 AM2/13/12
to Akka User List
Aaah, stupid me. Please excuse me, guys -- thread IDs are indeed
different (one thread ID per actor).

Thx&sorry,
Vasil

On Feb 13, 1:05 pm, √iktor Ҡlang <viktor.kl...@gmail.com> wrote:
> On Mon, Feb 13, 2012 at 10:58 AM, Vasil Remeniuk
> <vasil.remen...@gmail.com>wrote:

Jonas Bonér

unread,
Feb 13, 2012, 5:25:34 AM2/13/12
to akka...@googlegroups.com
On Mon, Feb 13, 2012 at 11:20 AM, Vasil Remeniuk
<vasil.r...@gmail.com> wrote:
> Aaah, stupid me. Please excuse me, guys -- thread IDs are indeed
> different (one thread ID per actor).

LOL. Running into Viktor can be a brutal reality check.

As the swedish saying goes: Viktor "släpper ingen jävel över bron".

--
Jonas Bonér
CTO
Typesafe - The software stack for applications that scale
Phone: +46 733 777 123
Twitter: @jboner

Christer Sandberg

unread,
Feb 13, 2012, 6:35:12 AM2/13/12
to akka...@googlegroups.com
Jag som är svensk skrattade ljudligt åt din kommentar Jonas ;)

√iktor Ҡlang

unread,
Feb 13, 2012, 7:25:15 AM2/13/12
to akka...@googlegroups.com
On Mon, Feb 13, 2012 at 11:20 AM, Vasil Remeniuk <vasil.r...@gmail.com> wrote:
Aaah, stupid me. Please excuse me, guys -- thread IDs are indeed
different (one thread ID per actor).

Happy hAkking!



--
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Mike Slinn

unread,
Feb 13, 2012, 8:37:38 AM2/13/12
to akka...@googlegroups.com
That is quite some saying ;)

Mike

Bernd Johannes

unread,
Feb 18, 2012, 7:25:22 AM2/18/12
to akka...@googlegroups.com, Roland Kuhn

Am Montag, 13. Februar 2012, 08:27:20 schrieb Roland Kuhn:

> Hi Vasil,

>

> On 13 feb 2012, at 07:49, Vasil Remeniuk <vasil.r...@gmail.com> wrote:

> > Hello, Hakkers!

> >

> > I'm trying out Akka 2.0-M4 at one of my old Java projects.

> > My aim is to run every actor an a dedicated thread, so that the thread

> > is tied to actor's lifecycle (created, when the actor is started, and

> > destroyed, when the actor is removed).

>

> This is not strictly true even in 1.3, since the thread will be released

> after the shutdown-timeout (and recreated on demand).


I'm currently struggling with this kind of thing as well. I spawn a "dedicated thread" worker to open a SWT session to do some "background" drawing which I do not want to execute on the GUI thread because it takes to much time to draw the image.

Akka works like a charm - appart from the issue that if the worker has nothing to do for an extended period of time it silently terminates its thread. When I stop the system the worker reawakes in postStop() to free its system resources - but sometimes on a different thread.

This causes SWT to complain because it cannot free its resources because SWT is always bound to exactly one thread (the one who called display.open()) and it does not support thread switching.


I was a little surprised by this because I thought that a "PinnedDispatcher" is exactly what I need. This causes me quite some headache as I didn't find a workaround yet.


And I think it qualifies as "use case" :-)


Greetings

Bernd

rkuhn

unread,
Feb 18, 2012, 7:49:07 AM2/18/12
to akka...@googlegroups.com, Roland Kuhn


Am Samstag, 18. Februar 2012 13:25:22 UTC+1 schrieb Bernd:

Am Montag, 13. Februar 2012, 08:27:20 schrieb Roland Kuhn:

> Hi Vasil,

>

> On 13 feb 2012, at 07:49, Vasil Remeniuk <vasil.r...@gmail.com> wrote:

> > Hello, Hakkers!

> >

> > I'm trying out Akka 2.0-M4 at one of my old Java projects.

> > My aim is to run every actor an a dedicated thread, so that the thread

> > is tied to actor's lifecycle (created, when the actor is started, and

> > destroyed, when the actor is removed).

>

> This is not strictly true even in 1.3, since the thread will be released

> after the shutdown-timeout (and recreated on demand).


I'm currently struggling with this kind of thing as well. I spawn a "dedicated thread" worker to open a SWT session to do some "background" drawing which I do not want to execute on the GUI thread because it takes to much time to draw the image.

Akka works like a charm - appart from the issue that if the worker has nothing to do for an extended period of time it silently terminates its thread. When I stop the system the worker reawakes in postStop() to free its system resources - but sometimes on a different thread.

This causes SWT to complain because it cannot free its resources because SWT is always bound to exactly one thread (the one who called display.open()) and it does not support thread switching.


Ah, so I was not actually wrong in my previous post ;-)
 

I was a little surprised by this because I thought that a "PinnedDispatcher" is exactly what I need. This causes me quite some headache as I didn't find a workaround yet.


I checked, and the PinnedDispatcher explicitly sets allowCorePoolTimeout to `true` in order to save resources, which explains your observation. So either you create your own PinnedDispatcher (looking at the built-in one you can see that this is trivial), or set keep-alive-time for that dispatcher to a very large duration.

Regards,

Roland

√iktor Ҡlang

unread,
Feb 18, 2012, 7:55:23 AM2/18/12
to akka...@googlegroups.com, Roland Kuhn
Or you just use a normal Dispatcher with a core-pool size of 1, and without allowCorePoolTimeout.

Profit.

Cheers,


--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/s6xEqFPYOTIJ.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Roland Kuhn

unread,
Feb 18, 2012, 7:58:31 AM2/18/12
to √iktor Ҡlang, akka...@googlegroups.com
But doesn’t this mean that multiple actors using the same dispatcher-id will then share a thread?

Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn


√iktor Ҡlang

unread,
Feb 18, 2012, 8:29:00 AM2/18/12
to Roland Kuhn, akka...@googlegroups.com


2012/2/18 Roland Kuhn <goo...@rkuhn.info>

But doesn’t this mean that multiple actors using the same dispatcher-id will then share a thread?

Yes, I conveniently left out that you need to write your own MessageDisaptcherConfigurator :p

√iktor Ҡlang

unread,
Feb 18, 2012, 8:31:57 AM2/18/12
to Roland Kuhn, akka...@googlegroups.com
But:


uses configureExecutor()


So if you just configure your thread-pool-executor section of the dispatcher, it should just work with PinnedDispatcher and turning off allowCorePoolTimeout?

Cheers,


2012/2/18 √iktor Ҡlang <viktor...@gmail.com>

rkuhn

unread,
Feb 18, 2012, 8:40:28 AM2/18/12
to akka...@googlegroups.com, Roland Kuhn


Am Samstag, 18. Februar 2012 14:31:57 UTC+1 schrieb Viktor Klang:
But:


uses configureExecutor()


So if you just configure your thread-pool-executor section of the dispatcher, it should just work with PinnedDispatcher and turning off allowCorePoolTimeout?

That property is unfortunately overridden here:

https://github.com/jboner/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/PinnedDispatcher.scala#L28

so setting a large timeout is the only thing possible without subclassing.

Regards,

Roland
 
Cheers,


2012/2/18 √iktor Ҡlang <viktor...@gmail.com>




To unsubscribe from this group, send email to akka-user+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.



--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn





--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

√iktor Ҡlang

unread,
Feb 18, 2012, 8:45:51 AM2/18/12
to akka...@googlegroups.com
On Sat, Feb 18, 2012 at 2:40 PM, rkuhn <goo...@rkuhn.info> wrote:


Am Samstag, 18. Februar 2012 14:31:57 UTC+1 schrieb Viktor Klang:
But:


uses configureExecutor()


So if you just configure your thread-pool-executor section of the dispatcher, it should just work with PinnedDispatcher and turning off allowCorePoolTimeout?

That property is unfortunately overridden here:

https://github.com/jboner/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/PinnedDispatcher.scala#L28

so setting a large timeout is the only thing possible without subclassing.

Hmmm, we should potentially rectify that.
 
To view this discussion on the web visit https://groups.google.com/d/msg/akka-user/-/QcdINYozTRYJ.

To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.

Bernd Johannes

unread,
Feb 18, 2012, 12:51:50 PM2/18/12
to akka...@googlegroups.com, √iktor Ҡlang

Am Samstag, 18. Februar 2012, 14:45:51 schrieb √iktor Ҡlang:


Hi Guys,


thanks for all the good hints, so I see I have hope to solve this (I am VERY new to akka - since M4 :-)


Greetings

Bernd


> On Sat, Feb 18, 2012 at 2:40 PM, rkuhn <goo...@rkuhn.info> wrote:

> > Am Samstag, 18. Februar 2012 14:31:57 UTC+1 schrieb Viktor Klang:

> >> But:

> >>

> >> https://github.com/jboner/**akka/blob/master/akka-actor/**

> >> src/main/scala/akka/dispatch/**Dispatchers.scala#L206<https://github.com

> >> /jboner/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/Dispatc

> >> hers.scala#L206>

> >>

> >> uses configureExecutor()

> >>

> >> https://github.com/jboner/**akka/blob/master/akka-actor/**

> >> src/main/scala/akka/dispatch/**AbstractDispatcher.scala#L395<https://git

> >> hub.com/jboner/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/

> >> AbstractDispatcher.scala#L395>

> >>>>> https://groups.google.com/d/*

> >>>>> *msg/akka-user/-/s6xEqFPYOTIJ<https://groups.google.com/d/msg/akka-u

> >>>>> ser/-/s6xEqFPYOTIJ> .

> >>>>>

> >>>>> To post to this group, send email to akka...@googlegroups.com.

> >>>>> To unsubscribe from this group, send email to

> >>>>> akka-user+unsubscribe@** googlegroups.com

> >>>>> <akka-user%2Bunsu...@googlegroups.com>. For more options, visit

> >>>>> this group at http://groups.google.com/** group/akka-user?hl=en

> >>>>> <http://groups.google.com/group/akka-user?hl=en> .

> >>>>

> >>>> --

> >>>> Viktor Klang

> >>>>

> >>>> Akka Tech Lead

> >>>> Typesafe <http://www.typesafe.com/> - The software stack for

> >>>> applications that scale

> >>>>

> >>>> Twitter: @viktorklang

> >>>>

> >>>> Roland Kuhn

> >>>>

> >>>> Typesafe <http://typesafe.com/> – The software stack for applications

> >>>> that scale.

> >>>> twitter: @rolandkuhn <http://twitter.com/#%21/rolandkuhn>

> >>>

> >>> --

> >>> Viktor Klang

> >>>

> >>> Akka Tech Lead

> >>> Typesafe <http://www.typesafe.com/> - The software stack for

> >>> applications that scale

> >>>

> >>> Twitter: @viktorklang

> >>

> >> --

> >> Viktor Klang

> >>

> >> Akka Tech Lead

> >> Typesafe <http://www.typesafe.com/> - The software stack for

Reply all
Reply to author
Forward
0 new messages