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
904b5b3c
Commit
904b5b3c
authored
Sep 27, 2013
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved broker impl and example
parent
076d830d
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
100 additions
and
61 deletions
+100
-61
cppa/cppa.hpp
cppa/cppa.hpp
+4
-2
cppa/io/broker.hpp
cppa/io/broker.hpp
+7
-5
examples/remote_actors/protobuf_broker.cpp
examples/remote_actors/protobuf_broker.cpp
+56
-40
src/broker.cpp
src/broker.cpp
+26
-8
unit_testing/test_broker.cpp
unit_testing/test_broker.cpp
+7
-6
No files found.
cppa/cppa.hpp
View file @
904b5b3c
...
...
@@ -565,17 +565,19 @@ actor_ptr spawn_io(F fun,
return
eval_sopts
(
Options
,
io
::
init_and_launch
(
move
(
ptr
)));
}
/*
template<class Impl, spawn_options Options = no_spawn_options, typename... Ts>
actor_ptr spawn_io(const char* host, uint16_t port, Ts&&... args) {
auto ptr = io::ipv4_io_stream::connect_to(host, port);
return spawn_io<Impl>(ptr, ptr, std::forward<Ts>(args)...);
}
*/
template
<
spawn_options
Options
=
no_spawn_options
,
typename
F
=
std
::
function
<
void
(
io
::
broker
*
)>,
typename
...
Ts
>
actor_ptr
spawn_io
(
F
fun
,
const
char
*
host
,
uint16_t
port
,
Ts
&&
...
args
)
{
auto
ptr
=
io
::
ipv4_io_stream
::
connect_to
(
host
,
port
);
actor_ptr
spawn_io
(
F
fun
,
const
std
::
string
&
host
,
uint16_t
port
,
Ts
&&
...
args
)
{
auto
ptr
=
io
::
ipv4_io_stream
::
connect_to
(
host
.
c_str
()
,
port
);
return
spawn_io
(
std
::
move
(
fun
),
ptr
,
ptr
,
std
::
forward
<
Ts
>
(
args
)...);
}
...
...
cppa/io/broker.hpp
View file @
904b5b3c
...
...
@@ -87,7 +87,7 @@ class broker : public extend<local_actor>::with<threadless, stackless> {
bool
initialized
()
const
;
void
quit
(
std
::
uint32_t
reason
)
;
void
quit
(
std
::
uint32_t
reason
=
exit_reason
::
normal
)
override
;
void
receive_policy
(
const
connection_handle
&
hdl
,
broker
::
policy_flag
policy
,
...
...
@@ -99,7 +99,7 @@ class broker : public extend<local_actor>::with<threadless, stackless> {
void
write
(
const
connection_handle
&
hdl
,
util
::
buffer
&&
buf
);
static
broker_ptr
from
(
std
::
function
<
void
(
broker
*
)
>
fun
,
static
broker_ptr
from
(
std
::
function
<
void
(
broker
*
,
connection_handle
)
>
fun
,
input_stream_ptr
in
,
output_stream_ptr
out
);
...
...
@@ -108,6 +108,7 @@ class broker : public extend<local_actor>::with<threadless, stackless> {
T0
&&
arg0
,
Ts
&&
...
args
)
{
return
from
(
std
::
bind
(
std
::
move
(
fun
),
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
,
detail
::
fwd
<
T0
>
(
arg0
),
detail
::
fwd
<
Ts
>
(
args
)...),
std
::
move
(
in
),
...
...
@@ -125,16 +126,17 @@ class broker : public extend<local_actor>::with<threadless, stackless> {
std
::
move
(
in
));
}
actor_ptr
fork
(
std
::
function
<
void
(
broker
*
)
>
fun
,
con
st
connection_handle
&
hdl
);
actor_ptr
fork
(
std
::
function
<
void
(
broker
*
,
connection_handle
)
>
fun
,
con
nection_handle
hdl
);
template
<
typename
F
,
typename
T0
,
typename
...
Ts
>
actor_ptr
fork
(
F
fun
,
con
st
connection_handle
&
hdl
,
con
nection_handle
hdl
,
T0
&&
arg0
,
Ts
&&
...
args
)
{
return
this
->
fork
(
std
::
bind
(
std
::
move
(
fun
),
std
::
placeholders
::
_1
,
std
::
placeholders
::
_2
,
detail
::
fwd
<
T0
>
(
arg0
),
detail
::
fwd
<
Ts
>
(
args
)...),
hdl
);
...
...
examples/remote_actors/protobuf_broker.cpp
View file @
904b5b3c
...
...
@@ -49,6 +49,12 @@ using namespace std;
using
namespace
cppa
;
using
namespace
cppa
::
io
;
void
print_on_exit
(
const
actor_ptr
&
ptr
,
const
std
::
string
&
name
)
{
ptr
->
attach_functor
([
=
](
std
::
uint32_t
reason
)
{
aout
<<
name
<<
" exited with reason "
<<
reason
<<
endl
;
});
}
void
ping
(
size_t
num_pings
)
{
auto
count
=
make_shared
<
size_t
>
(
0
);
become
(
...
...
@@ -56,7 +62,7 @@ void ping(size_t num_pings) {
send
(
pong
,
atom
(
"ping"
),
1
);
become
(
on
(
atom
(
"pong"
),
arg_match
)
>>
[
=
](
int
value
)
{
cout
<<
"<- pong
"
<<
value
<<
endl
;
aout
<<
"pong:
"
<<
value
<<
endl
;
if
(
++*
count
>=
num_pings
)
self
->
quit
();
else
reply
(
atom
(
"ping"
),
value
+
1
);
}
...
...
@@ -68,23 +74,24 @@ void ping(size_t num_pings) {
void
pong
()
{
become
(
on
(
atom
(
"ping"
),
arg_match
)
>>
[](
int
value
)
{
cout
<<
"<- ping
"
<<
value
<<
endl
;
aout
<<
"ping:
"
<<
value
<<
endl
;
reply
(
atom
(
"pong"
),
value
);
}
);
}
void
protobuf_io
(
broker
*
ios
,
const
actor_ptr
&
buddy
)
{
void
protobuf_io
(
broker
*
thisptr
,
connection_handle
hdl
,
const
actor_ptr
&
buddy
)
{
self
->
monitor
(
buddy
);
auto
write
=
[
=
](
const
org
::
libcppa
::
PingOrPong
&
p
)
{
string
buf
=
p
.
SerializeAsString
();
int32_t
s
=
htonl
(
static_cast
<
int32_t
>
(
buf
.
size
()));
ios
->
write
(
sizeof
(
int32_t
),
&
s
);
ios
->
write
(
buf
.
size
(),
buf
.
data
());
thisptr
->
write
(
hdl
,
sizeof
(
int32_t
),
&
s
);
thisptr
->
write
(
hdl
,
buf
.
size
(),
buf
.
data
());
};
auto
default_bhvr
=
(
on
(
atom
(
"IO_closed"
),
arg_match
)
>>
[
=
](
uint32_t
)
{
on
(
atom
(
"IO_closed"
),
hdl
)
>>
[
=
]
{
cout
<<
"IO_closed"
<<
endl
;
send_exit
(
buddy
,
exit_reason
::
remote_link_unreachable
);
self
->
quit
(
exit_reason
::
remote_link_unreachable
);
},
on
(
atom
(
"ping"
),
arg_match
)
>>
[
=
](
int
i
)
{
...
...
@@ -105,12 +112,9 @@ void protobuf_io(broker* ios, const actor_ptr& buddy) {
}
);
partial_function
await_protobuf_data
{
on
(
atom
(
"IO_read"
),
arg_match
)
>>
[
=
](
uint32_t
,
const
util
::
buffer
&
buf
)
{
on
(
atom
(
"IO_read"
),
hdl
,
arg_match
)
>>
[
=
](
const
util
::
buffer
&
buf
)
{
org
::
libcppa
::
PingOrPong
p
;
p
.
ParseFromArray
(
buf
.
data
(),
static_cast
<
int
>
(
buf
.
size
()));
auto
print
=
[](
const
char
*
name
,
int
value
)
{
cout
<<
name
<<
"{"
<<
value
<<
"}"
<<
endl
;
};
if
(
p
.
has_ping
())
{
send
(
buddy
,
atom
(
"ping"
),
p
.
ping
().
id
());
}
...
...
@@ -119,62 +123,74 @@ void protobuf_io(broker* ios, const actor_ptr& buddy) {
}
else
{
self
->
quit
(
exit_reason
::
user_defined
);
cerr
<<
"neither P
ong nor Pi
ng!"
<<
endl
;
cerr
<<
"neither P
ing nor Po
ng!"
<<
endl
;
}
// receive next length prefix
ios
->
receive_policy
(
broker
::
exactly
,
4
);
thisptr
->
receive_policy
(
hdl
,
broker
::
exactly
,
4
);
unbecome
();
},
default_bhvr
};
partial_function
await_length_prefix
{
on
(
atom
(
"IO_read"
),
arg_match
)
>>
[
=
](
uint32_t
,
const
util
::
buffer
&
buf
)
{
int
num_bytes
;
on
(
atom
(
"IO_read"
),
hdl
,
arg_match
)
>>
[
=
](
const
util
::
buffer
&
buf
)
{
int
32_t
num_bytes
;
memcpy
(
&
num_bytes
,
buf
.
data
(),
4
);
num_bytes
=
htonl
(
num_bytes
);
if
(
num_bytes
<
0
||
num_bytes
>
(
1024
*
1024
))
{
aout
<<
"someone is trying something nasty"
<<
endl
;
self
->
quit
(
exit_reason
::
user_defined
);
return
;
}
// receive protobuf data
ios
->
receive_policy
(
broker
::
exactly
,
(
size_t
)
num_bytes
);
thisptr
->
receive_policy
(
hdl
,
broker
::
exactly
,
static_cast
<
size_t
>
(
num_bytes
)
);
become
(
keep_behavior
,
await_protobuf_data
);
},
default_bhvr
};
// initial setup
ios
->
receive_policy
(
broker
::
exactly
,
4
);
thisptr
->
receive_policy
(
hdl
,
broker
::
exactly
,
4
);
become
(
await_length_prefix
);
}
void
server
(
broker
*
thisptr
,
actor_ptr
buddy
)
{
aout
<<
"server is running"
<<
endl
;
become
(
on
(
atom
(
"IO_accept"
),
arg_match
)
>>
[
=
](
accept_handle
,
connection_handle
hdl
)
{
aout
<<
"server: IO_accept"
<<
endl
;
auto
io_actor
=
thisptr
->
fork
(
protobuf_io
,
hdl
,
buddy
);
print_on_exit
(
io_actor
,
"protobuf_io"
);
// only accept 1 connection
thisptr
->
quit
();
},
others
()
>>
[
=
]
{
cout
<<
"unexpected: "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
}
);
}
optional
<
uint16_t
>
as_u16
(
const
std
::
string
&
str
)
{
return
static_cast
<
uint16_t
>
(
stoul
(
str
));
}
int
main
(
int
argc
,
char
**
argv
)
{
auto
print_exit
=
[](
const
actor_ptr
&
ptr
,
const
std
::
string
&
name
)
{
ptr
->
attach_functor
([
=
](
std
::
uint32_t
reason
)
{
cout
<<
name
<<
" exited with reason "
<<
reason
<<
endl
;
});
};
match
(
std
::
vector
<
string
>
{
argv
+
1
,
argv
+
argc
})
(
on
(
"-s"
)
>>
[
&
]
{
on
(
"-s"
,
as_u16
)
>>
[
&
](
uint16_t
port
)
{
cout
<<
"run in server mode"
<<
endl
;
std
::
string
hi
=
"hello"
;
auto
po
=
spawn
(
pong
);
auto
ack
=
io
::
ipv4_acceptor
::
create
(
4242
);
for
(;;)
{
auto
p
=
ack
->
accept_connection
();
//spawn_io<protobuf_io>(p.first, p.second);
auto
s
=
spawn_io
(
protobuf_io
,
std
::
move
(
p
.
first
),
std
::
move
(
p
.
second
),
po
);
print_exit
(
s
,
"io actor"
);
print_exit
(
po
,
"pong"
);
}
auto
pong_actor
=
spawn
(
pong
);
auto
sever_actor
=
spawn_io_server
(
server
,
port
,
pong_actor
);
print_on_exit
(
sever_actor
,
"server"
);
print_on_exit
(
pong_actor
,
"pong"
);
},
on
(
"-c"
,
val
<
string
>
,
as_u16
)
>>
[
&
](
const
string
&
host
,
uint16_t
port
)
{
auto
ping_actor
=
spawn
(
ping
,
20
);
auto
io_actor
=
spawn_io
(
protobuf_io
,
host
,
port
,
ping_actor
);
print_on_exit
(
io_actor
,
"protobuf_io"
);
print_on_exit
(
ping_actor
,
"ping"
);
send_as
(
io_actor
,
ping_actor
,
atom
(
"kickoff"
),
io_actor
);
},
on_arg_match
>>
[
&
](
const
string
&
host
,
const
string
&
port_str
)
{
auto
port
=
static_cast
<
uint16_t
>
(
stoul
(
port_str
));
auto
io
=
io
::
ipv4_io_stream
::
connect_to
(
host
.
c_str
(),
port
);
auto
pi
=
spawn
(
ping
,
20
);
auto
pr
=
spawn_io
(
protobuf_io
,
io
,
io
,
pi
);
send_as
(
pr
,
pi
,
atom
(
"kickoff"
),
pr
);
print_exit
(
pr
,
"io actor"
);
print_exit
(
pi
,
"ping"
);
others
()
>>
[]
{
cerr
<<
"use with eihter '-s PORT' as server or '-c HOST PORT' as client"
<<
endl
;
}
);
await_all_others_done
();
...
...
src/broker.cpp
View file @
904b5b3c
...
...
@@ -63,11 +63,21 @@ class default_broker : public broker {
typedef
std
::
function
<
void
(
broker
*
)
>
function_type
;
struct
fork_flag
{
};
template
<
typename
...
Ts
>
default_broker
(
function_type
&&
fun
,
Ts
&&
...
args
)
default_broker
(
function_type
&&
fun
,
Ts
&&
...
args
)
:
broker
{
std
::
forward
<
Ts
>
(
args
)...},
m_fun
{
move
(
fun
)}
{
}
template
<
typename
...
Ts
>
default_broker
(
fork_flag
,
std
::
function
<
void
(
broker
*
,
connection_handle
)
>&&
fun
,
connection_handle
hdl
,
Ts
&&
...
args
)
:
broker
{
std
::
forward
<
Ts
>
(
args
)...}
,
m_fun
{
std
::
bind
(
move
(
fun
),
std
::
placeholders
::
_1
,
hdl
)}
{
}
void
init
()
override
{
enqueue
(
nullptr
,
make_any_tuple
(
atom
(
"INITMSG"
)));
become
(
...
...
@@ -249,13 +259,13 @@ class broker::doorman : public broker::servant {
doorman
(
broker_ptr
parent
,
acceptor_uptr
ptr
)
:
super
{
move
(
parent
),
ptr
->
file_handle
()}
//, m_ptr{move(ptr)}
,
m_accept_msg
{
atom
(
"IO_accept"
),
accept_handle
::
from_int
(
ptr
->
file_handle
())}
{
m_ptr
.
reset
(
ptr
.
release
());
}
continue_reading_result
continue_reading
()
override
{
CPPA_REQUIRE
(
parent
()
!=
nullptr
);
CPPA_LOG_TRACE
(
""
);
for
(;;)
{
optional
<
stream_ptr_pair
>
opt
{
none
};
...
...
@@ -427,10 +437,15 @@ local_actor_ptr init_and_launch(broker_ptr ptr) {
return
move
(
ptr
);
}
broker_ptr
broker
::
from
(
std
::
function
<
void
(
broker
*
)
>
fun
,
broker_ptr
broker
::
from
(
std
::
function
<
void
(
broker
*
,
connection_handle
)
>
fun
,
input_stream_ptr
in
,
output_stream_ptr
out
)
{
return
make_counted
<
default_broker
>
(
move
(
fun
),
move
(
in
),
move
(
out
));
auto
hdl
=
connection_handle
::
from_int
(
in
->
read_handle
());
return
make_counted
<
default_broker
>
(
std
::
bind
(
move
(
fun
),
std
::
placeholders
::
_1
,
hdl
),
move
(
in
),
move
(
out
));
}
broker_ptr
broker
::
from
(
std
::
function
<
void
(
broker
*
)
>
fun
,
acceptor_uptr
in
)
{
...
...
@@ -460,12 +475,15 @@ accept_handle broker::add_doorman(acceptor_uptr ptr) {
return
id
;
}
actor_ptr
broker
::
fork
(
std
::
function
<
void
(
broker
*
)
>
fun
,
con
st
connection_handle
&
hdl
)
{
actor_ptr
broker
::
fork
(
std
::
function
<
void
(
broker
*
,
connection_handle
)
>
fun
,
con
nection_handle
hdl
)
{
auto
i
=
m_io
.
find
(
hdl
);
if
(
i
==
m_io
.
end
())
throw
std
::
invalid_argument
(
"invalid handle"
);
scribe
*
sptr
=
i
->
second
.
get
();
// non-owning pointer
auto
result
=
make_counted
<
default_broker
>
(
move
(
fun
),
move
(
i
->
second
));
auto
result
=
make_counted
<
default_broker
>
(
default_broker
::
fork_flag
{},
move
(
fun
),
hdl
,
move
(
i
->
second
));
init_and_launch
(
result
);
sptr
->
set_parent
(
result
);
// set new parent
m_io
.
erase
(
i
);
...
...
unit_testing/test_broker.cpp
View file @
904b5b3c
...
...
@@ -80,20 +80,20 @@ void pong() {
);
}
void
peer
(
io
::
broker
*
thisptr
,
const
actor_ptr
&
buddy
)
{
void
peer
(
io
::
broker
*
thisptr
,
io
::
connection_handle
hdl
,
const
actor_ptr
&
buddy
)
{
self
->
monitor
(
buddy
);
if
(
thisptr
->
num_connections
()
==
0
)
{
cout
<<
"num_connections() != 1"
<<
endl
;
throw
std
::
logic_error
(
"num_connections() != 1"
);
}
thisptr
->
for_each_connection
([
=
](
io
::
connection_handle
hdl
)
{
thisptr
->
receive_policy
(
hdl
,
io
::
broker
::
exactly
,
message_size
);
});
//
thisptr->for_each_connection([=](io::connection_handle hdl) {
//
thisptr->receive_policy(hdl, io::broker::exactly, message_size);
//
});
auto
write
=
[
=
](
atom_value
type
,
int
value
)
{
thisptr
->
for_each_connection
([
=
](
io
::
connection_handle
hdl
)
{
//
thisptr->for_each_connection([=](io::connection_handle hdl) {
thisptr
->
write
(
hdl
,
sizeof
(
type
),
&
type
);
thisptr
->
write
(
hdl
,
sizeof
(
value
),
&
value
);
});
//
});
};
become
(
on
(
atom
(
"IO_closed"
),
arg_match
)
>>
[
=
](
io
::
connection_handle
)
{
...
...
@@ -122,6 +122,7 @@ void peer(io::broker* thisptr, const actor_ptr& buddy) {
void
peer_acceptor
(
io
::
broker
*
thisptr
,
const
actor_ptr
&
buddy
)
{
become
(
on
(
atom
(
"IO_accept"
),
arg_match
)
>>
[
=
](
io
::
accept_handle
,
io
::
connection_handle
hdl
)
{
CPPA_CHECKPOINT
();
CPPA_LOGF_INFO
(
"received IO_accept"
);
thisptr
->
fork
(
peer
,
hdl
,
buddy
);
self
->
quit
();
...
...
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