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

Actors: handling null messages

12 replies
tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.

Hi!

class Foo extends Actor {
def act() {
// loop, react
case s: String =>
case x: Int =>
case (textTemplate: Int, language: String) =>

So, when sending null to this actor nothing will happen probably because it's
impossible to decide whether this null was a String or an Int null... Trying to
make this somewhat more explicit by sending a val s:String=null doesn't work
either, I assume the type information is simply lost. Is it nevertheless possible
somehow for the third case to only send the text template and the language being
null (meaning that a default language is used)?

And BTW what's the proposed way to catch unhandled exceptions in order to
prevent the entire actor to go down? Is there something like an
uncaughtExceptionHandler?

thx,
tcn

Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Actors: handling null messages

Do not use null (this is basically only for java interoperability) use
Option instead.

-Stefan

2010/6/27 Timo Nentwig :
> Hi!
>
> class Foo extends Actor {
>  def act() {
>    // loop, react
>    case s: String =>
>    case x: Int =>
>    case (textTemplate: Int, language: String) =>
>
> So, when sending null to this actor nothing will happen probably because
> it's impossible to decide whether this null was a String or an Int null...
> Trying to make this somewhat more explicit by sending a val s:String=null
> doesn't work either, I assume the type information is simply lost. Is it
> nevertheless possible
> somehow for the third case to only send the text template and the language
> being
> null (meaning that a default language is used)?
>
> And BTW what's the proposed way to catch unhandled exceptions in order to
> prevent the entire actor to go down? Is there something like an
> uncaughtExceptionHandler?
>
> thx,
> tcn
>

tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.
Re: Actors: handling null messages

On Sun, 27 Jun 2010, Stefan Langer wrote:

> Date: Sun, 27 Jun 2010 14:49:45 +0200
> From: Stefan Langer
> To: Timo Nentwig
> Cc: scala-user@listes.epfl.ch
> Subject: Re: [scala-user] Actors: handling null messages
>
> Do not use null (this is basically only for java interoperability) use
> Option instead.

Okay, this would work for my example. But my point was rather: how do I get to
*know* all at if something's unexpectedly null? If a message doesn't fit a
pattern, it's silently dropped.

Precisely, I ran a SQL query. I expected to get a language, but actually there
was no not-null constraint (legacy, whatever) and *some* records had no
language (-> null). I didn't even notice because no exception raised, everything
seemed to work fine. So I ended up added a match anything pattern to all of my
actors that simply log if they received a message they couldn't handle.

Is this the recommended way to cope with such issues?

(and I also didn't notice when an exception terminated the underlying thread, I
could continue to send messages to the actor, but they were not processed at
all)

> -Stefan
>
> 2010/6/27 Timo Nentwig :
>> Hi!
>>
>> class Foo extends Actor {
>>  def act() {
>>    // loop, react
>>    case s: String =>
>>    case x: Int =>
>>    case (textTemplate: Int, language: String) =>
>>
>> So, when sending null to this actor nothing will happen probably because
>> it's impossible to decide whether this null was a String or an Int null...
>> Trying to make this somewhat more explicit by sending a val s:String=null
>> doesn't work either, I assume the type information is simply lost. Is it
>> nevertheless possible
>> somehow for the third case to only send the text template and the language
>> being
>> null (meaning that a default language is used)?
>>
>> And BTW what's the proposed way to catch unhandled exceptions in order to
>> prevent the entire actor to go down? Is there something like an
>> uncaughtExceptionHandler?
>>
>> thx,
>> tcn
>>
>
>

Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Actors: handling null messages
In cases where you may get null you can use:scala> def f(a: Any): Unit = a match {     |   case i: Int => println("int!")     |   case s: String => println("string!")      |   case x if x == null => println("null!")     | }f: (a: Any)Unit
scala> f(null)null!
scala> 
But if you're dealing with legacy data of unknown quality then I would suggest keeping a default pattern in there.  Messages that don't match the partial function aren't dropped.  They hang around in the mailbox because maybe in the future they will match.  Given enough messages you can run out of memory.
On Sun, Jun 27, 2010 at 9:15 AM, Timo Nentwig <scala@nentwig.biz> wrote:
On Sun, 27 Jun 2010, Stefan Langer wrote:

Date: Sun, 27 Jun 2010 14:49:45 +0200
From: Stefan Langer <mailtolanger@googlemail.com>
To: Timo Nentwig <scala@nentwig.biz>
Cc: scala-user@listes.epfl.ch
Subject: Re: [scala-user] Actors: handling null messages

Do not use null (this is basically only for java interoperability) use
Option instead.

Okay, this would work for my example. But my point was rather: how do I get to *know* all at if something's unexpectedly null? If a message doesn't fit a pattern, it's silently dropped.

Precisely, I ran a SQL query. I expected to get a language, but actually there was no not-null constraint (legacy, whatever) and *some* records had no language (-> null). I didn't even notice because no exception raised, everything seemed to work fine. So I ended up added a match anything pattern to all of my actors that simply log if they received a message they couldn't handle.

Is this the recommended way to cope with such issues?

(and I also didn't notice when an exception terminated the underlying thread, I could continue to send messages to the actor, but they were not processed at all)

-Stefan

2010/6/27 Timo Nentwig <scala@nentwig.biz>:
Hi!

class Foo extends Actor {
 def act() {
   // loop, react
   case s: String =>
   case x: Int =>
   case (textTemplate: Int, language: String) =>

So, when sending null to this actor nothing will happen probably because
it's impossible to decide whether this null was a String or an Int null...
Trying to make this somewhat more explicit by sending a val s:String=null
doesn't work either, I assume the type information is simply lost. Is it
nevertheless possible
somehow for the third case to only send the text template and the language
being
null (meaning that a default language is used)?

And BTW what's the proposed way to catch unhandled exceptions in order to
prevent the entire actor to go down? Is there something like an
uncaughtExceptionHandler?

thx,
tcn





--
http://erikengbrecht.blogspot.com/
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Actors: handling null messages

On Sun, Jun 27, 2010 at 09:59:25AM -0400, Erik Engbrecht wrote:
> | case x if x == null => println("null!")

Or somewhat less circuitously,

case null => println("null!")

tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.
Re: Actors: handling null messages

On Sun, 27 Jun 2010, Erik Engbrecht wrote:

> suggest keeping a default pattern in there. Messages that don't match the
> partial function aren't dropped. They hang around in the mailbox because
> maybe in the future they will match. Given enough messages you can run out
> of memory.

In future? The mailbox isn't persisted (?).

tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.
Re: Actors: handling null messages

On Sun, 27 Jun 2010, Paul Phillips wrote:

> On Sun, Jun 27, 2010 at 09:59:25AM -0400, Erik Engbrecht wrote:
>> | case x if x == null => println("null!")
>
> Or somewhat less circuitously,

:) Frankly, this didn't come to my mind, it's fun, how easy, obvious and
straight forward things are in scala :)

> case null => println("null!")

Similar to my case m => error("Unhandled message: " + m)...but this doesn't
solve the problem, the problem is that I match on tuples and don't know which
elements may be null.

Regarding my tet unanswered seconds question, I have to put all my actor code in
try-catch in order to be sure that some unhandled exception doesn't shut down
the thread/actor?

Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Actors: handling null messages
"The future" being within the lifetime of the actor.  If you don't process messages then they stay in the actors mailbox until the actor is GC'd, or if something keeps on sending the actor messages that it will ignore, until the mailbox overflows the heap and the VM dies.

On Sun, Jun 27, 2010 at 11:14 AM, Timo Nentwig <scala@nentwig.biz> wrote:


On Sun, 27 Jun 2010, Erik Engbrecht wrote:

suggest keeping a default pattern in there.  Messages that don't match the
partial function aren't dropped.  They hang around in the mailbox because
maybe in the future they will match.  Given enough messages you can run out
of memory.

In future? The mailbox isn't persisted (?).



--
http://erikengbrecht.blogspot.com/
Erik Engbrecht
Joined: 2008-12-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Actors: handling null messages
You can match on null within the tuples, and also on the type of the object in the tuples.
scala> def f(x: Any): Unit = x match {        |   case s: String => println("string!")      |   case (s: String, null) => println("string and null!")     |   case (null, s: String) => println("null and string!")     |   case (a: String, b: String) => println("two strings!")      | }f: (x: Any)Unit
scala> f(("hello", null))string and null!
Regarding your second question, yes, you need to handle exceptions.  I think in 2.8 there may be a generic mechanism for defining an actor's exception handler, but I'm not sure.
Be careful with catching exceptions within actors.  The actors library uses exceptions for flow control, so if you try to catch everything you will break it.

On Sun, Jun 27, 2010 at 11:18 AM, Timo Nentwig <scala@nentwig.biz> wrote:


On Sun, 27 Jun 2010, Paul Phillips wrote:

On Sun, Jun 27, 2010 at 09:59:25AM -0400, Erik Engbrecht wrote:
    |   case x if x == null => println("null!")

Or somewhat less circuitously,

:) Frankly, this didn't come to my mind, it's fun, how easy, obvious and straight forward things are in scala :)

case null => println("null!")

Similar to my case m => error("Unhandled message: " + m)...but this doesn't solve the problem, the problem is that I match on tuples and don't know which elements may be null.

Regarding my tet unanswered seconds question, I have to put all my actor code in try-catch in order to be sure that some unhandled exception doesn't shut down the thread/actor?



--
http://erikengbrecht.blogspot.com/
tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.
Re: Actors: handling null messages

On Sun, 27 Jun 2010, Erik Engbrecht wrote:

> Date: Sun, 27 Jun 2010 11:32:45 -0400
> From: Erik Engbrecht
> To: Timo Nentwig
> Cc: Paul Phillips ,
> Stefan Langer , scala-user@listes.epfl.ch
> Subject: Re: [scala-user] Actors: handling null messages
>
> You can match on null within the tuples, and also on the type of the object
> in the tuples.
>
> scala> def f(x: Any): Unit = x match {
> | case s: String => println("string!")
> | case (s: String, null) => println("string and null!")
> | case (null, s: String) => println("null and string!")
> | case (a: String, b: String) => println("two strings!")
> | }
> f: (x: Any)Unit
>
> scala> f(("hello", null))
> string and null!

Sure, but I had to type down and handle all permutations. Did I mention that
default values were cool? :)

case (blah:String, language:String="en")

But this would make things intransparent and complex, too...

> Regarding your second question, yes, you need to handle exceptions. I think
> in 2.8 there may be a generic mechanism for defining an actor's exception
> handler, but I'm not sure.
>
> Be careful with catching exceptions within actors. The actors library uses
> exceptions for flow control, so if you try to catch everything you will
> break it.

Hmm, good point. But what am I supposed to do? I need to catch Exception, I need
to catch RuntimeException...not sure whether I need to catch Throwable. But I
can't afford the entire actor to go down just because - for whatever reason
- whatever exception/throwable was thrown (once) :-\

> On Sun, Jun 27, 2010 at 11:18 AM, Timo Nentwig wrote:
>
>>
>>
>> On Sun, 27 Jun 2010, Paul Phillips wrote:
>>
>> On Sun, Jun 27, 2010 at 09:59:25AM -0400, Erik Engbrecht wrote:
>>>
>>>> | case x if x == null => println("null!")
>>>>
>>>
>>> Or somewhat less circuitously,
>>>
>>
>> :) Frankly, this didn't come to my mind, it's fun, how easy, obvious and
>> straight forward things are in scala :)
>>
>> case null => println("null!")
>>>
>>
>> Similar to my case m => error("Unhandled message: " + m)...but this doesn't
>> solve the problem, the problem is that I match on tuples and don't know
>> which elements may be null.
>>
>> Regarding my tet unanswered seconds question, I have to put all my actor
>> code in try-catch in order to be sure that some unhandled exception doesn't
>> shut down the thread/actor?
>>
>
>
>

Arthur Peters 2
Joined: 2009-01-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Actors: handling null messages

I'm not all that experienced witht this my self but I think you should look into the "let it fail methodology of erlang, akka and other things modeled after erland OTP (scala-otp for example). The idea is that instead of catching exceptions you let the actor die and restart it. That's what actor linking is for.

This may not be a good design in your case but its worth concidering.

-Arthur (sent from phone)

On Jun 27, 2010 11:42 AM, "Timo Nentwig" <scala@nentwig.biz> wrote:



On Sun, 27 Jun 2010, Erik Engbrecht wrote:

Date: Sun, 27 Jun 2010 11:32:45 -0400
From: Erik Engbrecht <erik.engbrecht@gmail.com>
To: Timo Nentwig <scala@nentwig.biz>
Cc: Paul Phillips <paulp@improving.org>,
   Stefan Langer <mailtolanger@googlemail.com>, scala-user@listes.epfl.ch


> Subject: Re: [scala-user] Actors: handling null messages
>

> You can match on null within the tuples, and also on the type of the object
> in the tuples.
>
> s...


Sure, but I had to type down and handle all permutations. Did I mention that default values were cool? :)

