Question

I want to be able to track number of task completed in some state machine (using Akka FSM), it's like joining N actions, started on transition from state A to B, in state B. So when all evens reach FSM on state B - it proceeds to state C.

I created very simple tracker for fork/join states.

  sealed trait ForkJoin {

    def join(): ForkJoin

  }

  case class Forks(forkNum: Int) extends ForkJoin {

    private var finished: Int = 0

    override def join = if (finished + 1 == forkNum) JoinComplete
    else {
      val f = Forks(forkNum)
      f.finished = finished + 1
      f
    }

  }

  case object JoinComplete extends ForkJoin {

    override def join = JoinComplete

  }

What I don't like there - pewsense of var finished. By it's nature it is val, however I have no idea how to make a private val and initialize it in join method.

I thought there is some way to make a constructor argument as private, not accessible from outside - but this doesn't work.

Was it helpful?

Solution

It is not possible to pass private arguments to case classes. It doesn't make sense, because the identity of an instance of a case class is defined over the passed constructor arguments. A private constructor argument would change the state but would not affect neither equality comparisons nor pattern matches.

What you can do is make the whole constructor private. To function properly as a FSM state you may need to implement equals and hashCode on your own [1].

sealed trait ForkJoin {
  def join(): ForkJoin
}

case class Forks private(forkNum: Int, finished: Int) extends ForkJoin{

  override def join =
    if (finished + 1 == forkNum)
      JoinComplete
    else
      Forks(forkNum, finished + 1)

  def copy(forkNum: Int = this.forkNum) = 
    Forks(forkNum, finished)

}

object Forks{
  def apply(forkNum: Int): Forks = Forks(forkNum, 0)
}

object JoinComplete extends ForkJoin {
  override def join = JoinComplete
}

OTHER TIPS

something like that?

sealed trait ForkJoin {
    def join(): ForkJoin
 }

  case class Forks(forkNum: Int, finished: Int = 0) extends ForkJoin {
    override def join = if (finished + 1 == forkNum) JoinComplete
    else Forks(forkNum, finished + 1)
   }

  case object JoinComplete extends ForkJoin {
    override def join = JoinComplete
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top