- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Actor B spawned from Actor A may block ActorA ?!
Tue, 2010-08-31, 23:14
hi,
i am having a problem with scala actors :
- everything is done using the loop / react framework
- i have a message receiver actor that invokes handlers which can be registered with that receiver
- there is a handler A which sends out a new message, registers a new handler, gets a future
which is satisfied by that new handler, and calls Futures.awaitAll on that one
now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
happening fine in its own thread.
_but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
actor independant of the thread it was created from, it seems.
this is really bad of course. my shitty workaround now is to defer the handler reaction A with
EventQueue.invokeLater, and the problem is gone.
so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
doesn't produce a problem in the actor body it was created from.
is there a way to guarantee this independance?
note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
i had problems of deadlocks when using actors in blocking I/O.
thanks for help.
best, -sciss-
Wed, 2010-09-01, 00:07
#2
Re: Actor B spawned from Actor A may block ActorA ?!
it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
that is, Actor.actors { } doesn't execute the actor bodies any more.
so were is the flaw? is it Futures.awaitAll?
can i set some property that allows the number of actors to grow without problem?
thanks, -sciss-
Am 31.08.2010 um 23:30 schrieb Sciss:
> like this:
>
> object Schnuck extends actors.DaemonActor {
> var handler: Function0[ Unit ] = () => ()
> def act { loop { react {
> case "gaga" => reply( "gugu" )
> case "lala" => handler()
> }}}
> }
>
> Schnuck.start
>
> Schnuck.handler = () => {
> val fut = Schnuck !! "gaga"
> actors.Futures.awaitAll( 1000L, fut ) match {
> case List( Some( "gugu" )) => println( "SUCCESS" )
> case _ => println( "TIMEOUT" )
> }
> }
>
> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>
> Schnuck.handler = () => {
> actors.Actor.actor { // this should make us independant or not?
> val fut = Schnuck !! "gaga"
> actors.Futures.awaitAll( 1000L, fut ) match {
> case List( Some( "gugu" )) => println( "SUCCESS" )
> case _ => println( "TIMEOUT" )
> }
> }
> }
>
> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>
> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>
> thanks, -sciss-
>
>
>
> Am 31.08.2010 um 23:15 schrieb Sciss:
>
>> hi,
>>
>> i am having a problem with scala actors :
>> - everything is done using the loop / react framework
>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>
>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>
>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>> happening fine in its own thread.
>>
>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>> actor independant of the thread it was created from, it seems.
>>
>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>> EventQueue.invokeLater, and the problem is gone.
>>
>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>> doesn't produce a problem in the actor body it was created from.
>>
>> is there a way to guarantee this independance?
>>
>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>> i had problems of deadlocks when using actors in blocking I/O.
>>
>> thanks for help.
>>
>> best, -sciss-
>>
>
Wed, 2010-09-01, 00:27
#3
Re: Actor B spawned from Actor A may block ActorA ?!
if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
too. so something like
case class Fun( f: () => Unit )
case "lala" => handlerActor ! Fun( handler )
and handlerActor = new DaemonActor {
def act { loop { react {
case Fun( f ) => f()
}
}
...
ciao, -sciss-
Am 31.08.2010 um 23:54 schrieb Sciss:
> it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
> and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
> that is, Actor.actors { } doesn't execute the actor bodies any more.
>
> so were is the flaw? is it Futures.awaitAll?
>
> can i set some property that allows the number of actors to grow without problem?
>
> thanks, -sciss-
>
>
> Am 31.08.2010 um 23:30 schrieb Sciss:
>
>> like this:
>>
>> object Schnuck extends actors.DaemonActor {
>> var handler: Function0[ Unit ] = () => ()
>> def act { loop { react {
>> case "gaga" => reply( "gugu" )
>> case "lala" => handler()
>> }}}
>> }
>>
>> Schnuck.start
>>
>> Schnuck.handler = () => {
>> val fut = Schnuck !! "gaga"
>> actors.Futures.awaitAll( 1000L, fut ) match {
>> case List( Some( "gugu" )) => println( "SUCCESS" )
>> case _ => println( "TIMEOUT" )
>> }
>> }
>>
>> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>>
>> Schnuck.handler = () => {
>> actors.Actor.actor { // this should make us independant or not?
>> val fut = Schnuck !! "gaga"
>> actors.Futures.awaitAll( 1000L, fut ) match {
>> case List( Some( "gugu" )) => println( "SUCCESS" )
>> case _ => println( "TIMEOUT" )
>> }
>> }
>> }
>>
>> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>>
>> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>>
>> thanks, -sciss-
>>
>>
>>
>> Am 31.08.2010 um 23:15 schrieb Sciss:
>>
>>> hi,
>>>
>>> i am having a problem with scala actors :
>>> - everything is done using the loop / react framework
>>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>>
>>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>>
>>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>>> happening fine in its own thread.
>>>
>>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>>> actor independant of the thread it was created from, it seems.
>>>
>>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>>> EventQueue.invokeLater, and the problem is gone.
>>>
>>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>>> doesn't produce a problem in the actor body it was created from.
>>>
>>> is there a way to guarantee this independance?
>>>
>>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>>> i had problems of deadlocks when using actors in blocking I/O.
>>>
>>> thanks for help.
>>>
>>> best, -sciss-
>>>
>>
>
Wed, 2010-09-01, 01:47
#4
Re: Actor B spawned from Actor A may block ActorA ?!
I only use Akka actors and not Scala actors, but an issue I see is
that you are creating a new actor each time the handler is run which
might be causing your problems. Does something like this work for you?
Schnuck.handler = () => {
actors.Actor.actor {
val fut = Schnuck !! "gaga"
actors.Futures.awaitAll( 1000L, fut ) match {
case List( Some( "gugu" )) => println( "SUCCESS" )
case _ => println( "TIMEOUT" )
}
actors.Actor.exit() // stop the current actor once done
}
}
These examples are obviously not a good representation of your full
app so it is difficult to provide a better solution, but in general it
is usually best for actors (especially when using react) to
communicate with each other using messages instead of waiting for the
results of futures. How best to do this depends on what it is you are
actually doing with these messages, as this example only shows your
handlers printing to the screen (so, only side effects). Is this true
of your actual app as well?
On Tue, Aug 31, 2010 at 5:12 PM, Sciss wrote:
> if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
> too. so something like
>
> case class Fun( f: () => Unit )
>
> case "lala" => handlerActor ! Fun( handler )
>
> and handlerActor = new DaemonActor {
> def act { loop { react {
> case Fun( f ) => f()
> }
> }
>
> ...
>
> ciao, -sciss-
>
>
> Am 31.08.2010 um 23:54 schrieb Sciss:
>
>> it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
>> and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
>> that is, Actor.actors { } doesn't execute the actor bodies any more.
>>
>> so were is the flaw? is it Futures.awaitAll?
>>
>> can i set some property that allows the number of actors to grow without problem?
>>
>> thanks, -sciss-
>>
>>
>> Am 31.08.2010 um 23:30 schrieb Sciss:
>>
>>> like this:
>>>
>>> object Schnuck extends actors.DaemonActor {
>>> var handler: Function0[ Unit ] = () => ()
>>> def act { loop { react {
>>> case "gaga" => reply( "gugu" )
>>> case "lala" => handler()
>>> }}}
>>> }
>>>
>>> Schnuck.start
>>>
>>> Schnuck.handler = () => {
>>> val fut = Schnuck !! "gaga"
>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>> case _ => println( "TIMEOUT" )
>>> }
>>> }
>>>
>>> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>>>
>>> Schnuck.handler = () => {
>>> actors.Actor.actor { // this should make us independant or not?
>>> val fut = Schnuck !! "gaga"
>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>> case _ => println( "TIMEOUT" )
>>> }
>>> }
>>> }
>>>
>>> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>>>
>>> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>>>
>>> thanks, -sciss-
>>>
>>>
>>>
>>> Am 31.08.2010 um 23:15 schrieb Sciss:
>>>
>>>> hi,
>>>>
>>>> i am having a problem with scala actors :
>>>> - everything is done using the loop / react framework
>>>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>>>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>>>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>>>
>>>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>>>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>>>
>>>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>>>> happening fine in its own thread.
>>>>
>>>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>>>> actor independant of the thread it was created from, it seems.
>>>>
>>>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>>>> EventQueue.invokeLater, and the problem is gone.
>>>>
>>>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>>>> doesn't produce a problem in the actor body it was created from.
>>>>
>>>> is there a way to guarantee this independance?
>>>>
>>>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>>>> i had problems of deadlocks when using actors in blocking I/O.
>>>>
>>>> thanks for help.
>>>>
>>>> best, -sciss-
>>>>
>>>
>>
>
>
Wed, 2010-09-01, 01:47
#5
Re: Actor B spawned from Actor A may block ActorA ?!
i don't think scala actors have an explicit exit method. as soon as their "act" method is left, they should exit by themselves and be garbage-collected. at least that's my understanding.
Am 01.09.2010 um 01:36 schrieb Derek Williams:
> I only use Akka actors and not Scala actors, but an issue I see is
> that you are creating a new actor each time the handler is run which
> might be causing your problems. Does something like this work for you?
>
> Schnuck.handler = () => {
> actors.Actor.actor {
> val fut = Schnuck !! "gaga"
> actors.Futures.awaitAll( 1000L, fut ) match {
> case List( Some( "gugu" )) => println( "SUCCESS" )
> case _ => println( "TIMEOUT" )
> }
> actors.Actor.exit() // stop the current actor once done
> }
> }
>
> These examples are obviously not a good representation of your full
> app so it is difficult to provide a better solution, but in general it
> is usually best for actors (especially when using react) to
> communicate with each other using messages instead of waiting for the
> results of futures. How best to do this depends on what it is you are
> actually doing with these messages, as this example only shows your
> handlers printing to the screen (so, only side effects). Is this true
> of your actual app as well?
>
> On Tue, Aug 31, 2010 at 5:12 PM, Sciss wrote:
>> if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
>> too. so something like
>>
>> case class Fun( f: () => Unit )
>>
>> case "lala" => handlerActor ! Fun( handler )
>>
>> and handlerActor = new DaemonActor {
>> def act { loop { react {
>> case Fun( f ) => f()
>> }
>> }
>>
>> ...
>>
>> ciao, -sciss-
>>
>>
>> Am 31.08.2010 um 23:54 schrieb Sciss:
>>
>>> it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
>>> and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
>>> that is, Actor.actors { } doesn't execute the actor bodies any more.
>>>
>>> so were is the flaw? is it Futures.awaitAll?
>>>
>>> can i set some property that allows the number of actors to grow without problem?
>>>
>>> thanks, -sciss-
>>>
>>>
>>> Am 31.08.2010 um 23:30 schrieb Sciss:
>>>
>>>> like this:
>>>>
>>>> object Schnuck extends actors.DaemonActor {
>>>> var handler: Function0[ Unit ] = () => ()
>>>> def act { loop { react {
>>>> case "gaga" => reply( "gugu" )
>>>> case "lala" => handler()
>>>> }}}
>>>> }
>>>>
>>>> Schnuck.start
>>>>
>>>> Schnuck.handler = () => {
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>>>>
>>>> Schnuck.handler = () => {
>>>> actors.Actor.actor { // this should make us independant or not?
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>>>>
>>>> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>>>>
>>>> thanks, -sciss-
>>>>
>>>>
>>>>
>>>> Am 31.08.2010 um 23:15 schrieb Sciss:
>>>>
>>>>> hi,
>>>>>
>>>>> i am having a problem with scala actors :
>>>>> - everything is done using the loop / react framework
>>>>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>>>>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>>>>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>>>>
>>>>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>>>>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>>>>
>>>>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>>>>> happening fine in its own thread.
>>>>>
>>>>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>>>>> actor independant of the thread it was created from, it seems.
>>>>>
>>>>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>>>>> EventQueue.invokeLater, and the problem is gone.
>>>>>
>>>>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>>>>> doesn't produce a problem in the actor body it was created from.
>>>>>
>>>>> is there a way to guarantee this independance?
>>>>>
>>>>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>>>>> i had problems of deadlocks when using actors in blocking I/O.
>>>>>
>>>>> thanks for help.
>>>>>
>>>>> best, -sciss-
>>>>>
>>>>
>>>
>>
>>
>
>
>
Wed, 2010-09-01, 01:57
#6
Re: Actor B spawned from Actor A may block ActorA ?!
On Tue, Aug 31, 2010 at 5:12 PM, Sciss wrote:
> if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
> too. so something like
>
> case class Fun( f: () => Unit )
>
> case "lala" => handlerActor ! Fun( handler )
>
> and handlerActor = new DaemonActor {
> def act { loop { react {
> case Fun( f ) => f()
> }
> }
>
I missed this one. This is more like what I was suggesting. If your
handlerActor will be doing any blocking, and if you have more then 1
of these handlers, it is probably best to use receive instead of react
inside of it. If you are just going to have the one, or you are not
going to be blocking then it should be fine as is.
Wed, 2010-09-01, 02:07
#7
Re: Actor B spawned from Actor A may block ActorA ?!
thing is, i am actually spawing CCSTM transactions, so with this workaround the beauty is kind of lost, as i'm returning from parallelism which the STM explicitly supports to basically a single-threaded linearity (there won't be any concurrent transactions any more). this is ok in my current setup, but a bit sad though...
also, i'm not really doing "blocking I/O" here, i mean Future.await should suspend the actor, but isn't actually doing any real blocking I/O. so i don't know what's going on there.
best, -sciss-
Am 01.09.2010 um 01:36 schrieb Derek Williams:
> I only use Akka actors and not Scala actors, but an issue I see is
> that you are creating a new actor each time the handler is run which
> might be causing your problems. Does something like this work for you?
>
> Schnuck.handler = () => {
> actors.Actor.actor {
> val fut = Schnuck !! "gaga"
> actors.Futures.awaitAll( 1000L, fut ) match {
> case List( Some( "gugu" )) => println( "SUCCESS" )
> case _ => println( "TIMEOUT" )
> }
> actors.Actor.exit() // stop the current actor once done
> }
> }
>
> These examples are obviously not a good representation of your full
> app so it is difficult to provide a better solution, but in general it
> is usually best for actors (especially when using react) to
> communicate with each other using messages instead of waiting for the
> results of futures. How best to do this depends on what it is you are
> actually doing with these messages, as this example only shows your
> handlers printing to the screen (so, only side effects). Is this true
> of your actual app as well?
>
> On Tue, Aug 31, 2010 at 5:12 PM, Sciss wrote:
>> if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
>> too. so something like
>>
>> case class Fun( f: () => Unit )
>>
>> case "lala" => handlerActor ! Fun( handler )
>>
>> and handlerActor = new DaemonActor {
>> def act { loop { react {
>> case Fun( f ) => f()
>> }
>> }
>>
>> ...
>>
>> ciao, -sciss-
>>
>>
>> Am 31.08.2010 um 23:54 schrieb Sciss:
>>
>>> it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
>>> and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
>>> that is, Actor.actors { } doesn't execute the actor bodies any more.
>>>
>>> so were is the flaw? is it Futures.awaitAll?
>>>
>>> can i set some property that allows the number of actors to grow without problem?
>>>
>>> thanks, -sciss-
>>>
>>>
>>> Am 31.08.2010 um 23:30 schrieb Sciss:
>>>
>>>> like this:
>>>>
>>>> object Schnuck extends actors.DaemonActor {
>>>> var handler: Function0[ Unit ] = () => ()
>>>> def act { loop { react {
>>>> case "gaga" => reply( "gugu" )
>>>> case "lala" => handler()
>>>> }}}
>>>> }
>>>>
>>>> Schnuck.start
>>>>
>>>> Schnuck.handler = () => {
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>>>>
>>>> Schnuck.handler = () => {
>>>> actors.Actor.actor { // this should make us independant or not?
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>>>>
>>>> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>>>>
>>>> thanks, -sciss-
>>>>
>>>>
>>>>
>>>> Am 31.08.2010 um 23:15 schrieb Sciss:
>>>>
>>>>> hi,
>>>>>
>>>>> i am having a problem with scala actors :
>>>>> - everything is done using the loop / react framework
>>>>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>>>>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>>>>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>>>>
>>>>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>>>>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>>>>
>>>>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>>>>> happening fine in its own thread.
>>>>>
>>>>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>>>>> actor independant of the thread it was created from, it seems.
>>>>>
>>>>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>>>>> EventQueue.invokeLater, and the problem is gone.
>>>>>
>>>>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>>>>> doesn't produce a problem in the actor body it was created from.
>>>>>
>>>>> is there a way to guarantee this independance?
>>>>>
>>>>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>>>>> i had problems of deadlocks when using actors in blocking I/O.
>>>>>
>>>>> thanks for help.
>>>>>
>>>>> best, -sciss-
>>>>>
>>>>
>>>
>>
>>
>
>
>
Wed, 2010-09-01, 12:57
#8
Re: Actor B spawned from Actor A may block ActorA ?!
Scala actors have an explicit exit method. It is mysteriously called exit.
On Tue, Aug 31, 2010 at 8:40 PM, Sciss <contact@sciss.de> wrote:
--
http://erikengbrecht.blogspot.com/
On Tue, Aug 31, 2010 at 8:40 PM, Sciss <contact@sciss.de> wrote:
i don't think scala actors have an explicit exit method. as soon as their "act" method is left, they should exit by themselves and be garbage-collected. at least that's my understanding.
Am 01.09.2010 um 01:36 schrieb Derek Williams:
> I only use Akka actors and not Scala actors, but an issue I see is
> that you are creating a new actor each time the handler is run which
> might be causing your problems. Does something like this work for you?
>
> Schnuck.handler = () => {
> actors.Actor.actor {
> val fut = Schnuck !! "gaga"
> actors.Futures.awaitAll( 1000L, fut ) match {
> case List( Some( "gugu" )) => println( "SUCCESS" )
> case _ => println( "TIMEOUT" )
> }
> actors.Actor.exit() // stop the current actor once done
> }
> }
>
> These examples are obviously not a good representation of your full
> app so it is difficult to provide a better solution, but in general it
> is usually best for actors (especially when using react) to
> communicate with each other using messages instead of waiting for the
> results of futures. How best to do this depends on what it is you are
> actually doing with these messages, as this example only shows your
> handlers printing to the screen (so, only side effects). Is this true
> of your actual app as well?
>
> On Tue, Aug 31, 2010 at 5:12 PM, Sciss <contact@sciss.de> wrote:
>> if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
>> too. so something like
>>
>> case class Fun( f: () => Unit )
>>
>> case "lala" => handlerActor ! Fun( handler )
>>
>> and handlerActor = new DaemonActor {
>> def act { loop { react {
>> case Fun( f ) => f()
>> }
>> }
>>
>> ...
>>
>> ciao, -sciss-
>>
>>
>> Am 31.08.2010 um 23:54 schrieb Sciss:
>>
>>> it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
>>> and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
>>> that is, Actor.actors { } doesn't execute the actor bodies any more.
>>>
>>> so were is the flaw? is it Futures.awaitAll?
>>>
>>> can i set some property that allows the number of actors to grow without problem?
>>>
>>> thanks, -sciss-
>>>
>>>
>>> Am 31.08.2010 um 23:30 schrieb Sciss:
>>>
>>>> like this:
>>>>
>>>> object Schnuck extends actors.DaemonActor {
>>>> var handler: Function0[ Unit ] = () => ()
>>>> def act { loop { react {
>>>> case "gaga" => reply( "gugu" )
>>>> case "lala" => handler()
>>>> }}}
>>>> }
>>>>
>>>> Schnuck.start
>>>>
>>>> Schnuck.handler = () => {
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>>>>
>>>> Schnuck.handler = () => {
>>>> actors.Actor.actor { // this should make us independant or not?
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>>>>
>>>> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>>>>
>>>> thanks, -sciss-
>>>>
>>>>
>>>>
>>>> Am 31.08.2010 um 23:15 schrieb Sciss:
>>>>
>>>>> hi,
>>>>>
>>>>> i am having a problem with scala actors :
>>>>> - everything is done using the loop / react framework
>>>>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>>>>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>>>>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>>>>
>>>>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>>>>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>>>>
>>>>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>>>>> happening fine in its own thread.
>>>>>
>>>>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>>>>> actor independant of the thread it was created from, it seems.
>>>>>
>>>>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>>>>> EventQueue.invokeLater, and the problem is gone.
>>>>>
>>>>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>>>>> doesn't produce a problem in the actor body it was created from.
>>>>>
>>>>> is there a way to guarantee this independance?
>>>>>
>>>>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>>>>> i had problems of deadlocks when using actors in blocking I/O.
>>>>>
>>>>> thanks for help.
>>>>>
>>>>> best, -sciss-
>>>>>
>>>>
>>>
>>
>>
>
>
>
> --
> Derek
--
http://erikengbrecht.blogspot.com/
Wed, 2010-09-01, 13:07
#9
Re: Actor B spawned from Actor A may block ActorA ?!
On Wed, Sep 1, 2010 at 1:55 PM, Erik Engbrecht <erik.engbrecht@gmail.com> wrote:
Scala actors have an explicit exit method. It is mysteriously called exit.
Protip: When migrating from Scala Actors to Akka Actors, replace all occurences of "exit" to "stop", otherwise it'll use Predef.exit = System.exit
On Tue, Aug 31, 2010 at 8:40 PM, Sciss <contact@sciss.de> wrote:
i don't think scala actors have an explicit exit method. as soon as their "act" method is left, they should exit by themselves and be garbage-collected. at least that's my understanding.
Am 01.09.2010 um 01:36 schrieb Derek Williams:
> I only use Akka actors and not Scala actors, but an issue I see is
> that you are creating a new actor each time the handler is run which
> might be causing your problems. Does something like this work for you?
>
> Schnuck.handler = () => {
> actors.Actor.actor {
> val fut = Schnuck !! "gaga"
> actors.Futures.awaitAll( 1000L, fut ) match {
> case List( Some( "gugu" )) => println( "SUCCESS" )
> case _ => println( "TIMEOUT" )
> }
> actors.Actor.exit() // stop the current actor once done
> }
> }
>
> These examples are obviously not a good representation of your full
> app so it is difficult to provide a better solution, but in general it
> is usually best for actors (especially when using react) to
> communicate with each other using messages instead of waiting for the
> results of futures. How best to do this depends on what it is you are
> actually doing with these messages, as this example only shows your
> handlers printing to the screen (so, only side effects). Is this true
> of your actual app as well?
>
> On Tue, Aug 31, 2010 at 5:12 PM, Sciss <contact@sciss.de> wrote:
>> if i create one single handler-actor in advance (not from within the message reception actor), and execute the handlers all on this separate actor, it seems to be working ok,
>> too. so something like
>>
>> case class Fun( f: () => Unit )
>>
>> case "lala" => handlerActor ! Fun( handler )
>>
>> and handlerActor = new DaemonActor {
>> def act { loop { react {
>> case Fun( f ) => f()
>> }
>> }
>>
>> ...
>>
>> ciao, -sciss-
>>
>>
>> Am 31.08.2010 um 23:54 schrieb Sciss:
>>
>>> it get's worse. i changed now testwise my main receiver code from loopWhile( ... ) { react { }} to while( ... ) receive {},
>>> and now it doesn't take long and the actors are starving (although i did System.setProperty( "actors.enableForkJoin", "false" ),
>>> that is, Actor.actors { } doesn't execute the actor bodies any more.
>>>
>>> so were is the flaw? is it Futures.awaitAll?
>>>
>>> can i set some property that allows the number of actors to grow without problem?
>>>
>>> thanks, -sciss-
>>>
>>>
>>> Am 31.08.2010 um 23:30 schrieb Sciss:
>>>
>>>> like this:
>>>>
>>>> object Schnuck extends actors.DaemonActor {
>>>> var handler: Function0[ Unit ] = () => ()
>>>> def act { loop { react {
>>>> case "gaga" => reply( "gugu" )
>>>> case "lala" => handler()
>>>> }}}
>>>> }
>>>>
>>>> Schnuck.start
>>>>
>>>> Schnuck.handler = () => {
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
>>>>
>>>> Schnuck.handler = () => {
>>>> actors.Actor.actor { // this should make us independant or not?
>>>> val fut = Schnuck !! "gaga"
>>>> actors.Futures.awaitAll( 1000L, fut ) match {
>>>> case List( Some( "gugu" )) => println( "SUCCESS" )
>>>> case _ => println( "TIMEOUT" )
>>>> }
>>>> }
>>>> }
>>>>
>>>> Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
>>>>
>>>> of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
>>>>
>>>> thanks, -sciss-
>>>>
>>>>
>>>>
>>>> Am 31.08.2010 um 23:15 schrieb Sciss:
>>>>
>>>>> hi,
>>>>>
>>>>> i am having a problem with scala actors :
>>>>> - everything is done using the loop / react framework
>>>>> - i have a message receiver actor that invokes handlers which can be registered with that receiver
>>>>> - there is a handler A which sends out a new message, registers a new handler, gets a future
>>>>> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>>>>>
>>>>> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
>>>>> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>>>>>
>>>>> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
>>>>> happening fine in its own thread.
>>>>>
>>>>> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
>>>>> actor independant of the thread it was created from, it seems.
>>>>>
>>>>> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
>>>>> EventQueue.invokeLater, and the problem is gone.
>>>>>
>>>>> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
>>>>> doesn't produce a problem in the actor body it was created from.
>>>>>
>>>>> is there a way to guarantee this independance?
>>>>>
>>>>> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
>>>>> i had problems of deadlocks when using actors in blocking I/O.
>>>>>
>>>>> thanks for help.
>>>>>
>>>>> best, -sciss-
>>>>>
>>>>
>>>
>>
>>
>
>
>
> --
> Derek
--
http://erikengbrecht.blogspot.com/
--
Viktor Klang,
Code Connoisseur
Work: www.akkasource.com
Code: github.com/viktorklang
Follow: twitter.com/viktorklang
Read: klangism.tumblr.com
like this:
object Schnuck extends actors.DaemonActor {
var handler: Function0[ Unit ] = () => ()
def act { loop { react {
case "gaga" => reply( "gugu" )
case "lala" => handler()
}}}
}
Schnuck.start
Schnuck.handler = () => {
val fut = Schnuck !! "gaga"
actors.Futures.awaitAll( 1000L, fut ) match {
case List( Some( "gugu" )) => println( "SUCCESS" )
case _ => println( "TIMEOUT" )
}
}
Schnuck ! "lala" // ok, this obviously produces a TIMEOUT
Schnuck.handler = () => {
actors.Actor.actor { // this should make us independant or not?
val fut = Schnuck !! "gaga"
actors.Futures.awaitAll( 1000L, fut ) match {
case List( Some( "gugu" )) => println( "SUCCESS" )
case _ => println( "TIMEOUT" )
}
}
}
Schnuck ! "lala" // this works _most of the time_, but sometimes (heavy CPU load i think) still blocks and causes the TIMEOUT
of course the problem cannot be reproduced here :-( but i am pretty much certain this is my scenario and the blocking does happen.
thanks, -sciss-
Am 31.08.2010 um 23:15 schrieb Sciss:
> hi,
>
> i am having a problem with scala actors :
> - everything is done using the loop / react framework
> - i have a message receiver actor that invokes handlers which can be registered with that receiver
> - there is a handler A which sends out a new message, registers a new handler, gets a future
> which is satisfied by that new handler, and calls Futures.awaitAll on that one
>
> now there was a deadlock, because Futures.awaitAll was called from the actor body of the general receiver,
> so basically the receiver thread blocks and thus doesn't pop new messages from its mailbox.
>
> so i tried to fix this by spawing a new actor upon notification of A, so that the Futures.awaitAll would be
> happening fine in its own thread.
>
> _but_: that doesn't seem to happen all of the time. Thus Actors.actor { } is not guaranteed to create a new
> actor independant of the thread it was created from, it seems.
>
> this is really bad of course. my shitty workaround now is to defer the handler reaction A with
> EventQueue.invokeLater, and the problem is gone.
>
> so how can it be that Actors.actor doesn't guarantee to create an actor that when blocking via receive
> doesn't produce a problem in the actor body it was created from.
>
> is there a way to guarantee this independance?
>
> note that my system is configured with System.setProperty( "actors.enableForkJoin", "false" ) because
> i had problems of deadlocks when using actors in blocking I/O.
>
> thanks for help.
>
> best, -sciss-
>