scala - Actor that waits for completing all jobs in children before exit -
can't figure out how resolve following problem: have few actors (workers) execute tasks in way when recieve (i mean react) them. main actor (foreman) controls process , can recieve task stop work. in case main actor must stop creating new tasks , wait when workers finish existing tasks , main actor should exit.
import actors.actor import actors.actor._ class foreman extends actor{ val workera = new workera val workerb = new workerb val workerc = new workerc self.link(workera) self.link(workerb) self.link(workerc) def act{ workera.start workerb.start workerc.start // adding tasks workers somehow //... loop{ case resultoftask(res) => //... case stop => //workers mustn't stop must finish tasks , exit case productionaccident => //... } } } case class task(activity:string) case class resultoftask(result:string) trait worker extends actor{ def act{ loop{ react{ case task(activity) => sender ! processtask(activity) } } } def processtask(activity:string):resultoftask }
to solve wrote following code:
def condition = workera.getstate!=state.suspended && workerb.getstate!=state.suspended && workerc.getstate!=state.suspended && mailboxsize == 0 case stop => { if(condition) exit("sweet dreams") else continue }
to check if main actor should exit. variant have counder in "worker" trait, increment when worker recieves message , decrement when reponses.
trait worker extends actor { private var count = 0 def act { loop{ react{ case task(activity) => { count += 1 sender ! processtask(activity) count -= 1 } } } } def hasdonealltasks = count == 0 def processtask(activity: string): resultoftask }
and "condition" function in "foreman" be
def condition = workera.hasdonealltasks && workerb.hasdonealltasks && workerc.hasdonealltasks && mailboxsize == 0
i hope there better solutions , propose them.
if foreman expects answer workers, solution easy: foreman maintains counter, , each time sends message increments , each time receives 1 worker decrements it. time counter 0 free stop (assuming no-one else sends messages workers).
if foreman not expect answer workers, can make case having no-content message
case object done { }
and having workers reply when they're finished. then, see above.
if foreman not 1 talking workers, or want there less chatter in background, foreman , workers have negotiate. foreman can send
case object requeststop { }
and workers graceful , reply done
when they're done. when foreman receives many done
messages has sent requeststop
s, free exit.
Comments
Post a Comment