1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
package examples.actors
import java.util.Date
import scala.actors._
import scala.actors.Actor._
/** A simple demonstrator program implementing an online auction service
* The example uses the actor abstraction defined in the API of
* package scala.actors.
*/
trait AuctionMessage
case class Offer(bid: Int, client: Actor) extends AuctionMessage // make a bid
case class Inquire(client: Actor) extends AuctionMessage // inquire status
trait AuctionReply
case class Status(asked: Int, expiration: Date) // asked sum, expiration date
extends AuctionReply
case object BestOffer extends AuctionReply // yours is the best offer
case class BeatenOffer(maxBid: Int) extends AuctionReply // offer beaten by maxBid
case class AuctionConcluded(seller: Actor, client: Actor) // auction concluded
extends AuctionReply
case object AuctionFailed extends AuctionReply // failed with no bids
case object AuctionOver extends AuctionReply // bidding is closed
class AuctionActor(seller: Actor, minBid: Int, closing: Date) extends Actor {
val timeToShutdown = 3000 // msec
val bidIncrement = 10
def act() {
var maxBid = minBid - bidIncrement
var maxBidder: Actor = null
loop {
reactWithin (closing.getTime() - new Date().getTime()) {
case Offer(bid, client) =>
if (bid >= maxBid + bidIncrement) {
if (maxBid >= minBid)
maxBidder ! BeatenOffer(bid)
maxBid = bid
maxBidder = client
client ! BestOffer
}
else
client ! BeatenOffer(maxBid)
case Inquire(client) =>
client ! Status(maxBid, closing)
case TIMEOUT =>
if (maxBid >= minBid) {
val reply = AuctionConcluded(seller, maxBidder)
maxBidder ! reply
seller ! reply
} else {
seller ! AuctionFailed
}
reactWithin(timeToShutdown) {
case Offer(_, client) => client ! AuctionOver
case TIMEOUT => exit()
}
}
}
}
}
object auction {
val random = new scala.util.Random
val minBid = 100
val closing = new Date(new Date().getTime() + 4000)
val seller = Actor.actor { }
val auction = new AuctionActor(seller, minBid, closing)
def client(i: Int, increment: Int, top: Int) = new Actor {
val name = "Client " + i
def log(msg: String) = Console.println(name + ": " + msg)
var max: Int = _
var current: Int = 0
def act() {
log("started")
auction ! Inquire(this)
receive {
case Status(maxBid, _) =>
log("status(" + maxBid + ")")
max = maxBid
}
loop {
if (max >= top) {
log("too high for me")
}
else if (current < max) {
current = max + increment
Thread.sleep(1 + random.nextInt(1000))
auction ! Offer(current, this)
}
reactWithin(3000) {
case BestOffer =>
log("bestOffer(" + current + ")")
case BeatenOffer(maxBid) =>
log("beatenOffer(" + maxBid + ")")
max = maxBid
case AuctionConcluded(seller, maxBidder) =>
log("auctionConcluded"); exit()
case AuctionOver =>
log("auctionOver"); exit()
case TIMEOUT =>
exit()
}
}
}
}
def main(args: Array[String]) {
seller.start()
auction.start()
client(1, 20, 200).start()
client(2, 10, 300).start()
}
}
|