IncDesInt - laforge49/Asynchronous-Functional-Programming GitHub Wiki

There are 3 types of messages handled by all IncDes actors.

case class Length()
case class Bytes()
case class Copy(mailbox: Mailbox)
  1. Length is used to determine the number of bytes needed to save the serialized form of an IncDes actor. The returned result is an Int.
  2. The result returned by Bytes is an Array[Byte] holding the persistent form of an IncDes actor. And
  3. Copy creates an unopened copy of an IncDes actor with the same content and name as the IncDes actor.

There are also 2 types of messages handled by basic item actors.

case class Value()
case class Set[V](transactionContext, value: V)
  1. Value returns as a result the value which the item was assigned.
  2. Set assigns a value and returns a result of null.

In the case of IncDesInt, the value must be an Int with an initial value of 0.

###Testing

We will start by looking at test code for Length, Bytes, Value and Set.

val j1 = IncDesInt(null)
Future(j1, Set(null, 32))
Future(j1, Length()) must be equalTo (4)
Future(j1, Value()) must be equalTo (32)
var bs = Future(j1, Bytes()).asInstanceOf[Array[Byte]]

val j2 = IncDesInt(null)
j2.load(bs)
Future(j2, Value()) must be equalTo (32)

val j3 = IncDesInt(null)
Future(j3, Set(null, -4))
bs = Future(j3, Bytes()).asInstanceOf[Array[Byte]]

val j4 = IncDesInt(null)
j4.load(bs)
bs = Future(j4, Bytes()).asInstanceOf[Array[Byte]]

val j5 = IncDesInt(null)
j5.load(bs)
Future(j5, Value()) must be equalTo (-4)

The IncDesComponentFactory depends on FactoryRegistryComponentFactory and configures it with the factories for the IncDes actors. This means that by using a system services actor which includes IncDesComponentFactory, we can use Instantiate messages to create IncDes actors. And the val INC_DES_INT_FACTORY_ID has been assigned the factory id of the factory for IncDesInt.

To test factory creation and Copy, we will need a Driver actor.

case class DoIt()

class Driver extends Actor {
  bind(classOf[DoIt], doit)
  setMailbox(new ReactorMailbox)

  def doit(msg: AnyRef, rf: Any => Unit) {
    val results = new Results
    val chain = new Chain(results)
    chain.op(systemServices, Instantiate(INC_DES_INT_FACTORY_ID, null), "incDesInt")
    chain.op(Unit => results("incDesInt"), Set(null, 42))
    chain.op(Unit => results("incDesInt"), Copy(null), "clone")
    chain.op(Unit => results("clone"), Value())
    this(chain)(rf)
  }
}

On receipt of a DoIt message, Driver does the following:

  1. Create an IncDesInt actor.
  2. Assign the IncDesInt actor a value of 42.
  3. Makes a copy of the IncDesInt actor.
  4. Returns the value assigned to the copy.

Finally, we need a bit of code.

val systemServices = SystemServices(new IncDesComponentFactory)
val driver = new Driver
driver.setSystemServices(systemServices)
Future(driver, DoIt()) must be equalTo (42)

This code does the needful.

  1. Create the system services actor,
  2. Create the Driver actor,
  3. Inject the system services actor into the Driver actor,
  4. Send a DoIt message to the Driver and then
  5. Verify the reults.

IntTest

tutorial