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
22b1bc45
Commit
22b1bc45
authored
Jul 09, 2016
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Streamline API for remote spawning
parent
80c56b4f
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
116 additions
and
84 deletions
+116
-84
examples/remoting/remote_spawn.cpp
examples/remoting/remote_spawn.cpp
+8
-9
libcaf_core/caf/actor_system.hpp
libcaf_core/caf/actor_system.hpp
+30
-0
libcaf_core/caf/function_view.hpp
libcaf_core/caf/function_view.hpp
+2
-2
libcaf_core/caf/infer_handle.hpp
libcaf_core/caf/infer_handle.hpp
+12
-0
libcaf_core/caf/none.hpp
libcaf_core/caf/none.hpp
+1
-1
libcaf_core/caf/optional.hpp
libcaf_core/caf/optional.hpp
+4
-0
libcaf_core/caf/uniform_type_info_map.hpp
libcaf_core/caf/uniform_type_info_map.hpp
+0
-6
libcaf_core/src/actor_system.cpp
libcaf_core/src/actor_system.cpp
+33
-10
libcaf_core/src/uniform_type_info_map.cpp
libcaf_core/src/uniform_type_info_map.cpp
+0
-21
libcaf_core/test/actor_factory.cpp
libcaf_core/test/actor_factory.cpp
+4
-6
libcaf_io/caf/io/middleman.hpp
libcaf_io/caf/io/middleman.hpp
+7
-12
libcaf_io/caf/io/middleman_actor.hpp
libcaf_io/caf/io/middleman_actor.hpp
+2
-2
libcaf_io/src/middleman.cpp
libcaf_io/src/middleman.cpp
+8
-11
libcaf_io/src/middleman_actor.cpp
libcaf_io/src/middleman_actor.cpp
+5
-4
No files found.
examples/remoting/remote_spawn.cpp
View file @
22b1bc45
...
...
@@ -7,7 +7,8 @@
// Run client at the same host:
// - remote_spawn -n localhost -p 4242
// Manual refs: 250-262 ()
// Manual refs: 137-139, 144, 148 (ConfiguringActorApplications)
// 101-119 (RemoteSpawn)
#include <array>
#include <vector>
...
...
@@ -36,7 +37,6 @@ using calculator = typed_actor<replies_to<add_atom, int, int>::with<int>,
replies_to
<
sub_atom
,
int
,
int
>::
with
<
int
>>
;
// function-based, statically typed, event-based API
calculator
::
behavior_type
calculator_fun
(
calculator
::
pointer
self
)
{
return
{
[
=
](
add_atom
,
int
a
,
int
b
)
->
int
{
...
...
@@ -108,7 +108,8 @@ void client(actor_system& system, const std::string& host, uint16_t port) {
auto
type
=
"calculator"
;
// type of the actor we wish to spawn
auto
args
=
make_message
();
// arguments to construct the actor
auto
tout
=
std
::
chrono
::
seconds
(
30
);
// wait no longer than 30s
auto
worker
=
system
.
middleman
().
remote_spawn
<
calculator
>
(
*
node
,
type
,
args
,
tout
);
auto
worker
=
system
.
middleman
().
remote_spawn
<
calculator
>
(
*
node
,
type
,
args
,
tout
);
if
(
!
worker
)
{
std
::
cerr
<<
"*** remote spawn failed: "
<<
system
.
render
(
worker
.
error
())
<<
std
::
endl
;
...
...
@@ -130,15 +131,10 @@ void server(actor_system& system, uint16_t port) {
std
::
cout
<<
"*** running on port: "
<<
*
res
<<
std
::
endl
<<
"*** press <enter> to shutdown server"
<<
std
::
endl
;
int
dummy
;
std
::
cin
>>
dummy
;
getchar
();
}
struct
config
:
actor_system_config
{
uint16_t
port
=
0
;
std
::
string
host
=
"localhost"
;
bool
server_mode
=
false
;
config
()
{
add_actor_type
(
"calculator"
,
calculator_fun
);
opt_group
{
custom_options_
,
"global"
}
...
...
@@ -146,6 +142,9 @@ struct config : actor_system_config {
.
add
(
host
,
"host,H"
,
"set node (ignored in server mode)"
)
.
add
(
server_mode
,
"server-mode,s"
,
"enable server mode"
);
}
uint16_t
port
=
0
;
std
::
string
host
=
"localhost"
;
bool
server_mode
=
false
;
};
void
caf_main
(
actor_system
&
system
,
const
config
&
cfg
)
{
...
...
libcaf_core/caf/actor_system.hpp
View file @
22b1bc45
...
...
@@ -179,6 +179,10 @@ public:
return
mpi
{};
}
inline
mpi
message_types
(
detail
::
type_list
<
strong_actor_ptr
>
)
const
{
return
mpi
{};
}
template
<
class
...
Ts
>
mpi
message_types
(
detail
::
type_list
<
typed_actor
<
Ts
...
>>
)
const
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"empty typed actor handle given"
);
...
...
@@ -336,6 +340,26 @@ public:
return
spawn_functor
<
Os
>
(
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
/// Returns a new actor with run-time type `name`, constructed
/// with the arguments stored in `args`.
/// @experimental
template
<
class
Handle
,
class
E
=
typename
std
::
enable_if
<
is_handle
<
Handle
>
::
value
>::
type
>
expected
<
Handle
>
spawn
(
const
std
::
string
&
name
,
message
args
,
execution_unit
*
ctx
=
nullptr
,
bool
check_interface
=
true
,
const
mpi
*
expected_ifs
=
nullptr
)
{
mpi
tmp
;
if
(
check_interface
&&
!
expected_ifs
)
{
tmp
=
message_types
<
Handle
>
();
expected_ifs
=
&
tmp
;
}
auto
res
=
dyn_spawn_impl
(
name
,
args
,
ctx
,
check_interface
,
expected_ifs
);
if
(
!
res
)
return
std
::
move
(
res
.
error
());
return
actor_cast
<
Handle
>
(
std
::
move
(
*
res
));
}
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
Iter
,
class
F
,
class
...
Ts
>
infer_handle_from_class_t
<
T
>
...
...
@@ -445,6 +469,12 @@ private:
"Probably you have tried to spawn a broker or opencl actor."
);
}
expected
<
strong_actor_ptr
>
dyn_spawn_impl
(
const
std
::
string
&
name
,
message
&
args
,
execution_unit
*
ctx
,
bool
check_interface
,
optional
<
const
mpi
&>
expected_ifs
);
template
<
class
C
,
spawn_options
Os
,
class
...
Ts
>
infer_handle_from_class_t
<
C
>
spawn_impl
(
actor_config
&
cfg
,
Ts
&&
...
xs
)
{
...
...
libcaf_core/caf/function_view.hpp
View file @
22b1bc45
...
...
@@ -259,8 +259,8 @@ bool operator!=(std::nullptr_t x, const function_view<T>& y) {
/// @relates function_view
/// @experimental
template
<
class
T
>
function_view
<
T
>
make_function_view
(
const
T
&
x
)
{
return
{
x
};
function_view
<
T
>
make_function_view
(
const
T
&
x
,
duration
t
=
infinite
)
{
return
{
x
,
t
};
}
}
// namespace caf
...
...
libcaf_core/caf/infer_handle.hpp
View file @
22b1bc45
...
...
@@ -209,6 +209,18 @@ struct infer_handle_from_state<T, false> {
template
<
class
T
>
using
infer_handle_from_state_t
=
typename
infer_handle_from_state
<
T
>::
type
;
template
<
class
T
>
struct
is_handle
:
std
::
false_type
{};
template
<
>
struct
is_handle
<
actor
>
:
std
::
true_type
{};
template
<
>
struct
is_handle
<
strong_actor_ptr
>
:
std
::
true_type
{};
template
<
class
...
Ts
>
struct
is_handle
<
typed_actor
<
Ts
...
>>
:
std
::
true_type
{};
}
// namespace caf
#endif // CAF_INFER_HANDLE_HPP
libcaf_core/caf/none.hpp
View file @
22b1bc45
...
...
@@ -44,7 +44,7 @@ static constexpr none_t none = none_t{};
/// @relates none_t
inline
std
::
string
to_string
(
const
none_t
&
)
{
return
"
<none>
"
;
return
"
none
"
;
}
}
// namespace caf
...
...
libcaf_core/caf/optional.hpp
View file @
22b1bc45
...
...
@@ -176,6 +176,10 @@ class optional<T&> {
// nop
}
optional
(
T
*
x
)
:
m_value
(
x
)
{
// nop
}
optional
(
const
optional
&
other
)
=
default
;
optional
&
operator
=
(
const
optional
&
other
)
=
default
;
...
...
libcaf_core/caf/uniform_type_info_map.hpp
View file @
22b1bc45
...
...
@@ -75,10 +75,6 @@ public:
type_erased_value_ptr
make_value
(
const
std
::
type_info
&
ti
)
const
;
actor_factory_result
make_actor
(
const
std
::
string
&
name
,
actor_config
&
cfg
,
message
&
msg
)
const
;
/// Returns the portable name for given type information or `nullptr`
/// if no mapping was found.
const
std
::
string
*
portable_name
(
uint16_t
nr
,
const
std
::
type_info
*
ti
)
const
;
...
...
@@ -90,8 +86,6 @@ public:
return
portable_name
(
x
.
first
,
x
.
second
);
}
error_renderer
renderer
(
atom_value
x
)
const
;
/// Returns the enclosing actor system.
inline
actor_system
&
system
()
const
{
return
system_
;
...
...
libcaf_core/src/actor_system.cpp
View file @
22b1bc45
...
...
@@ -147,15 +147,12 @@ behavior config_serv_impl(stateful_actor<kvstate>* self) {
behavior
spawn_serv_impl
(
event_based_actor
*
self
)
{
CAF_LOG_TRACE
(
""
);
return
{
[
=
](
spawn_atom
,
const
std
::
string
&
name
,
message
&
args
)
->
result
<
strong_actor_ptr
,
std
::
set
<
std
::
string
>>
{
[
=
](
spawn_atom
,
const
std
::
string
&
name
,
message
&
args
,
actor_system
::
mpi
&
xs
)
->
expected
<
strong_actor_ptr
>
{
CAF_LOG_TRACE
(
CAF_ARG
(
name
)
<<
CAF_ARG
(
args
));
printf
(
"%s %d -- %s
\n
"
,
__FILE__
,
__LINE__
,
to_string
(
self
->
current_mailbox_element
()
->
content
()).
c_str
());
actor_config
cfg
{
self
->
context
()};
auto
res
=
self
->
system
().
types
().
make_actor
(
name
,
cfg
,
args
);
if
(
!
res
.
first
)
return
sec
::
cannot_spawn_actor_from_arguments
;
return
{
res
.
first
,
res
.
second
};
return
self
->
system
().
spawn
<
strong_actor_ptr
>
(
name
,
std
::
move
(
args
),
self
->
context
(),
true
,
&
xs
);
}
};
}
...
...
@@ -307,8 +304,13 @@ const uniform_type_info_map& actor_system::types() const {
}
std
::
string
actor_system
::
render
(
const
error
&
x
)
const
{
auto
f
=
types
().
renderer
(
x
.
category
());
return
f
?
f
(
x
.
code
(),
x
.
category
(),
x
.
context
())
:
to_string
(
x
);
if
(
!
x
)
return
to_string
(
x
);
auto
&
xs
=
config
().
error_renderers
;
auto
i
=
xs
.
find
(
x
.
category
());
if
(
i
!=
xs
.
end
())
return
i
->
second
(
x
.
code
(),
x
.
category
(),
x
.
context
());
return
to_string
(
x
);
}
group_manager
&
actor_system
::
groups
()
{
...
...
@@ -368,4 +370,25 @@ void actor_system::await_detached_threads() {
detached_cv
.
wait
(
guard
);
}
expected
<
strong_actor_ptr
>
actor_system
::
dyn_spawn_impl
(
const
std
::
string
&
name
,
message
&
args
,
execution_unit
*
ctx
,
bool
check_interface
,
optional
<
const
mpi
&>
expected_ifs
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
name
)
<<
CAF_ARG
(
args
)
<<
CAF_ARG
(
check_interface
)
<<
CAF_ARG
(
expected_ifs
));
if
(
name
.
empty
())
return
sec
::
invalid_argument
;
auto
&
fs
=
cfg_
.
actor_factories
;
auto
i
=
fs
.
find
(
name
);
if
(
i
==
fs
.
end
())
return
sec
::
unknown_type
;
actor_config
cfg
{
ctx
?
ctx
:
&
dummy_execution_unit_
};
auto
res
=
i
->
second
(
cfg
,
args
);
if
(
!
res
.
first
)
return
sec
::
cannot_spawn_actor_from_arguments
;
if
(
check_interface
&&
!
assignable
(
res
.
second
,
*
expected_ifs
))
return
sec
::
unexpected_actor_messaging_interface
;
return
std
::
move
(
res
.
first
);
}
}
// namespace caf
libcaf_core/src/uniform_type_info_map.cpp
View file @
22b1bc45
...
...
@@ -154,27 +154,6 @@ uniform_type_info_map::portable_name(uint16_t nr,
return
nullptr
;
}
uniform_type_info_map
::
error_renderer
uniform_type_info_map
::
renderer
(
atom_value
x
)
const
{
auto
&
error_renderers
=
system
().
config
().
error_renderers
;
auto
i
=
error_renderers
.
find
(
x
);
if
(
i
!=
error_renderers
.
end
())
return
i
->
second
;
return
nullptr
;
}
actor_factory_result
uniform_type_info_map
::
make_actor
(
const
std
::
string
&
name
,
actor_config
&
cfg
,
message
&
msg
)
const
{
strong_actor_ptr
res
;
std
::
set
<
std
::
string
>
ifs
;
auto
&
factories
=
system
().
config
().
actor_factories
;
auto
i
=
factories
.
find
(
name
);
if
(
i
!=
factories
.
end
())
std
::
tie
(
res
,
ifs
)
=
i
->
second
(
cfg
,
msg
);
return
std
::
make_pair
(
std
::
move
(
res
),
std
::
move
(
ifs
));
}
uniform_type_info_map
::
uniform_type_info_map
(
actor_system
&
sys
)
:
system_
(
sys
)
{
sorted_builtin_types
list
;
fill_builtins
(
builtin_
,
list
,
0
);
...
...
libcaf_core/test/actor_factory.cpp
View file @
22b1bc45
...
...
@@ -45,15 +45,13 @@ struct fixture {
std
::
set
<
std
::
string
>
ifs
;
scoped_execution_unit
context
{
&
system
};
actor_config
actor_cfg
{
&
context
};
std
::
tie
(
res
,
ifs
)
=
system
.
types
().
make_actor
(
"test_actor"
,
actor_cfg
,
args
);
auto
aut
=
system
.
spawn
<
actor
>
(
"test_actor"
,
std
::
move
(
args
)
);
if
(
expect_fail
)
{
CAF_REQUIRE
(
!
res
);
CAF_REQUIRE
(
!
aut
);
return
;
}
CAF_REQUIRE
(
res
);
CAF_CHECK
(
ifs
.
empty
());
auto
aut
=
actor_cast
<
actor
>
(
res
);
self
->
wait_for
(
aut
);
CAF_REQUIRE
(
aut
);
self
->
wait_for
(
*
aut
);
CAF_MESSAGE
(
"aut done"
);
}
};
...
...
libcaf_io/caf/io/middleman.hpp
View file @
22b1bc45
...
...
@@ -175,17 +175,11 @@ public:
duration
timeout
=
std
::
chrono
::
seconds
(
60
))
{
if
(
!
nid
||
name
.
empty
())
return
sec
::
invalid_argument
;
auto
res
=
remote_spawn_impl
(
nid
,
name
,
args
,
timeout
);
auto
res
=
remote_spawn_impl
(
nid
,
name
,
args
,
system
().
message_types
<
Handle
>
(),
timeout
);
if
(
!
res
)
return
std
::
move
(
res
.
error
());
if
(
!
system
().
assignable
<
Handle
>
(
res
->
second
))
{
// kill remote actor immediately and return error on interfaces mismatch
anon_send_exit
(
res
->
first
,
exit_reason
::
kill
);
return
make_error
(
sec
::
unexpected_actor_messaging_interface
,
system
().
message_types
<
Handle
>
(),
std
::
move
(
res
->
second
));
}
return
actor_cast
<
Handle
>
(
res
->
first
);
return
actor_cast
<
Handle
>
(
std
::
move
(
*
res
));
}
/// Smart pointer for `network::multiplexer`.
...
...
@@ -297,9 +291,10 @@ private:
return
system
().
spawn_class
<
Impl
,
Os
>
(
cfg
);
}
expected
<
std
::
pair
<
strong_actor_ptr
,
std
::
set
<
std
::
string
>>>
remote_spawn_impl
(
const
node_id
&
nid
,
std
::
string
&
name
,
message
&
args
,
duration
timeout
);
expected
<
strong_actor_ptr
>
remote_spawn_impl
(
const
node_id
&
nid
,
std
::
string
&
name
,
message
&
args
,
std
::
set
<
std
::
string
>
ifs
,
duration
timeout
);
expected
<
uint16_t
>
publish
(
const
strong_actor_ptr
&
whom
,
std
::
set
<
std
::
string
>
sigs
,
...
...
libcaf_io/caf/io/middleman_actor.hpp
View file @
22b1bc45
...
...
@@ -102,8 +102,8 @@ using middleman_actor =
reacts_to
<
close_atom
,
uint16_t
>
,
replies_to
<
spawn_atom
,
node_id
,
std
::
string
,
message
>
::
with
<
strong_actor_ptr
,
std
::
set
<
std
::
string
>
>
,
replies_to
<
spawn_atom
,
node_id
,
std
::
string
,
message
,
std
::
set
<
std
::
string
>
>
::
with
<
strong_actor_ptr
>
,
replies_to
<
get_atom
,
node_id
>::
with
<
node_id
,
std
::
string
,
uint16_t
>>
;
...
...
libcaf_io/src/middleman.cpp
View file @
22b1bc45
...
...
@@ -107,17 +107,14 @@ middleman::middleman(actor_system& sys)
// nop
}
expected
<
std
::
pair
<
strong_actor_ptr
,
std
::
set
<
std
::
string
>>>
middleman
::
remote_spawn_impl
(
const
node_id
&
nid
,
std
::
string
&
name
,
message
&
args
,
duration
timeout
)
{
auto
f
=
make_function_view
(
actor_handle
());
f
.
timeout
=
timeout
;
auto
res
=
f
(
spawn_atom
::
value
,
nid
,
std
::
move
(
name
),
std
::
move
(
args
));
// why can't we assign a tuple<T1, T2> to pair<T1, T2>? No one knows!
if
(
!
res
)
return
std
::
move
(
res
.
error
());
return
std
::
make_pair
(
std
::
move
(
std
::
get
<
0
>
(
*
res
)),
std
::
move
(
std
::
get
<
1
>
(
*
res
)));
expected
<
strong_actor_ptr
>
middleman
::
remote_spawn_impl
(
const
node_id
&
nid
,
std
::
string
&
name
,
message
&
args
,
std
::
set
<
std
::
string
>
s
,
duration
timeout
)
{
auto
f
=
make_function_view
(
actor_handle
(),
timeout
);
return
f
(
spawn_atom
::
value
,
nid
,
std
::
move
(
name
),
std
::
move
(
args
),
std
::
move
(
s
));
}
expected
<
uint16_t
>
middleman
::
open
(
uint16_t
port
,
const
char
*
cstr
,
bool
ru
)
{
...
...
libcaf_io/src/middleman_actor.cpp
View file @
22b1bc45
...
...
@@ -160,12 +160,13 @@ public:
delegate
(
broker_
,
atm
,
p
);
return
{};
},
[
=
](
spawn_atom
atm
,
node_id
&
nid
,
std
::
string
&
str
,
message
&
msg
)
->
delegated
<
strong_actor_ptr
,
mpi_set
>
{
[
=
](
spawn_atom
atm
,
node_id
&
nid
,
std
::
string
&
str
,
message
&
msg
,
std
::
set
<
std
::
string
>&
ifs
)
->
delegated
<
strong_actor_ptr
>
{
CAF_LOG_TRACE
(
""
);
delegate
(
broker_
,
forward_atom
::
value
,
nid
,
atom
(
"SpawnServ"
),
make_message
(
atm
,
std
::
move
(
str
),
std
::
move
(
msg
)));
//delegate(broker_, atm, std::move(nid), std::move(str), std::move(msg
));
make_message
(
atm
,
std
::
move
(
str
),
std
::
move
(
msg
),
std
::
move
(
ifs
)
));
return
{};
},
[
=
](
get_atom
atm
,
node_id
nid
)
...
...
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