How can I get information from another actor right when an actor starts to create (or immediately alter) the behavior?

In my app, I need an actor to get some information from another actor either at, or immediately after startup. This information needs to be used to return another behavior, since that actor cannot do much before this happens. The problem that I am seeing is that it has to obtain the information from another actor, so that requires a future. So far, this is what I have, but I would like to know if this is a/the right way to go about something like this:

  def apply(iterationNumber: Int, localPlayerId: String, maxIterationSeconds: Int)
           (implicit timeout: Timeout, scheduler: Scheduler, ec: ExecutionContext): Behavior[IterationCommand] = {
    Behaviors.setup { context =>
      val receptionist = context.system.receptionist
      context.system.receptionist ! Receptionist.Register(iterationServiceKey, context.self)

      val temporaryBehavior = Behaviors.receiveMessage[IterationCommand] {
        case ElectedLeaderId(leaderId) =>
          val timer = context.scheduleOnce((3 * maxIterationSeconds).seconds, context.self, StopIteration)
          iterationBehavior(iterationNumber, localPlayerId, leaderId, Seq.empty, receptionist, timer, context)
        case _ =>

      electLeader(iterationNumber, receptionist, context.self)

the electLeader method calls out to another actor to get some information so that it can do that election.

Overall, that looks reasonable (especially if the expectation is that messages sent before a leader is elected are discarded… if they’re meant to be (possibly) processed once the leader is elected, a stash is called for).

The electLeader function seems a bit unwieldy: it takes a Timeout but then doesn’t seem to give the caller any way to deal with the timeout (e.g. to signal that no leader was elected within the timeout (or some multiple thereof)). If context.self isn’t relevant for the logic in electLeader beyond forwarding the ElectedLeaderId to the actor, I’d consider adjusting to something like (omitting types):

def electLeader(iterationNumber, receptionist)(implicit timeout, scheduler, ec): Future[LeaderIdType]

context.pipeToSelf(electLeader(iterationNumber, receptionist)) {
  case Success(leaderId) => ElectedLeaderId(leaderId)
  case Failure(ex) => FailedToElectLeader(...)

The Scheduler and likely ExecutionContext (unless there’s going to be substantial thread blocking in electLeader) are both going to come from the ActorSystem, so they can probably be removed as implicit args. So could the receptionist, for that matter: taking an ActorSystem (e.g. an ActorSystem[Nothing]) as an argument might simplify signatures.