#! /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
}


AltStyle によって変換されたページ (->オリジナル) /