AlessandroEmm AlessandroEmm - 2 months ago 10
Scala Question

Do something only once, without state

I have the following situation:

Upon initialitation (actually first receive) of a socket I want to check something in the handshake (TLS), this has to be only checked upon connection initialization and not on every further receive.

Currently I have an odd:

// this is happening outer scope
var somethingThatGetsComputedinInit = 0

def receive {
if (init) {
somethingThatGetsComputedinInit = doinitstuff(StuffIOnlyGetInitially)
init = false
}
}


Although it would work, this smells so imperative and ugly. What would be a purely functional solution to this?

Answer

In your specific example, since you are using actors, you actually can swap out its implementation to model a state machine using "context.become and context.unbecome". There is an abstraction layer, Akka FSM, on top of this which provides a nicer syntax for doing exactly this type of thing.

Example partially lifted from the Akka FSM docs:

sealed trait State
case object Initializing extends State
case object Initialized extends State

class Socket extends Actor with FSM[State, Option[Client]] {

  startWith(Initializing, None)

  when(Initializing) {
    case Event(msg: Connect, _) => createClient(msg).fold(stay) {
      client => 
        //Do more stuff
        goto(Initialized) using Some(client)
    }
  }

  when(Initialized) {
    case Event(msg: Receive, data@Some(client)) => 
      //Do more stuff using client
      stay using data
  }

  initialize()

}
Comments