 case (blah:String, language:String="en")

But this would make things intransparent and complex, too...



> Regarding your second question, yes, you need to handle exceptions.  I think
> in 2.8 there may ...

Hmm, good point. But what am I supposed to do? I need to catch Exception, I need to catch RuntimeException...not sure whether I need to catch Throwable. But I can't afford the entire actor to go down just because - for whatever reason - whatever exception/throwable was thrown (once) :-\



> On Sun, Jun 27, 2010 at 11:18 AM, Timo Nentwig <scala@nentwig.biz> wrote:
>
>>
>>
>> On Sun, 27 ...

Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Actors: handling null messages

Timo Nentwig wrote:
> On Sun, 27 Jun 2010, Erik Engbrecht wrote:
>> Regarding your second question, yes, you need to handle exceptions. I think
>> in 2.8 there may be a generic mechanism for defining an actor's exception
>> handler, but I'm not sure.
>>
>> Be careful with catching exceptions within actors. The actors library uses
>> exceptions for flow control, so if you try to catch everything you will
>> break it.
>
> Hmm, good point. But what am I supposed to do? I need to catch Exception, I need
> to catch RuntimeException...not sure whether I need to catch Throwable. But I
> can't afford the entire actor to go down just because - for whatever reason
> - whatever exception/throwable was thrown (once) :-\

First, on Scala 2.8 you can override `def exceptionHandler:
PartialFunction[Exception, Unit]` to return a partial function that
handles certain exceptions globally. Note that if you are inside a
`loop`, execution resumes with the next iteration after the exception
has been handled (same for `loopWhile`, `andThen` etc.).

Second, you can safely catch exceptions inside actors if you take care
not to catch instances of `scala.util.control.ControlThrowable`, for example

try {
// ...
} catch {
case e: Throwable if
!e.isInstanceOf[scala.util.control.ControlThrowable] =>
...
}

Cheers,
Philipp

>> On Sun, Jun 27, 2010 at 11:18 AM, Timo Nentwig wrote:
>>
>>>
>>> On Sun, 27 Jun 2010, Paul Phillips wrote:
>>>
>>> On Sun, Jun 27, 2010 at 09:59:25AM -0400, Erik Engbrecht wrote:
>>>>> | case x if x == null => println("null!")
>>>>>
>>>> Or somewhat less circuitously,
>>>>
>>> :) Frankly, this didn't come to my mind, it's fun, how easy, obvious and
>>> straight forward things are in scala :)
>>>
>>> case null => println("null!")
>>> Similar to my case m => error("Unhandled message: " + m)...but this doesn't
>>> solve the problem, the problem is that I match on tuples and don't know
>>> which elements may be null.
>>>
>>> Regarding my tet unanswered seconds question, I have to put all my actor
>>> code in try-catch in order to be sure that some unhandled exception doesn't
>>> shut down the thread/actor?
>>>
>>
>>

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Actors: handling null messages
You might be able to implement the "default" using extractors, if someone knows the syntax offhand.I don't know if you'll be able to do
  case (blah:String, Language("en")(language)) or simply  case (blah: String, Language(language))  // Language uses "en" in place of null


