Skip to content
laforge49 edited this page Jul 26, 2011 · 10 revisions

Large composites often have complex initialization and takedown. To help with this, on receipt of the first message an actor calls the open method on each of its components in the order in which they were added to the actor. In addition, actors have a close method which calls a close method on its components in reverse order.

Once an actor receives a message, no more components can be added.

We can illustrate this with two simple components which print a message when they are opened or closed.

class SC1Factory extends ComponentFactory {
  addDependency(classOf[SC2Factory])
  override protected def instantiate(actor: Actor) = new SC1(actor, this)
}

class SC1(actor: Actor, componentFactory: ComponentFactory) extends Component(actor, componentFactory) {
  override def open {println("SC1 open")}
  override def close {println("SC1 close")}
}

class SC2Factory extends ComponentFactory {
  override protected def instantiate(actor: Actor) = new SC2(actor, this)
}

case class DoIt()

class SC2(actor: Actor, componentFactory: ComponentFactory) extends Component(actor, componentFactory) {

  override def open {println("SC2 open")}

  override def close {println("SC2 close")}

  def doit(msg: AnyRef, rf: Any => Unit) {
    println("Done it!")
    rf(null)
  }
}

Since SC1 depends on SC2, SC2 should be opened before SC1 and SC1 should be closed before SC2. The test code for this is quite brief.

class CompositeFactory extends Factory(null) {
  include(new SC1Factory)
}

val actor = (new CompositeFactory).newActor(null)
Future(actor, DoIt())
actor.close

And here is the output.

SC2 open
SC1 open
Done it!
SC1 close
SC2 close

LifecycleTest

Clone this wiki locally