This page is no longer maintained — Please continue to the home page at www.scala-lang.org

minor simplification of Actor code

3 replies
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.

A minor recommendation, after glancing over Actor.scala.

Simplify this:

private[actors] val tl = new ThreadLocal[Actor]

...
....
def self: Actor = {
var a = tl.get.asInstanceOf[Actor]
if (null eq a) {
a = new ActorProxy(currentThread)
tl.set(a)
}
a
}

To this:

private [actors] val tl = new ThreadLocal[Actor] {
override def initialValue = new ActorProxy(currentThread)
}

def self: Actor = tl.get

Thanks,
Dimitris

Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: minor simplification of Actor code

Hi Dimitris,

Thanks for your suggestion.

Andreou Dimitris wrote:
> Simplify this:
>
> private[actors] val tl = new ThreadLocal[Actor]
>
> ...
> ....
> ....
> .....
> def self: Actor = {
> var a = tl.get.asInstanceOf[Actor]
> if (null eq a) {
> a = new ActorProxy(currentThread)
> tl.set(a)
> }
> a
> }
>
> To this:
>
> private [actors] val tl = new ThreadLocal[Actor] {
> override def initialValue = new ActorProxy(currentThread)
> }
>
> def self: Actor = tl.get

Note that this code changes the behavior slightly: it always creates a
new `ActorProxy` for each worker thread whenever the thread references
the `Actor` object for the first time.

The current implementation only creates a new `ActorProxy` when
`Actor.self` is invoked from a thread which does not currently execute
an actor.

The difference is important since `ActorProxy` creates a reference to a
scheduler. This becomes an issue when people want to use custom
schedulers (e.g., with daemon-like behavior). I am still working on a
good solution to this (see #1405).

The advantage of your code is, of course, that `self` is faster because
of one less test. Therefore, I agree that we should use an initial value
for `tl`.

Thanks,
Philipp

ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: minor simplification of Actor code

O/H Philipp Haller έγραψε:
> Hi Dimitris,
>
> Thanks for your suggestion.
>
> Andreou Dimitris wrote:
>
>> Simplify this:
>>
>> private[actors] val tl = new ThreadLocal[Actor]
>>
>> ...
>> ....
>> ....
>> .....
>> def self: Actor = {
>> var a = tl.get.asInstanceOf[Actor]
>> if (null eq a) {
>> a = new ActorProxy(currentThread)
>> tl.set(a)
>> }
>> a
>> }
>>
>> To this:
>>
>> private [actors] val tl = new ThreadLocal[Actor] {
>> override def initialValue = new ActorProxy(currentThread)
>> }
>>
>> def self: Actor = tl.get
>>
>
> Note that this code changes the behavior slightly: it always creates a
> new `ActorProxy` for each worker thread whenever the thread references
> the `Actor` object for the first time.
>
> The current implementation only creates a new `ActorProxy` when
> `Actor.self` is invoked from a thread which does not currently execute
> an actor.
>
> The difference is important since `ActorProxy` creates a reference to a
> scheduler. This becomes an issue when people want to use custom
> schedulers (e.g., with daemon-like behavior). I am still working on a
> good solution to this (see #1405).
>
> The advantage of your code is, of course, that `self` is faster because
> of one less test. Therefore, I agree that we should use an initial value
> for `tl`.
>
> Thanks,
> Philipp
>
I don't have yet a complete view of the code to have an opinion on that
- and I didn't notice Action_Proxy_ at all. I'm also sending some minor
comments privately and will review the code more thoroughly when time
permits. Thanks for your answer.

Dimitris

Carsten Saager
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
Re: minor simplification of Actor code
Hi Dimitris,

Thanks for your suggestion.

Andreou Dimitris wrote:
> Simplify this:
>
>   private[actors] val tl = new ThreadLocal[Actor]
>
> ...
> ....
> ....
> .....
>   def self: Actor = {
>     var a = tl.get.asInstanceOf[Actor]
>     if (null eq a) {
>       a = new ActorProxy(currentThread)
>       tl.set(a)
>     }
>     a
>   }
>
> To this:
>
>  private [actors] val tl = new ThreadLocal[Actor] {
>     override def initialValue = new ActorProxy(currentThread)
>  }
>
>   def self: Actor = tl.get

Note that this code changes the behavior slightly: it always creates a
new `ActorProxy` for each worker thread whenever the thread references
the `Actor` object for the first time.

The current implementation only creates a new `ActorProxy` when
`Actor.self` is invoked from a thread which does not currently execute
an actor.

The difference is important since `ActorProxy` creates a reference to a
scheduler. This becomes an issue when people want to use custom
schedulers (e.g., with daemon-like behavior). I am still working on a
good solution to this (see #1405).

The advantage of your code is, of course, that `self` is faster because
of one less test. Therefore, I agree that we should use an initial value
for `tl`.

Thanks,
Philipp


Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland