NPE when sending an ask in a closure

63 views
Skip to first unread message

Simon Schäfer

unread,
Jan 15, 2014, 12:11:51 PM1/15/14
to akka...@googlegroups.com
I have the following code:

import scala.concurrent.Future
import scala.concurrent.Promise
import scala.concurrent.duration.DurationInt
import scala.concurrent.duration.FiniteDuration

import akka.actor.Actor
import akka.actor.ActorRef
import akka.pattern.ask
import akka.util.Timeout.durationToTimeout

trait ActorHelpers {

  self: Actor =>

  import context.dispatcher

  def keepAsking(recipient: ActorRef, msg: Any, interval: FiniteDuration): Future[Any] = {
    val p = Promise[Any]()
    val cancel = context.system.scheduler.schedule(0.millis, interval) {
      if (context != null)
        (recipient ? msg)(1.hour) foreach p.trySuccess
    }
    val f = p.future
    f.onComplete(_ => cancel.cancel())
    f
  }

}


The idea of this code snippet is that a message is resend as long as an answer is retrieved. The problem is that I sometimes get a NPE on the line that contains the ask.

Without the check if context is null I get even more NPEs. I don't understand why I get NPEs here, because I can't see where context or some of its state is accessed. Can someone explain it?

√iktor Ҡlang

unread,
Jan 15, 2014, 12:22:35 PM1/15/14
to Akka User List
Hint: remove import context.dispatcher
 

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.



--
Cheers,

Viktor Klang

Director of Engineering

Twitter: @viktorklang

√iktor Ҡlang

unread,
Jan 15, 2014, 1:26:57 PM1/15/14
to Akka User List
As for implementation, I'd probably do something like this: (WARNING: NOT COMPILED)

 import akka.pattern.after

 def keepAsking(recipient: ActorRef, msg: Any, every: FiniteDuration)(implicit ec: ExecutionContext, scheduler: Scheduler): Future[Any] = {
    def retry(): Future[Any] = after(every, scheduler)((recipient ? msg)(every)) recoverWith { case _ => retry() }
    retry()
  }
--
Cheers,

Viktor Klang

Concurrent, Distributed

Twitter: @viktorklang

Simon Schäfer

unread,
Jan 17, 2014, 6:10:47 PM1/17/14
to akka...@googlegroups.com


On Wednesday, January 15, 2014 6:22:35 PM UTC+1, √ wrote:

Hint: remove import context.dispatcher

Awesome, removing the import and adding it the ExecutionContext as implicit argument solved the problem.

Nevertheless, I do not understand what the difference is. I had to add the import in the class that calls my helper function, which gets available through trait mixin. Thus, why is it not the same reference?

√iktor Ҡlang

unread,
Jan 18, 2014, 3:17:13 AM1/18/14
to Akka User List

Hint: context is a method. What gets closed over?

--

Simon Schäfer

unread,
Jan 18, 2014, 4:29:42 AM1/18/14
to akka...@googlegroups.com

On 01/18/2014 09:17 AM, √iktor Ҡlang wrote:

Hint: context is a method. What gets closed over?

Ok, got it. Thanks for help.
You received this message because you are subscribed to a topic in the Google Groups "Akka User List" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/akka-user/Utj2emipjeU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to akka-user+...@googlegroups.com.

√iktor Ҡlang

unread,
Jan 18, 2014, 5:16:48 AM1/18/14
to Akka User List

Happy hAkking! :)

Reply all
Reply to author
Forward
0 new messages