- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Automatically shutting down an unreferenced actor
Mon, 2010-05-17, 18:37
hi, i was wondering....
def test {
val a = new scala.actors.Actor {
def act = loop { react { case _ => }}
override def finalize {
println( "Actor gc'ed" )
}
}
a.start
}
test
// dum-di-dum....
it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
thanks, -sciss-
Mon, 2010-05-17, 20:27
#2
Re: Automatically shutting down an unreferenced actor
because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
> That actor is looping infinitely on a react, why would it ever be GC'ed?
>
> On Mon, May 17, 2010 at 2:37 PM, Sciss wrote:
> hi, i was wondering....
>
> def test {
> val a = new scala.actors.Actor {
> def act = loop { react { case _ => }}
> override def finalize {
> println( "Actor gc'ed" )
> }
> }
> a.start
> }
>
> test
> // dum-di-dum....
>
> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>
> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>
> thanks, -sciss-
>
>
>
>
Mon, 2010-05-17, 20:57
#3
Re: Automatically shutting down an unreferenced actor
I guess it's still possible for a non-trivial actor to have no references but still do something.
It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
On 17 May 2010 20:13, Sciss <contact@sciss.de> wrote:
--
Kevin Wright
mail/google talk: kev.lee.wright@googlemail.com
wave: kev.lee.wright@googlewave.com
skype: kev.lee.wright
twitter: @thecoda
It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
On 17 May 2010 20:13, Sciss <contact@sciss.de> wrote:
because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
> That actor is looping infinitely on a react, why would it ever be GC'ed?
>
> On Mon, May 17, 2010 at 2:37 PM, Sciss <contact@sciss.de> wrote:
> hi, i was wondering....
>
> def test {
> val a = new scala.actors.Actor {
> def act = loop { react { case _ => }}
> override def finalize {
> println( "Actor gc'ed" )
> }
> }
> a.start
> }
>
> test
> // dum-di-dum....
>
> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>
> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>
> thanks, -sciss-
>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
--
Kevin Wright
mail/google talk: kev.lee.wright@googlemail.com
wave: kev.lee.wright@googlewave.com
skype: kev.lee.wright
twitter: @thecoda
Mon, 2010-05-17, 21:17
#4
Re: Automatically shutting down an unreferenced actor
On Mon, May 17, 2010 at 2:50 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I guess it's still possible for a non-trivial actor to have no references but still do something.
One use-case that comes to mind:
object Heartbeat {
def start(a: Actor, interval: Long): Unit = actor { loop {
reactWithin(interval) { case TIMEOUT => a ! Ping }
}}
}
Obviously there are better ways to implement this, or at least nicer functionality were one to actually keep the reference (stop/restart), but it's certainly an example of an actor that's doing something useful without being referenced.
- Colin
Disclaimer: code of the top of my head, your compliage may vary.
Mon, 2010-05-17, 21:27
#5
Re: Automatically shutting down an unreferenced actor
ok, you convinced me....
Am 17.05.2010 um 21:10 schrieb Colin Bullock:
>
>
> On Mon, May 17, 2010 at 2:50 PM, Kevin Wright wrote:
> I guess it's still possible for a non-trivial actor to have no references but still do something.
>
> One use-case that comes to mind:
>
> object Heartbeat {
> def start(a: Actor, interval: Long): Unit = actor { loop {
> reactWithin(interval) { case TIMEOUT => a ! Ping }
> }}
> }
>
> Obviously there are better ways to implement this, or at least nicer functionality were one to actually keep the reference (stop/restart), but it's certainly an example of an actor that's doing something useful without being referenced.
>
> - Colin
>
> Disclaimer: code of the top of my head, your compliage may vary.
Tue, 2010-05-18, 18:17
#6
Re: Automatically shutting down an unreferenced actor
Lift actors do work that way; they get GC'd when the user has no reference to them.
On Mon, May 17, 2010 at 3:50 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On Mon, May 17, 2010 at 3:50 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I guess it's still possible for a non-trivial actor to have no references but still do something.
It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
On 17 May 2010 20:13, Sciss <contact@sciss.de> wrote:
because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
> That actor is looping infinitely on a react, why would it ever be GC'ed?
>
> On Mon, May 17, 2010 at 2:37 PM, Sciss <contact@sciss.de> wrote:
> hi, i was wondering....
>
> def test {
> val a = new scala.actors.Actor {
> def act = loop { react { case _ => }}
> override def finalize {
> println( "Actor gc'ed" )
> }
> }
> a.start
> }
>
> test
> // dum-di-dum....
>
> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>
> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>
> thanks, -sciss-
>
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
--
Kevin Wright
mail/google talk: kev.lee.wright@googlemail.com
wave: kev.lee.wright@googlewave.com
skype: kev.lee.wright
twitter: @thecoda
Tue, 2010-05-18, 18:27
#7
Re: Automatically shutting down an unreferenced actor
thanks for the reference, i will check it out. i take it lift has its own actor framework then, not being based on scala.actors._ ?
Am 18.05.2010 um 18:10 schrieb Naftoli Gugenheim:
> Lift actors do work that way; they get GC'd when the user has no reference to them.
>
>
> On Mon, May 17, 2010 at 3:50 PM, Kevin Wright wrote:
> I guess it's still possible for a non-trivial actor to have no references but still do something.
>
> It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
>
>
> On 17 May 2010 20:13, Sciss wrote:
> because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
>
> Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
>
>> That actor is looping infinitely on a react, why would it ever be GC'ed?
>>
>> On Mon, May 17, 2010 at 2:37 PM, Sciss wrote:
>> hi, i was wondering....
>>
>> def test {
>> val a = new scala.actors.Actor {
>> def act = loop { react { case _ => }}
>> override def finalize {
>> println( "Actor gc'ed" )
>> }
>> }
>> a.start
>> }
>>
>> test
>> // dum-di-dum....
>>
>> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>>
>> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>>
>> thanks, -sciss-
>>
>>
>>
>>
>> --
>> Daniel C. Sobral
>>
>> I travel to the future all the time.
>
>
>
>
Tue, 2010-05-18, 18:47
#8
Re: Automatically shutting down an unreferenced actor
On Tue, May 18, 2010 at 10:17 AM, Sciss <contact@sciss.de> wrote:
thanks for the reference, i will check it out. i take it lift has its own actor framework then, not being based on scala.actors._ ?
Yes. LiftActors are not based on Scala Actors. They do not have a "running" state and will be GCed when all references are gone like any other object in the JVM. They use java.util.concurrent for scheduling and avoid some memory retention issues that we encountered in the Scala Actor package. LiftActors are event-based only (no thread-based option) and the syntax is slightly different (no act = loop {...} stuff and a different mechanism for dynamically changing message handlers).
Am 18.05.2010 um 18:10 schrieb Naftoli Gugenheim:
> Lift actors do work that way; they get GC'd when the user has no reference to them.
>
>
> On Mon, May 17, 2010 at 3:50 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
> I guess it's still possible for a non-trivial actor to have no references but still do something.
>
> It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
>
>
> On 17 May 2010 20:13, Sciss <contact@sciss.de> wrote:
> because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
>
> Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
>
>> That actor is looping infinitely on a react, why would it ever be GC'ed?
>>
>> On Mon, May 17, 2010 at 2:37 PM, Sciss <contact@sciss.de> wrote:
>> hi, i was wondering....
>>
>> def test {
>> val a = new scala.actors.Actor {
>> def act = loop { react { case _ => }}
>> override def finalize {
>> println( "Actor gc'ed" )
>> }
>> }
>> a.start
>> }
>>
>> test
>> // dum-di-dum....
>>
>> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>>
>> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>>
>> thanks, -sciss-
>>
>>
>>
>>
>> --
>> Daniel C. Sobral
>>
>> I travel to the future all the time.
>
>
>
>
> --
> Kevin Wright
>
> mail/google talk: kev.lee.wright@googlemail.com
> wave: kev.lee.wright@googlewave.com
> skype: kev.lee.wright
> twitter: @thecoda
>
>
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics
Tue, 2010-05-18, 21:57
#9
Re: Automatically shutting down an unreferenced actor
Hi,
Actually, it is not a GC problem. If you run the following program using
a profiler (VisualVM is the quickest option I can think of) you'll see
that all the actors get GC'ed:
class C(store: Boolean) {
var as: List[Actor] = List()
def test() {
val a = new Actor {
def act() = loop { react { case _ => print("X") }}
}
if (store)
as = a :: as
a.start()
Test.cnt += 1
if (Test.cnt % 1000000 == 0) {
a ! 0
System.gc()
}
}
}
object Test {
var cnt = 0
def main(args: Array[String]) {
scala.actors.Debug.level = 3
val c = new C(args(0).toInt == 1)
for (_ <- 1 to 10000000) {
c.test()
}
}
}
Passing 1 (instead of, say, 0) as an argument on the command line will
most likely bring your JVM to a grinding halt.
Just this simple experiment tells us that nowhere in the scheduler are
references kept to active actors-- they are indeed GC'ed once they
become unreachable.
However, the actual effect you are seeing is that the program does not
terminate. That's because the actor scheduler thread does not terminate,
since by default it does not track whether its actors have been GC'ed or
not.
On 2.8 there is an easy way to create actors that do *not* prevent the
scheduler thread from terminating, even if they have not terminated:
`DaemonActor`s. If you create instances of `DaemonActor` instead of
`Actor` in the above program the program will terminate automatically.
(You might want to add a `Thread.sleep(1000)` at the end of `Test.main`
to be sure you see all the output before the program terminates, since
the output is done on a daemon thread different from the main thread.)
The same experiment as above shows that all those `DaemonActor`s are GC'ed.
About your example using `finalize`: I haven't been able to get it to
work even without using any actors at all. As far as I know the use of
`finalize` is deprecated (it might not even be guaranteed to be
invoked?); your example should work using `WeakReference`s, though.
Cheers,
Philipp
Sciss wrote:
> hi, i was wondering....
>
> def test {
> val a = new scala.actors.Actor {
> def act = loop { react { case _ => }}
> override def finalize {
> println( "Actor gc'ed" )
> }
> }
> a.start
> }
>
> test
> // dum-di-dum....
>
> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>
> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>
> thanks, -sciss-
>
Tue, 2010-05-18, 22:07
#10
Re: Automatically shutting down an unreferenced actor
hi philipp,
thanks for the hint with DaemonActor, i will check it out. i have code that uses finalize and it does get invoked when the the object is gc'ed. anyway, it was just to test the general behaviour, not that i will actually want to do anything in finalize.
my scenario is like that the actors are used to ensure concurrency and isolation, and there is going to be DSL and the user shouldn't be bothered with keeping track of all the actors, so they should automatically terminate if they cannot be reached anymore.
best, -sciss--
Am 18.05.2010 um 21:56 schrieb Philipp Haller:
> Hi,
>
> Actually, it is not a GC problem. If you run the following program using
> a profiler (VisualVM is the quickest option I can think of) you'll see
> that all the actors get GC'ed:
>
> class C(store: Boolean) {
> var as: List[Actor] = List()
> def test() {
> val a = new Actor {
> def act() = loop { react { case _ => print("X") }}
> }
> if (store)
> as = a :: as
> a.start()
> Test.cnt += 1
> if (Test.cnt % 1000000 == 0) {
> a ! 0
> System.gc()
> }
> }
> }
> object Test {
> var cnt = 0
> def main(args: Array[String]) {
> scala.actors.Debug.level = 3
> val c = new C(args(0).toInt == 1)
> for (_ <- 1 to 10000000) {
> c.test()
> }
> }
> }
>
> Passing 1 (instead of, say, 0) as an argument on the command line will
> most likely bring your JVM to a grinding halt.
> Just this simple experiment tells us that nowhere in the scheduler are
> references kept to active actors-- they are indeed GC'ed once they
> become unreachable.
>
> However, the actual effect you are seeing is that the program does not
> terminate. That's because the actor scheduler thread does not terminate,
> since by default it does not track whether its actors have been GC'ed or
> not.
>
> On 2.8 there is an easy way to create actors that do *not* prevent the
> scheduler thread from terminating, even if they have not terminated:
> `DaemonActor`s. If you create instances of `DaemonActor` instead of
> `Actor` in the above program the program will terminate automatically.
>
> (You might want to add a `Thread.sleep(1000)` at the end of `Test.main`
> to be sure you see all the output before the program terminates, since
> the output is done on a daemon thread different from the main thread.)
>
> The same experiment as above shows that all those `DaemonActor`s are GC'ed.
>
> About your example using `finalize`: I haven't been able to get it to
> work even without using any actors at all. As far as I know the use of
> `finalize` is deprecated (it might not even be guaranteed to be
> invoked?); your example should work using `WeakReference`s, though.
>
> Cheers,
> Philipp
>
>
> Sciss wrote:
>> hi, i was wondering....
>>
>> def test {
>> val a = new scala.actors.Actor {
>> def act = loop { react { case _ => }}
>> override def finalize {
>> println( "Actor gc'ed" )
>> }
>> }
>> a.start
>> }
>>
>> test
>> // dum-di-dum....
>>
>> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>>
>> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>>
>> thanks, -sciss-
>>
>
Tue, 2010-05-18, 23:17
#11
Re: Automatically shutting down an unreferenced actor
Cool. If I don't want my actors to commit seppuku, how can I terminate
the dispatcher at will? Is this an object with a stop() ?
On 5/18/10, Philipp Haller wrote:
> Hi,
>
> Actually, it is not a GC problem. If you run the following program using
> a profiler (VisualVM is the quickest option I can think of) you'll see
> that all the actors get GC'ed:
>
> class C(store: Boolean) {
> var as: List[Actor] = List()
> def test() {
> val a = new Actor {
> def act() = loop { react { case _ => print("X") }}
> }
> if (store)
> as = a :: as
> a.start()
> Test.cnt += 1
> if (Test.cnt % 1000000 == 0) {
> a ! 0
> System.gc()
> }
> }
> }
> object Test {
> var cnt = 0
> def main(args: Array[String]) {
> scala.actors.Debug.level = 3
> val c = new C(args(0).toInt == 1)
> for (_ <- 1 to 10000000) {
> c.test()
> }
> }
> }
>
> Passing 1 (instead of, say, 0) as an argument on the command line will
> most likely bring your JVM to a grinding halt.
> Just this simple experiment tells us that nowhere in the scheduler are
> references kept to active actors-- they are indeed GC'ed once they
> become unreachable.
>
> However, the actual effect you are seeing is that the program does not
> terminate. That's because the actor scheduler thread does not terminate,
> since by default it does not track whether its actors have been GC'ed or
> not.
>
> On 2.8 there is an easy way to create actors that do *not* prevent the
> scheduler thread from terminating, even if they have not terminated:
> `DaemonActor`s. If you create instances of `DaemonActor` instead of
> `Actor` in the above program the program will terminate automatically.
>
> (You might want to add a `Thread.sleep(1000)` at the end of `Test.main`
> to be sure you see all the output before the program terminates, since
> the output is done on a daemon thread different from the main thread.)
>
> The same experiment as above shows that all those `DaemonActor`s are GC'ed.
>
> About your example using `finalize`: I haven't been able to get it to
> work even without using any actors at all. As far as I know the use of
> `finalize` is deprecated (it might not even be guaranteed to be
> invoked?); your example should work using `WeakReference`s, though.
>
> Cheers,
> Philipp
>
>
> Sciss wrote:
>> hi, i was wondering....
>>
>> def test {
>> val a = new scala.actors.Actor {
>> def act = loop { react { case _ => }}
>> override def finalize {
>> println( "Actor gc'ed" )
>> }
>> }
>> a.start
>> }
>>
>> test
>> // dum-di-dum....
>>
>> it seems the actor is never gc'ed, so it must be referenced somewhere...
>> probaby as it is a running thread or so?
>>
>> is it possible to detect when the actor isn't used anymore, without
>> explicitly calling stop?
>>
>> thanks, -sciss-
>>
>
>
Wed, 2010-05-19, 01:47
#12
Re: Automatically shutting down an unreferenced actor
p.s. getting warm with actors now. the more i dig into it the more fun it is. great library!
is there another mechanism for returning typed Future instances other than the !! with a partial function?
why wouldn't it suffice to have a method !: P which takes care of the matching?
or put differently, when would my partial function look any different than
myActor !!( msg, { case x: ExpectedType => x })
?
best, -sciss-
Am 18.05.2010 um 21:56 schrieb Philipp Haller:
> Hi,
>
> Actually, it is not a GC problem. If you run the following program using
> a profiler (VisualVM is the quickest option I can think of) you'll see
> that all the actors get GC'ed:
>
> class C(store: Boolean) {
> var as: List[Actor] = List()
> def test() {
> val a = new Actor {
> def act() = loop { react { case _ => print("X") }}
> }
> if (store)
> as = a :: as
> a.start()
> Test.cnt += 1
> if (Test.cnt % 1000000 == 0) {
> a ! 0
> System.gc()
> }
> }
> }
> object Test {
> var cnt = 0
> def main(args: Array[String]) {
> scala.actors.Debug.level = 3
> val c = new C(args(0).toInt == 1)
> for (_ <- 1 to 10000000) {
> c.test()
> }
> }
> }
>
> Passing 1 (instead of, say, 0) as an argument on the command line will
> most likely bring your JVM to a grinding halt.
> Just this simple experiment tells us that nowhere in the scheduler are
> references kept to active actors-- they are indeed GC'ed once they
> become unreachable.
>
> However, the actual effect you are seeing is that the program does not
> terminate. That's because the actor scheduler thread does not terminate,
> since by default it does not track whether its actors have been GC'ed or
> not.
>
> On 2.8 there is an easy way to create actors that do *not* prevent the
> scheduler thread from terminating, even if they have not terminated:
> `DaemonActor`s. If you create instances of `DaemonActor` instead of
> `Actor` in the above program the program will terminate automatically.
>
> (You might want to add a `Thread.sleep(1000)` at the end of `Test.main`
> to be sure you see all the output before the program terminates, since
> the output is done on a daemon thread different from the main thread.)
>
> The same experiment as above shows that all those `DaemonActor`s are GC'ed.
>
> About your example using `finalize`: I haven't been able to get it to
> work even without using any actors at all. As far as I know the use of
> `finalize` is deprecated (it might not even be guaranteed to be
> invoked?); your example should work using `WeakReference`s, though.
>
> Cheers,
> Philipp
>
>
> Sciss wrote:
>> hi, i was wondering....
>>
>> def test {
>> val a = new scala.actors.Actor {
>> def act = loop { react { case _ => }}
>> override def finalize {
>> println( "Actor gc'ed" )
>> }
>> }
>> a.start
>> }
>>
>> test
>> // dum-di-dum....
>>
>> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>>
>> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>>
>> thanks, -sciss-
>>
>
Wed, 2010-05-19, 01:57
#13
Re: Automatically shutting down an unreferenced actor
p.p.s. i think i couldn't detect the GC because i was running the stuff in the REPL. maybe that is a problem. i will try again with standalone code
Am 18.05.2010 um 21:56 schrieb Philipp Haller:
> Hi,
>
> Actually, it is not a GC problem. If you run the following program using
> a profiler (VisualVM is the quickest option I can think of) you'll see
> that all the actors get GC'ed:
>
> class C(store: Boolean) {
> var as: List[Actor] = List()
> def test() {
> val a = new Actor {
> def act() = loop { react { case _ => print("X") }}
> }
> if (store)
> as = a :: as
> a.start()
> Test.cnt += 1
> if (Test.cnt % 1000000 == 0) {
> a ! 0
> System.gc()
> }
> }
> }
> object Test {
> var cnt = 0
> def main(args: Array[String]) {
> scala.actors.Debug.level = 3
> val c = new C(args(0).toInt == 1)
> for (_ <- 1 to 10000000) {
> c.test()
> }
> }
> }
>
> Passing 1 (instead of, say, 0) as an argument on the command line will
> most likely bring your JVM to a grinding halt.
> Just this simple experiment tells us that nowhere in the scheduler are
> references kept to active actors-- they are indeed GC'ed once they
> become unreachable.
>
> However, the actual effect you are seeing is that the program does not
> terminate. That's because the actor scheduler thread does not terminate,
> since by default it does not track whether its actors have been GC'ed or
> not.
>
> On 2.8 there is an easy way to create actors that do *not* prevent the
> scheduler thread from terminating, even if they have not terminated:
> `DaemonActor`s. If you create instances of `DaemonActor` instead of
> `Actor` in the above program the program will terminate automatically.
>
> (You might want to add a `Thread.sleep(1000)` at the end of `Test.main`
> to be sure you see all the output before the program terminates, since
> the output is done on a daemon thread different from the main thread.)
>
> The same experiment as above shows that all those `DaemonActor`s are GC'ed.
>
> About your example using `finalize`: I haven't been able to get it to
> work even without using any actors at all. As far as I know the use of
> `finalize` is deprecated (it might not even be guaranteed to be
> invoked?); your example should work using `WeakReference`s, though.
>
> Cheers,
> Philipp
>
>
> Sciss wrote:
>> hi, i was wondering....
>>
>> def test {
>> val a = new scala.actors.Actor {
>> def act = loop { react { case _ => }}
>> override def finalize {
>> println( "Actor gc'ed" )
>> }
>> }
>> a.start
>> }
>>
>> test
>> // dum-di-dum....
>>
>> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
>>
>> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
>>
>> thanks, -sciss-
>>
>
Wed, 2010-05-19, 02:07
#14
Re: Automatically shutting down an unreferenced actor
eh, forget the question. i see that one can use the body of the partialfunction as continuation code... so !: P would just be a handy shortcut, when you don't need this body of code
Am 19.05.2010 um 01:40 schrieb Sciss:
> or put differently, when would my partial function look any different than
Wed, 2010-05-19, 03:57
#15
Re: Automatically shutting down an unreferenced actor
Slightly off topic, but can i be pointed out to some example code that uses Scala 2.8 reactors?
Can it be used shorthand like:
val myActor = actor {
...
}
Wed, 2010-05-19, 11:37
#16
Re: Automatically shutting down an unreferenced actor
On 05/19/2010 12:09 AM, Razie wrote:
> Cool. If I don't want my actors to commit seppuku, how can I terminate
> the dispatcher at will? Is this an object with a stop() ?
Yes, you can do `Scheduler.shutdown()`.
Philipp
> On 5/18/10, Philipp Haller wrote:
>> Hi,
>>
>> Actually, it is not a GC problem. If you run the following program using
>> a profiler (VisualVM is the quickest option I can think of) you'll see
>> that all the actors get GC'ed:
>>
>> class C(store: Boolean) {
>> var as: List[Actor] = List()
>> def test() {
>> val a = new Actor {
>> def act() = loop { react { case _ => print("X") }}
>> }
>> if (store)
>> as = a :: as
>> a.start()
>> Test.cnt += 1
>> if (Test.cnt % 1000000 == 0) {
>> a ! 0
>> System.gc()
>> }
>> }
>> }
>> object Test {
>> var cnt = 0
>> def main(args: Array[String]) {
>> scala.actors.Debug.level = 3
>> val c = new C(args(0).toInt == 1)
>> for (_<- 1 to 10000000) {
>> c.test()
>> }
>> }
>> }
>>
>> Passing 1 (instead of, say, 0) as an argument on the command line will
>> most likely bring your JVM to a grinding halt.
>> Just this simple experiment tells us that nowhere in the scheduler are
>> references kept to active actors-- they are indeed GC'ed once they
>> become unreachable.
>>
>> However, the actual effect you are seeing is that the program does not
>> terminate. That's because the actor scheduler thread does not terminate,
>> since by default it does not track whether its actors have been GC'ed or
>> not.
>>
>> On 2.8 there is an easy way to create actors that do *not* prevent the
>> scheduler thread from terminating, even if they have not terminated:
>> `DaemonActor`s. If you create instances of `DaemonActor` instead of
>> `Actor` in the above program the program will terminate automatically.
>>
>> (You might want to add a `Thread.sleep(1000)` at the end of `Test.main`
>> to be sure you see all the output before the program terminates, since
>> the output is done on a daemon thread different from the main thread.)
>>
>> The same experiment as above shows that all those `DaemonActor`s are GC'ed.
>>
>> About your example using `finalize`: I haven't been able to get it to
>> work even without using any actors at all. As far as I know the use of
>> `finalize` is deprecated (it might not even be guaranteed to be
>> invoked?); your example should work using `WeakReference`s, though.
>>
>> Cheers,
>> Philipp
>>
>>
>> Sciss wrote:
>>> hi, i was wondering....
>>>
>>> def test {
>>> val a = new scala.actors.Actor {
>>> def act = loop { react { case _ => }}
>>> override def finalize {
>>> println( "Actor gc'ed" )
>>> }
>>> }
>>> a.start
>>> }
>>>
>>> test
>>> // dum-di-dum....
>>>
>>> it seems the actor is never gc'ed, so it must be referenced somewhere...
>>> probaby as it is a running thread or so?
>>>
>>> is it possible to detect when the actor isn't used anymore, without
>>> explicitly calling stop?
>>>
>>> thanks, -sciss-
>>>
>>
>>
>
Wed, 2010-05-19, 14:27
#17
Re: Automatically shutting down an unreferenced actor
On 05/19/2010 04:48 AM, Ravi Mendis wrote:
> Slightly off topic, but can i be pointed out to some example code that uses Scala 2.8 reactors?
You could take a look at the tests in the Scala source tree (grep for
`Reactor` in the `jvm` directory):
http://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/test/files/jvm
> Can it be used shorthand like:
>
> val myActor = actor {
> ...
> }
Currently, you need to subclass `Reactor`:
val myActor = new Reactor[Msg] {
def act() { ... }
}
myActor.start()
It would be nice to have a shortcut (since I think in many cases
`Reactor`s are all you need/want), however there are two issues:
1) `Reactor` does not maintain a thread-local `self` reference.
Therefore, the shortcut would have to look differently from
`actor {...}`, since one would need to pass a closure that takes the
current `Reactor` as a parameter:
reactor[String] { self => self.react { case "hello" => ... } }
(Or shorter, `reactor[String] { _.react { case "hello" => ... } }`.)
Note that I provided the `String` type argument explicitly so that
`self` has type `Reactor[String]`. Here is the signature:
def reactor[T >: Null](body: Reactor[T] => Unit): Reactor[T]
Also, `react` cannot be `protected` in the `Reactor` trait, then.
2) `reactor` in the `Actor` object is already taken to create an actor
from a `Responder`:
def reactor(body: => Responder[Unit]): Actor
This was introduced before `Reactor`s to allow a more convenient way
to write CPS code using `react`.
Another `Reactor`-returning `reactor` method could add confusion.
One approach could be to deprecate the existing `reactor` method,
since the continuations plug-in in 2.8 is probably the preferred way
to write CPS code anyway.
Or, one could simply leave things as they are, adding the new
`Reactor`-returning method.
Cheers,
Philipp
Thu, 2010-05-20, 18:27
#18
Re: Automatically shutting down an unreferenced actor
hi david,
is the lift actors API somewhere online?
http://dev.liftweb.net/framework/lift-base/lift-actor
gives me a 404...
thanks, -sciss-
Am 18.05.2010 um 18:44 schrieb David Pollak:
>
>
> On Tue, May 18, 2010 at 10:17 AM, Sciss wrote:
> thanks for the reference, i will check it out. i take it lift has its own actor framework then, not being based on scala.actors._ ?
>
> Yes. LiftActors are not based on Scala Actors. They do not have a "running" state and will be GCed when all references are gone like any other object in the JVM. They use java.util.concurrent for scheduling and avoid some memory retention issues that we encountered in the Scala Actor package. LiftActors are event-based only (no thread-based option) and the syntax is slightly different (no act = loop {...} stuff and a different mechanism for dynamically changing message handlers).
>
>
> Am 18.05.2010 um 18:10 schrieb Naftoli Gugenheim:
>
> > Lift actors do work that way; they get GC'd when the user has no reference to them.
> >
> >
> > On Mon, May 17, 2010 at 3:50 PM, Kevin Wright wrote:
> > I guess it's still possible for a non-trivial actor to have no references but still do something.
> >
> > It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
> >
> >
> > On 17 May 2010 20:13, Sciss wrote:
> > because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
> >
> > Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
> >
> >> That actor is looping infinitely on a react, why would it ever be GC'ed?
> >>
> >> On Mon, May 17, 2010 at 2:37 PM, Sciss wrote:
> >> hi, i was wondering....
> >>
> >> def test {
> >> val a = new scala.actors.Actor {
> >> def act = loop { react { case _ => }}
> >> override def finalize {
> >> println( "Actor gc'ed" )
> >> }
> >> }
> >> a.start
> >> }
> >>
> >> test
> >> // dum-di-dum....
> >>
> >> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
> >>
> >> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
> >>
> >> thanks, -sciss-
> >>
> >>
> >>
> >>
> >> --
> >> Daniel C. Sobral
> >>
> >> I travel to the future all the time.
> >
> >
> >
> >
> > --
> > Kevin Wright
> >
> > mail/google talk: kev.lee.wright@googlemail.com
> > wave: kev.lee.wright@googlewave.com
> > skype: kev.lee.wright
> > twitter: @thecoda
> >
> >
>
>
>
>
Thu, 2010-05-20, 18:37
#19
Re: Automatically shutting down an unreferenced actor
On Thu, May 20, 2010 at 10:19 AM, Sciss <contact@sciss.de> wrote:
hi david,
is the lift actors API somewhere online?
http://dev.liftweb.net/framework/lift-base/lift-actor
gives me a 404...
When I make up random URLs, they often lead to 404s, too.
Here's the documentation for Lift's Actors:
http://scala-tools.org/mvnsites/liftweb-2.0-M5/framework/lift-base/lift-actor/scaladocs/index.html
More generally, information about various Scala-tools.org hosted sites can be found at:
http://scala-tools.org/mvnsites/
thanks, -sciss-
Am 18.05.2010 um 18:44 schrieb David Pollak:
>
>
> On Tue, May 18, 2010 at 10:17 AM, Sciss <contact@sciss.de> wrote:
> thanks for the reference, i will check it out. i take it lift has its own actor framework then, not being based on scala.actors._ ?
>
> Yes. LiftActors are not based on Scala Actors. They do not have a "running" state and will be GCed when all references are gone like any other object in the JVM. They use java.util.concurrent for scheduling and avoid some memory retention issues that we encountered in the Scala Actor package. LiftActors are event-based only (no thread-based option) and the syntax is slightly different (no act = loop {...} stuff and a different mechanism for dynamically changing message handlers).
>
>
> Am 18.05.2010 um 18:10 schrieb Naftoli Gugenheim:
>
> > Lift actors do work that way; they get GC'd when the user has no reference to them.
> >
> >
> > On Mon, May 17, 2010 at 3:50 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
> > I guess it's still possible for a non-trivial actor to have no references but still do something.
> >
> > It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
> >
> >
> > On 17 May 2010 20:13, Sciss <contact@sciss.de> wrote:
> > because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
> >
> > Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
> >
> >> That actor is looping infinitely on a react, why would it ever be GC'ed?
> >>
> >> On Mon, May 17, 2010 at 2:37 PM, Sciss <contact@sciss.de> wrote:
> >> hi, i was wondering....
> >>
> >> def test {
> >> val a = new scala.actors.Actor {
> >> def act = loop { react { case _ => }}
> >> override def finalize {
> >> println( "Actor gc'ed" )
> >> }
> >> }
> >> a.start
> >> }
> >>
> >> test
> >> // dum-di-dum....
> >>
> >> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
> >>
> >> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
> >>
> >> thanks, -sciss-
> >>
> >>
> >>
> >>
> >> --
> >> Daniel C. Sobral
> >>
> >> I travel to the future all the time.
> >
> >
> >
> >
> > --
> > Kevin Wright
> >
> > mail/google talk: kev.lee.wright@googlemail.com
> > wave: kev.lee.wright@googlewave.com
> > skype: kev.lee.wright
> > twitter: @thecoda
> >
> >
>
>
>
>
> --
> Lift, the simply functional web framework http://liftweb.net
> Beginning Scala http://www.apress.com/book/view/1430219890
> Follow me: http://twitter.com/dpp
> Surf the harmonics
--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics
Thu, 2010-05-20, 18:37
#20
Re: Automatically shutting down an unreferenced actor
thanks,
i took the links from http://scala-tools.org/mvnsites/liftweb-2.0-M5/framework/lift-base/lift-... (all of which seem broken).
ciao, -sciss-
Am 20.05.2010 um 18:29 schrieb David Pollak:
>
>
> On Thu, May 20, 2010 at 10:19 AM, Sciss wrote:
> hi david,
>
> is the lift actors API somewhere online?
>
> http://dev.liftweb.net/framework/lift-base/lift-actor
>
> gives me a 404...
>
> When I make up random URLs, they often lead to 404s, too.
>
> Here's the documentation for Lift's Actors:
> http://scala-tools.org/mvnsites/liftweb-2.0-M5/framework/lift-base/lift-...
>
> More generally, information about various Scala-tools.org hosted sites can be found at:
> http://scala-tools.org/mvnsites/
>
>
>
> thanks, -sciss-
>
>
> Am 18.05.2010 um 18:44 schrieb David Pollak:
>
> >
> >
> > On Tue, May 18, 2010 at 10:17 AM, Sciss wrote:
> > thanks for the reference, i will check it out. i take it lift has its own actor framework then, not being based on scala.actors._ ?
> >
> > Yes. LiftActors are not based on Scala Actors. They do not have a "running" state and will be GCed when all references are gone like any other object in the JVM. They use java.util.concurrent for scheduling and avoid some memory retention issues that we encountered in the Scala Actor package. LiftActors are event-based only (no thread-based option) and the syntax is slightly different (no act = loop {...} stuff and a different mechanism for dynamically changing message handlers).
> >
> >
> > Am 18.05.2010 um 18:10 schrieb Naftoli Gugenheim:
> >
> > > Lift actors do work that way; they get GC'd when the user has no reference to them.
> > >
> > >
> > > On Mon, May 17, 2010 at 3:50 PM, Kevin Wright wrote:
> > > I guess it's still possible for a non-trivial actor to have no references but still do something.
> > >
> > > It can still SEND messages, and may be called back from native code, or be running a countdown timer. Such things aren't always easy to determine in the compiler or VM.
> > >
> > >
> > > On 17 May 2010 20:13, Sciss wrote:
> > > because there is noone referencing the actor, hence noone that could send it messages. so i have a "dead thread" somewhere, no?
> > >
> > > Am 17.05.2010 um 20:02 schrieb Daniel Sobral:
> > >
> > >> That actor is looping infinitely on a react, why would it ever be GC'ed?
> > >>
> > >> On Mon, May 17, 2010 at 2:37 PM, Sciss wrote:
> > >> hi, i was wondering....
> > >>
> > >> def test {
> > >> val a = new scala.actors.Actor {
> > >> def act = loop { react { case _ => }}
> > >> override def finalize {
> > >> println( "Actor gc'ed" )
> > >> }
> > >> }
> > >> a.start
> > >> }
> > >>
> > >> test
> > >> // dum-di-dum....
> > >>
> > >> it seems the actor is never gc'ed, so it must be referenced somewhere... probaby as it is a running thread or so?
> > >>
> > >> is it possible to detect when the actor isn't used anymore, without explicitly calling stop?
> > >>
> > >> thanks, -sciss-
> > >>
> > >>
> > >>
> > >>
> > >> --
> > >> Daniel C. Sobral
> > >>
> > >> I travel to the future all the time.
> > >
> > >
> > >
> > >
> > > --
> > > Kevin Wright
> > >
> > > mail/google talk: kev.lee.wright@googlemail.com
> > > wave: kev.lee.wright@googlewave.com
> > > skype: kev.lee.wright
> > > twitter: @thecoda
> > >
> > >
> >
> >
> >
> >
> > --
> > Lift, the simply functional web framework http://liftweb.net
> > Beginning Scala http://www.apress.com/book/view/1430219890
> > Follow me: http://twitter.com/dpp
> > Surf the harmonics
>
>
>
>
On Mon, May 17, 2010 at 2:37 PM, Sciss <contact@sciss.de> wrote:
--
Daniel C. Sobral
I travel to the future all the time.