scala - One-off object pooling with Actor provider -
I have an object with a heavy initial cost and memory footprint. I the initial time is human-worthable but the production frequency is low is.
HeavyClass {heavyInit ()}My solution is to create a provider actor, an object created prematurely and provide immediate request. After that the providers will run with creating further objects.
class HeavyClassProvider extends the actor {var hc: option [HeavyClass] = some (new heavy class ()) override DRF = {case "request" = & gt; Sender ! {HC getOrElse new HeavyClass ()} self! "RESPAWN" HC = Any case "RESPAWN" if (HC == none) => HC = Some (new HeavyClass ())}}
and a consumer:
Intangible class Heavy classcoreman extends actor {import context.dispatcher Import akka.pattern .cack import scale Concentrations _ Import unit built-in value timeout = timeout (5, sec) var Provider: Actor RHCH: Option [HeavyClass] = No override DRF Received = {Case "Start" = & gt; (The provider asks "request"). Success on the map [Heavy class] {Case H: Heavy class => HC = Som (H)})}}
Is there a similar pattern? Code looks hopeless, is there a clear way to do this?
There is a problem with your solution when you new heavy class ()
, Your actor gets blocked until this computation process is done. It is avoided in future or in any other actor. One way to do this is:
import akka.pattern.pipe ... class HeavyClassProvider extends the actor {// start inync during computation init: var hc: future [HeavyClass ] = Future (new heavyclass) override deaf received = {case "request" = & gt; // When the result is complete, send the result to the requestor / immediately upon completion // Immediately: // start a new calculation for HC pipe sender and send yourself: The result of the new FC (new heavyclass) pipe self case: Heavy class = & Gt; // New result is ready HC = Future Successful (result) // update with new calculation results case status Failier (F) = & gt; // calculation fail hc = future.phale [heavyclass] (f) // maybe request repeat again}}
(I have not compiled it)
My first solution is to calculate how much futures are done at the same time not restricted If you receive multiple requests, then it will calculate many futures that can not be desirable, Although there is no race situation in this actor to restrict Just present a boolean flag in the actor who tells you whether you are doing some computing in advance, apart from these, all these var
s becoming / unhappy
behaviors Can be changed.
There are several requests for a Single Concurrent Future Count :
Import akka.pattern.pipe ... Category HeavyClassProvider Extension of the actor {// Init: var hc: future [HeavyClass] = future (new HeavyClass) pipe self-computing computing: Boolean = true override def = {case "request" = & gt; // Completed by the sender / immediate completion of the request to the requestor // immediately: // start a new calculation for HC pipe sender and send yourself: if (! Computing) future (new heavyclass) pipe self case result : Heavy class = & gt; // The new result is ready HC = future. Successful (result) // updated with new computed results computing = false case status. Feller (f) = & gt; // calculation fail hc = future.file [heavyclass] (f) computing = false // maybe request repeat again}}
edit: further requirements in comments here After discussing yet another implementation that sends new object to the sender / customer :
import akka.pattern. Pipe ... class HeavyClassProvider is extracted actor {Override def = {case "request" => Future (New Heavy Class) sender to pipe}}
and then it can be simplified:
object SomeFactoryObject {def computeLongOp: Future [Heavyclass] = Future (New Heavy Class)}
In this case no actor is required. In the case of synchronization mechanism and non-blocking computing, the purpose of using an actor in these cases is for the cash result of that actor and provides async count with more complex logic than just future
Is, otherwise the future
is enough.
Comments
Post a Comment