Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8668795
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T18:18:10+00:00 2026-06-12T18:18:10+00:00

I have actors that need to do very long-running and computationally expensive work, but

  • 0

I have actors that need to do very long-running and computationally expensive work, but the computation itself can be done incrementally. So while the complete computation itself takes hours to complete, the intermediate results are actually extremely useful, and I’d like to be able to respond to any requests of them. This is the pseudo code of what I want to do:

var intermediateResult = ...
loop {
     while (mailbox.isEmpty && computationNotFinished)
       intermediateResult = computationStep(intermediateResult)


     receive {
         case GetCurrentResult => sender ! intermediateResult
         ...other messages...
     }
 }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T18:18:11+00:00Added an answer on June 12, 2026 at 6:18 pm

    I assume from your comment to Roland Kuhn answer that you have some work which can be considered as recursive, at least in blocks. If this is not the case, I don’t think there could be any clean solution to handle your problem and you will have to deal with complicated pattern matching blocks.

    If my assumptions are correct, I would schedule the computation asynchronously and let the actor be free to answer other messages. The key point is to use Future monadic capabilities and having a simple receive block. You would have to handle three messages (startComputation, changeState, getState)

    You will end up having the following receive:

    def receive {
      case StartComputation(myData) =>expensiveStuff(myData)
      case ChangeState(newstate) = this.state = newstate
      case GetState => sender ! this.state
    }
    

    And then you can leverage the map method on Future, by defining your own recursive map:

     def mapRecursive[A](f:Future[A], handler: A => A, exitConditions: A => Boolean):Future[A] = {
        f.flatMap {  a=>
                     if (exitConditions(a))
                       f
                     else {
                         val newFuture = f.flatMap{ a=> Future(handler(a))}
                         mapRecursive(newFuture,handler,exitConditions)
                     }
    
                  }
      }
    

    Once you have this tool, everything is easier. If you look to the following example :

    def main(args:Array[String]){
        val baseFuture:Future[Int] = Promise.successful(64)
        val newFuture:Future[Int] = mapRecursive(baseFuture,
                                     (a:Int) => {
                                       val result = a/2
                                       println("Additional step done: the current a is " + result)
                                       result
                                     }, (a:Int) => (a<=1))
    
        val one = Await.result(newFuture,Duration.Inf)
        println("Computation finished, result = " + one)
    
    
    
      }
    

    Its output is:

    Additional step done: the current a is 32

    Additional step done: the current a is 16

    Additional step done: the current a is 8

    Additional step done: the current a is 4

    Additional step done: the current a is 2

    Additional step done: the current a is 1

    Computation finished, result = 1

    You understand you can do the same, inside your expensiveStuffmethod

      def expensiveStuff(myData:MyData):Future[MyData]= {
        val firstResult = Promise.successful(myData)
        val handler : MyData => MyData = (myData) => {
          val result = myData.copy(myData.value/2)
          self ! ChangeState(result)
          result
        }
        val exitCondition : MyData => Boolean = (myData:MyData) => myData.value==1
        mapRecursive(firstResult,handler,exitCondition)
      }
    

    EDIT – MORE DETAILED

    If you don’t want to block the Actor, which processes messages from its mailbox in a thread-safe and synchronous manner, the only thing you can do is to get the computation executed on a different thread. This is exactly an high performance non blocking receive.

    However, you were right in saying that the approach I propose pays a high performance penalty. Every step is done on a different future, which might be not necessary at all. You can therefore recurse the handler to obtain a single-threaded or multiple-threaded execution. There is no magic formula after all:

    • If you want to schedule asynchronously and minimize the cost, all the work should be done by a single thread
    • This however could prevent other work to start, because if all the threads on a thread pool are taken, the futures will queue. You might therefore want to break the operation into multiple futures so that even at full usage some new work can be scheduled before old work has been completed.

    def recurseFuture[A](entryFuture: Future[A], handler: A => A, exitCondition: A => Boolean, maxNestedRecursion: Long = Long.MaxValue): Future[A] = {
            def recurse(a:A, handler: A => A, exitCondition: A => Boolean, maxNestedRecursion: Long, currentStep: Long): Future[A] = {
              if (exitCondition(a))
                Promise.successful(a)
              else
                if (currentStep==maxNestedRecursion)
                  Promise.successful(handler(a)).flatMap(a => recurse(a,handler,exitCondition,maxNestedRecursion,0))
                else{
                  recurse(handler(a),handler,exitCondition,maxNestedRecursion,currentStep+1)
                }
            }
            entryFuture.flatMap { a => recurse(a,handler,exitCondition,maxNestedRecursion,0) }
          }
    

    I have enhanced for testing purposes my handler method:

      val handler: Int => Int = (a: Int) => {
          val result = a / 2
          println("Additional step done: the current a is " + result + " on thread " + Thread.currentThread().getName)
          result
        }
    

    Approach 1: Recurse the handler on itself so to get all execute on a single thread.

        println("Starting strategy with all the steps on the same thread")
        val deepestRecursion: Future[Int] = recurseFuture(baseFuture,handler, exitCondition)
        Await.result(deepestRecursion, Duration.Inf)
        println("Completed strategy with all the steps on the same thread")
        println("")
    

    Approach 2: Recurse for a limited depth the handler on itself

    println("Starting strategy with the steps grouped by three")
    val threeStepsInSameFuture: Future[Int] = recurseFuture(baseFuture,handler, exitCondition,3)
    val threeStepsInSameFuture2: Future[Int] = recurseFuture(baseFuture,handler, exitCondition,4)
    Await.result(threeStepsInSameFuture, Duration.Inf)
    Await.result(threeStepsInSameFuture2, Duration.Inf)
    println("Completed strategy with all the steps grouped by three")
    executorService.shutdown()
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have read that, when using react, all actors can execute in a single
I have quite large files that I need to deal with (500Meg+ zip files).
Let's say I have a supervisor that has linked 2 actors. When my app
I need help to put an XSLT condition that work: within for-each loop that
Let me first say that I have quite a lot of Java experience, but
Consider a game engine that utilizes a scene . Now, a scene can have
I have written a very simple webserver in Scala (based on Actors). The purpose
I have a Movies and a Actors table and Casts as join-model. To be
i have table with filmname and actors column in sql server 2005 i want
I have created a database of my movies and another with my actors in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.