Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
723689ae
Commit
723689ae
authored
May 14, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
scala remote actors benchmark
parent
7fdfbfb4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
210 additions
and
47 deletions
+210
-47
benchmarks/Distributed.scala
benchmarks/Distributed.scala
+210
-47
No files found.
benchmarks/Distributed.scala
View file @
723689ae
import
akka.actor.
{
Props
,
Actor
,
ActorRef
,
ActorSystem
}
import
akka.actor.
{
Props
,
Actor
=>
AkkaActor
,
ActorRef
=>
AkkaActorRef
,
ActorSystem
}
import
scala.actors.
{
Actor
,
AbstractActor
,
OutputChannel
}
import
scala.actors.remote.RemoteActor
import
scala.actors.remote.RemoteActor._
import
scala.actors.remote.Node
import
com.typesafe.config.ConfigFactory
import
Console.println
...
...
@@ -13,18 +19,134 @@ case class AddPong(path: String)
case
object
Hello
case
object
Olleh
case
class
PongDidNotRespond
(
pong
:
ActorRef
,
ping
:
ActorRef
)
case
class
PongDidNotRespond
(
pong
:
AkkaActorRef
,
ping
:
AkkaActorRef
)
case
class
RemoteActorPath
(
uri
:
String
,
host
:
String
,
port
:
Int
)
case
class
RunClient
(
pongs
:
List
[
ActorRef
],
numPings
:
Int
)
case
class
RunClient
(
pongs
:
List
[
RemoteActorPath
],
numPings
:
Int
)
case
class
RunAkkaClient
(
pongs
:
List
[
AkkaActorRef
],
numPings
:
Int
)
object
global
{
val
latch
=
new
java
.
util
.
concurrent
.
CountDownLatch
(
1
)
}
class
PingActor
(
parent
:
ActorRef
,
pong
:
ActorRef
)
extends
Actor
{
class
PingActor
(
parent
:
OutputChannel
[
Any
],
pong
:
AbstractActor
)
extends
Actor
{
override
def
act
()
=
react
{
case
Pong
(
0
)
=>
{
parent
!
Done
}
case
Pong
(
value
)
=>
{
reply
(
Ping
(
value
-
1
))
act
}
case
KickOff
(
value
)
=>
{
pong
!
Ping
(
value
)
act
}
}
}
class
ServerActor
(
port
:
Int
)
extends
Actor
{
private
var
pongs
:
List
[
Pair
[
String
,
AbstractActor
]]
=
Nil
final
def
msgLoop
()
:
Nothing
=
react
{
case
Ping
(
value
)
=>
{
reply
(
Pong
(
value
))
msgLoop
}
case
AddPong
(
path
)
=>
{
if
(
pongs
.
exists
(
x
=>
x
.
_1
==
path
))
{
sender
!
Ok
}
else
{
try
{
path
.
split
(
":"
)
match
{
case
Array
(
node
,
port
)
=>
{
val
pong
=
select
(
new
Node
(
node
,
port
.
toInt
),
'Pong
)
sender
!
Ok
pongs
=
Pair
(
path
,
pong
)
::
pongs
}
}
}
catch
{
case
e
=>
{
// catches match error, connection error and
// integer conversion failure
reply
(
Error
(
e
.
toString
))
}
}
}
msgLoop
}
case
KickOff
(
value
)
=>
{
val
client
=
sender
pongs
.
foreach
(
x
=>
(
new
PingActor
(
client
,
x
.
_2
)).
start
()
!
KickOff
(
value
))
msgLoop
}
}
override
def
act
()
{
RemoteActor
.
classLoader
=
getClass
().
getClassLoader
alive
(
port
)
register
(
'Pong
,
Actor
.
self
)
msgLoop
}
}
class
ClientActor
extends
Actor
{
private
var
left
:
Int
=
0
private
var
numPings
:
Int
=
0
private
var
pongs
:
List
[
AbstractActor
]
=
Nil
def
collectDoneMessages
()
:
Nothing
=
react
{
case
Done
=>
{
if
(
left
>
1
)
{
left
-=
1
collectDoneMessages
}
}
}
def
collectOkMessages
()
:
Nothing
=
react
{
case
Ok
=>
{
if
(
left
==
1
)
{
pongs
.
foreach
(
x
=>
x
!
KickOff
(
numPings
))
left
=
pongs
.
length
*
(
pongs
.
length
-
1
)
collectDoneMessages
}
else
{
left
-=
1
collectOkMessages
}
}
case
Error
(
what
)
=>
{
println
(
"Error: "
+
what
)
}
}
override
def
act
()
=
{
RemoteActor
.
classLoader
=
getClass
().
getClassLoader
()
react
{
case
RunClient
(
pongPaths
,
numPings
)
=>
{
this
.
numPings
=
numPings
pongs
=
pongPaths
.
map
(
x
=>
{
val
pong
=
select
(
new
Node
(
x
.
host
,
x
.
port
),
'Pong
)
pong
!
AddPong
(
x
.
uri
)
pong
})
left
=
pongs
.
length
*
(
pongs
.
length
-
1
)
collectOkMessages
}
}
}
}
class
PingAkkaActor
(
parent
:
AkkaActorRef
,
pong
:
AkkaActorRef
)
extends
AkkaActor
{
def
receive
=
{
case
Pong
(
0
)
=>
{
//println(parent + " ! Done")
parent
!
Done
context
.
stop
(
self
)
}
...
...
@@ -32,18 +154,16 @@ class PingActor(parent: ActorRef, pong: ActorRef) extends Actor {
sender
!
Ping
(
value
-
1
)
}
case
KickOff
(
value
)
=>
{
//println("PingActor::KickOff " + value)
pong
!
Ping
(
value
)
}
}
}
class
ServerA
ctor
(
system
:
ActorSystem
)
extends
Actor
{
class
ServerA
kkaActor
(
system
:
ActorSystem
)
extends
Akka
Actor
{
var
pongs
=
List
[
ActorRef
]()
var
pendingPongs
=
List
[
Pair
[
ActorRef
,
ActorRef
]]()
import
context.become
def
receive
=
{
def
rec
vLoop
(
pongs
:
List
[
AkkaActorRef
],
pendingPongs
:
List
[
Pair
[
AkkaActorRef
,
AkkaActorRef
]])
:
Rec
eive
=
{
case
Ping
(
value
)
=>
{
sender
!
Pong
(
value
)
}
...
...
@@ -52,8 +172,7 @@ class ServerActor(system: ActorSystem) extends Actor {
case
Some
((
pong
,
ping
))
=>
{
println
(
"added actor "
+
pong
.
path
)
ping
!
Ok
pendingPongs
=
pendingPongs
.
filterNot
(
x
=>
x
.
_1
==
sender
)
pongs
=
pong
::
pongs
become
(
recvLoop
(
pong
::
pongs
,
pendingPongs
.
filterNot
(
x
=>
x
.
_1
==
sender
)))
}
case
None
=>
{
// operation already timed out
...
...
@@ -64,24 +183,25 @@ println("added actor " + pong.path)
pendingPongs
.
find
(
x
=>
x
.
_1
==
sender
)
match
{
case
Some
(
Pair
(
_
,
y
))
=>
{
ping
!
Error
(
pong
+
" did not respond"
)
pendingPongs
=
pendingPongs
.
filterNot
(
x
=>
x
.
_1
==
sender
)
become
(
recvLoop
(
pongs
,
pendingPongs
.
filterNot
(
x
=>
x
.
_1
==
sender
))
)
}
case
None
=>
{
// operation already succeeded
// operation already succeeded
(received Olleh)
}
}
}
case
AddPong
(
path
)
=>
{
if
(
pongs
.
exists
((
x
)
=>
x
.
path
==
path
))
{
sender
!
Ok
}
else
{
}
else
{
import
akka.util.duration._
println
(
"try to add actor "
+
path
)
val
pong
=
system
.
actorFor
(
path
)
// wait at most 5sec. for response
pong
!
Hello
pendingPongs
=
Pair
(
pong
,
sender
)
::
pendingPongs
system
.
scheduler
.
scheduleOnce
(
5
seconds
,
self
,
PongDidNotRespond
(
pong
,
sender
))
become
(
recvLoop
(
pongs
,
Pair
(
pong
,
sender
)
::
pendingPongs
))
//pong ! Hello
//pongs = pong :: pongs
//sender ! Ok
...
...
@@ -90,16 +210,18 @@ println("try to add actor " + path)
case
KickOff
(
value
)
=>
{
val
client
=
sender
//println("KickOff(" + value + ") from " + client)
pongs
.
foreach
((
x
)
=>
context
.
actorOf
(
Props
(
new
PingActor
(
client
,
x
)))
!
KickOff
(
value
))
pongs
.
foreach
((
x
)
=>
context
.
actorOf
(
Props
(
new
PingA
kkaA
ctor
(
client
,
x
)))
!
KickOff
(
value
))
}
case
Hello
=>
{
sender
!
Olleh
}
}
def
receive
=
recvLoop
(
Nil
,
Nil
)
}
class
ClientA
ctor
extends
Actor
{
class
ClientA
kkaActor
extends
Akka
Actor
{
import
context._
...
...
@@ -115,12 +237,12 @@ class ClientActor extends Actor {
left
=
left
-
1
}
}
case
x
=>
{
case
_
=>
{
// ignore any other message
}
}
def
collectOkMessages
(
pongs
:
List
[
ActorRef
],
numPings
:
Int
)
:
Receive
=
{
def
collectOkMessages
(
pongs
:
List
[
A
kkaA
ctorRef
],
numPings
:
Int
)
:
Receive
=
{
case
Ok
=>
{
//println("Ok")
if
(
left
==
1
)
{
...
...
@@ -142,7 +264,7 @@ class ClientActor extends Actor {
}
def
receive
=
{
case
RunClient
(
pongs
,
numPings
)
=>
{
case
Run
Akka
Client
(
pongs
,
numPings
)
=>
{
import
akka.util.duration._
pongs
.
foreach
(
x
=>
pongs
.
foreach
(
y
=>
if
(
x
!=
y
)
{
x
!
AddPong
(
y
.
path
.
toString
)
...
...
@@ -155,45 +277,86 @@ class ClientActor extends Actor {
}
object
DistributedClientApp
{
def
main
(
args
:
Array
[
String
])
:
Unit
=
{
val
system
=
ActorSystem
(
"benchmark"
,
ConfigFactory
.
load
.
getConfig
(
"benchmark"
))
val
NumPings
=
"num_pings=([0-9]+)"
.
r
val
SimpleUri
=
"([0-9a-zA-Z\\.]+):([0-9]+)"
.
r
var
numPings
:
Int
=
0
var
pongs
=
List
[
ActorRef
]()
def
runAkka
(
system
:
ActorSystem
,
args
:
List
[
String
],
pongs
:
List
[
AkkaActorRef
],
numPings
:
Option
[
Int
])
:
Unit
=
args
match
{
case
NumPings
(
num
)
::
tail
=>
numPings
match
{
case
Some
(
x
)
=>
{
println
(
"\"num_pings\" already defined, first value = "
+
x
+
", second value = "
+
num
)
}
case
None
=>
runAkka
(
system
,
tail
,
pongs
,
Some
(
num
.
toInt
))
}
case
path
::
tail
=>
{
runAkka
(
system
,
tail
,
system
.
actorFor
(
path
)
::
pongs
,
numPings
)
}
case
Nil
=>
numPings
match
{
case
Some
(
x
)
=>
{
if
(
pongs
isEmpty
)
throw
new
RuntimeException
(
"No pong no fun"
)
system
.
actorOf
(
Props
[
ClientAkkaActor
])
!
RunAkkaClient
(
pongs
,
x
)
global
.
latch
.
await
system
.
shutdown
System
.
exit
(
0
)
}
case
None
=>
{
throw
new
RuntimeException
(
"no \"num_pings\" found"
)
}
}
}
val
NumPings
=
"num_pings=([0-9]+)"
.
r
args
.
foreach
(
arg
=>
arg
match
{
case
NumPings
(
num
)
=>
{
numPings
=
num
.
toInt
def
runRemoteActors
(
args
:
List
[
String
],
pongs
:
List
[
RemoteActorPath
],
numPings
:
Option
[
Int
])
:
Unit
=
args
match
{
case
NumPings
(
num
)
::
tail
=>
numPings
match
{
case
Some
(
x
)
=>
{
println
(
"\"num_pings\" already defined, first value = "
+
x
+
", second value = "
+
num
)
}
case
None
=>
runRemoteActors
(
tail
,
pongs
,
Some
(
num
.
toInt
))
}
case
arg
::
tail
=>
arg
match
{
case
SimpleUri
(
host
,
port
)
=>
{
runRemoteActors
(
tail
,
RemoteActorPath
(
arg
,
host
,
port
.
toInt
)
::
pongs
,
numPings
)
}
case
_
=>
{
//println("add actor " + arg)
pongs
=
system
.
actorFor
(
arg
)
::
pongs
throw
new
IllegalArgumentException
(
"illegal argument: "
+
arg
)
}
})
system
.
actorOf
(
Props
[
ClientActor
])
!
RunClient
(
pongs
,
numPings
)
}
case
Nil
=>
numPings
match
{
case
Some
(
x
)
=>
{
(
new
ClientActor
).
start
!
RunClient
(
pongs
,
x
)
}
case
None
=>
{
throw
new
RuntimeException
(
"no \"num_pings\" found"
)
}
}
}
global
.
latch
.
await
system
.
shutdown
System
.
exit
(
0
)
def
main
(
args
:
Array
[
String
])
:
Unit
=
args
.
toList
match
{
case
"akka"
::
akkaArgs
=>
{
val
system
=
ActorSystem
(
"benchmark"
,
ConfigFactory
.
load
.
getConfig
(
"benchmark"
))
runAkka
(
system
,
akkaArgs
,
Nil
,
None
)
}
case
"remote_actors"
::
tail
=>
{
runRemoteActors
(
tail
,
Nil
,
None
)
}
case
Nil
=>
{
println
(
"usage: ..."
)
}
}
}
object
DistributedServerApp
{
def
main
(
args
:
Array
[
String
])
:
Unit
=
{
val
sysName
=
if
(
args
.
length
>
0
)
args
(
0
)
else
"pongServer"
val
system
=
ActorSystem
(
sysName
,
ConfigFactory
.
load
.
getConfig
(
"pongServer"
))
val
pong
=
system
.
actorOf
(
Props
(
new
ServerActor
(
system
)),
"pong"
)
//val subSystem = ActorSystem(sysName + "Client", ConfigFactory.load.getConfig("benchmark"))
//val pong = system.actorOf(Props(new ServerActor(subSystem)), "pong")
def
usage
=
println
(
"usage: (akka [configName]) | (remote_actors {port})"
)
def
main
(
args
:
Array
[
String
])
:
Unit
=
args
.
toList
match
{
case
"akka"
::
tail
if
tail
.
length
<
2
=>
{
val
system
=
ActorSystem
(
if
(
tail
.
isEmpty
)
"pongServer"
else
tail
.
head
,
ConfigFactory
.
load
.
getConfig
(
"pongServer"
))
val
pong
=
system
.
actorOf
(
Props
(
new
ServerAkkaActor
(
system
)),
"pong"
)
}
case
"remote_actors"
::
port
::
Nil
=>
{
(
new
ServerActor
(
port
.
toInt
)).
start
}
case
_
=>
usage
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment