hemant | 14 Oct 02:17
Gravatar

Actor and blocking IO calls

The arrangement:

* Master Actor which start a server on given port

* DataActor (handles, certain type, but not all, incoming requests)
  act() of DataActor looks like following. Also, there will be
  only one instance of DataActor for this app.

        loop = {
          receiveWithin(10) {
             case data: Foo => processFoo(data)
             case bar: Bar => processBar(data)
             case _ => doSomeHouseKeeping()
          }
        }
       def processFoo(data: Foo) = {
         // processing of foo usually needs another Actor, just for this session
         val fooActor = allFooActors.getOrElseUpdate(data.session,new
FooActor())
       }

* FooActor:
    loop = {
      receiveWithin(10) {
         case data: Foo => openBlockingChannelForFoo()
         case Actor.stop => stopThis()
         case _ => readFromBlockingChannel()
      }
    }
   def openBlockingChannel() = //opens a HttpURLConnection, which may block
(Continue reading)

Philipp Haller | 15 Oct 17:19
Favicon

Re: Actor and blocking IO calls

>   1. If I use receiveWithin in DataActor, somehow, FooActor is not getting
>      chance to run. I can see, FooActor being intitialized and all, but
>      it never really runs (or in other words, I can't see, instance of FooActor
>      processing messages.)
>      This gets fixed, if i use react() in DataActor's act() method. But,
>      since react() will block when waiting for messages, I won't be able
>      to run housekeeping chores in that Actor.

Note that `reactWithin` behaves like `receiveWithin` except that it does
not return. So, if you can live with that restriction, then it should
not make a difference which one you use.

>   2. As mentioned above, FooActor contains lots of blocking IO calls and I
>      have observed the behaviour that, multiple instances of FooActor()
>      aren't running concurrently. Meaning, if more than one instance
>      of FooActor exists, application behaves in very non-deterministic
>      manner. How to solve this? As in is this intended? Since, I read
>      actor callbacks, should be essentially nonblocking, but if we are
>      using say blocking IO, some Actor is going to block and it should
>      not halt, other Actors, right?

Right, an actor that blocks should never prevent other actors from
making progress.
You can try to set the following properties to higher values, so that
the thread pool, which is used to run actors, is populated with more
worker threads initially, e.g.:
  -Dactors.corePoolSize=16
  -Dactors.maxPoolSize=256

In general, the number of actors that may block their thread should be
(Continue reading)

hemant | 16 Oct 10:59
Gravatar

Re: Actor and blocking IO calls

On Wed, Oct 15, 2008 at 8:49 PM, Philipp Haller <philipp.haller <at> epfl.ch> wrote:
>>   1. If I use receiveWithin in DataActor, somehow, FooActor is not getting
>>      chance to run. I can see, FooActor being intitialized and all, but
>>      it never really runs (or in other words, I can't see, instance of FooActor
>>      processing messages.)
>>      This gets fixed, if i use react() in DataActor's act() method. But,
>>      since react() will block when waiting for messages, I won't be able
>>      to run housekeeping chores in that Actor.
>
> Note that `reactWithin` behaves like `receiveWithin` except that it does
> not return. So, if you can live with that restriction, then it should
> not make a difference which one you use.
>
>>   2. As mentioned above, FooActor contains lots of blocking IO calls and I
>>      have observed the behaviour that, multiple instances of FooActor()
>>      aren't running concurrently. Meaning, if more than one instance
>>      of FooActor exists, application behaves in very non-deterministic
>>      manner. How to solve this? As in is this intended? Since, I read
>>      actor callbacks, should be essentially nonblocking, but if we are
>>      using say blocking IO, some Actor is going to block and it should
>>      not halt, other Actors, right?
>
> Right, an actor that blocks should never prevent other actors from
> making progress.
> You can try to set the following properties to higher values, so that
> the thread pool, which is used to run actors, is populated with more
> worker threads initially, e.g.:
>  -Dactors.corePoolSize=16
>  -Dactors.maxPoolSize=256
>
(Continue reading)


Gmane