#! /usr/bin/env fan
//
// Copyright (c) 2009, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 08 Sep 09 Brian Frank Creation
//
using concurrent
**
** Basic actor examples
**
class Actors
{
Void main()
{
echoActor
counterActor
coalescingActor
}
Void echoActor()
{
echo("\n--- echoActor ---")
// this actor just echos messages sent to it
a := Actor(ActorPool()) |msg| { echo(msg); return msg }
// send some messages and have them printed to console
f1 := a.send("message 1")
f2 := a.send("message 2")
f3 := a.send("message 3")
// now block for the result of each message
echo("Result 1 = " + f1.get)
echo("Result 2 = " + f2.get)
echo("Result 3 = " + f3.get)
}
Void counterActor()
{
echo("\n--- echoCounter ---")
// this actor stores state in context to keep
// track of a simple counter everytime a message is received
a := Actor(ActorPool()) |msg|
{
if (msg == "current") return Actor.locals["counter"]
if (msg == "reset") { Actor.locals["counter"] = 0; return null }
Actor.locals["counter"] = 1 + (Int)Actor.locals["counter"]
return null // ignored
}
// reset the counter to zero
a.send("reset")
// send 100 messages
100.times { a.send(it) }
// send the "get" message and block for result
echo("Result " + a.send("current").get)
}
Void coalescingActor()
{
echo("\n--- coalescingActor ---")
// this function is used to get coalesing key
toKey := |Rec msg->Obj| { msg.key }
// this function is used to coalesce two messages with same key
coalesce := |Rec oldOne, Rec newOne->Rec| { Rec(oldOne.key, oldOne.data.dup.addAll(newOne.data)) }
// this our receive function
receive := |Rec msg| { echo(msg.key + ": " + msg.data) }
// create an actor that "writes" multiple records
// to standard out, we coalesce and pending writes
// into a single write
a := Actor.makeCoalescing(ActorPool(), toKey, coalesce, receive)
// blast messages to the actor with the same key to see how
// pending messages are coalesced
100.times |i|
{
key := i.isEven ? "a" : "b"
a.send(Rec(key, [i.toStr]))
}
// stop and wait until done
a.pool.stop.join
}
}
const class Rec
{
new make(Str k, Str[] d) { key = k; data = d }
const Str key
const Str[] data
}