On Sun, Jun 27, 2010 at 11:42 AM, Timo Nentwig <scala@nentwig.biz> wrote:


On Sun, 27 Jun 2010, Erik Engbrecht wrote:

Date: Sun, 27 Jun 2010 11:32:45 -0400
From: Erik Engbrecht <erik.engbrecht@gmail.com>
To: Timo Nentwig <scala@nentwig.biz>
Cc: Paul Phillips <paulp@improving.org>,
   Stefan Langer <mailtolanger@googlemail.com>, scala-user@listes.epfl.ch
Subject: Re: [scala-user] Actors: handling null messages

You can match on null within the tuples, and also on the type of the object
in the tuples.

scala> def f(x: Any): Unit = x match {
   |   case s: String => println("string!")
   |   case (s: String, null) => println("string and null!")
   |   case (null, s: String) => println("null and string!")
   |   case (a: String, b: String) => println("two strings!")
   | }
f: (x: Any)Unit

scala> f(("hello", null))
string and null!

Sure, but I had to type down and handle all permutations. Did I mention that default values were cool? :)

 case (blah:String, language:String="en")

But this would make things intransparent and complex, too...

Regarding your second question, yes, you need to handle exceptions.  I think
in 2.8 there may be a generic mechanism for defining an actor's exception
handler, but I'm not sure.

Be careful with catching exceptions within actors.  The actors library uses
exceptions for flow control, so if you try to catch everything you will
break it.

Hmm, good point. But what am I supposed to do? I need to catch Exception, I need to catch RuntimeException...not sure whether I need to catch Throwable. But I can't afford the entire actor to go down just because - for whatever reason - whatever exception/throwable was thrown (once) :-\

On Sun, Jun 27, 2010 at 11:18 AM, Timo Nentwig <scala@nentwig.biz> wrote:



On Sun, 27 Jun 2010, Paul Phillips wrote:

 On Sun, Jun 27, 2010 at 09:59:25AM -0400, Erik Engbrecht wrote:

   |   case x if x == null => println("null!")


Or somewhat less circuitously,


:) Frankly, this didn't come to my mind, it's fun, how easy, obvious and
straight forward things are in scala :)

 case null => println("null!")


Similar to my case m => error("Unhandled message: " + m)...but this doesn't
solve the problem, the problem is that I match on tuples and don't know
which elements may be null.

Regarding my tet unanswered seconds question, I have to put all my actor
code in try-catch in order to be sure that some unhandled exception doesn't
shut down the thread/actor?




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