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
043aa21d
Commit
043aa21d
authored
Sep 19, 2016
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix spawn_in_group<T>, close #509
parent
4746c434
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
81 additions
and
29 deletions
+81
-29
libcaf_core/caf/actor_system.hpp
libcaf_core/caf/actor_system.hpp
+23
-18
libcaf_core/caf/local_actor.hpp
libcaf_core/caf/local_actor.hpp
+6
-6
libcaf_core/test/local_group.cpp
libcaf_core/test/local_group.cpp
+52
-5
No files found.
libcaf_core/caf/actor_system.hpp
View file @
043aa21d
...
...
@@ -360,20 +360,24 @@ public:
return
actor_cast
<
Handle
>
(
std
::
move
(
*
res
));
}
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
Iter
,
class
F
,
class
...
Ts
>
/// Spawns a class-based actor `T` immediately joining the groups in
/// range `[first, last)`.
/// @private
template
<
class
T
,
spawn_options
Os
,
class
Iter
,
class
...
Ts
>
infer_handle_from_class_t
<
T
>
spawn_
in_groups_impl
(
actor_config
&
cfg
,
Iter
first
,
Iter
second
,
Ts
&&
...
xs
)
{
spawn_
class_in_groups
(
actor_config
&
cfg
,
Iter
first
,
Iter
last
,
Ts
&&
...
xs
)
{
check_invariants
<
T
>
();
auto
irange
=
make_input_range
(
first
,
second
);
auto
irange
=
make_input_range
(
first
,
last
);
cfg
.
groups
=
&
irange
;
return
spawn_class
<
T
,
Os
>
(
cfg
,
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
spawn_options
Os
=
no_spawn_options
,
class
Iter
,
class
F
,
class
...
Ts
>
/// Spawns a class-based actor `T` immediately joining the groups in
/// range `[first, last)`.
/// @private
template
<
spawn_options
Os
,
class
Iter
,
class
F
,
class
...
Ts
>
infer_handle_from_fun_t
<
F
>
spawn_
in_groups_impl
(
actor_config
&
cfg
,
Iter
first
,
Iter
second
,
spawn_
fun_in_groups
(
actor_config
&
cfg
,
Iter
first
,
Iter
second
,
F
&
fun
,
Ts
&&
...
xs
)
{
check_invariants
<
infer_impl_from_fun_t
<
F
>>
();
auto
irange
=
make_input_range
(
first
,
second
);
...
...
@@ -386,7 +390,7 @@ public:
infer_handle_from_fun_t
<
F
>
spawn_in_groups
(
std
::
initializer_list
<
group
>
gs
,
F
fun
,
Ts
&&
...
xs
)
{
actor_config
cfg
;
return
spawn_
in_groups_impl
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
return
spawn_
fun_in_groups
<
Os
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
...
...
@@ -395,7 +399,7 @@ public:
infer_handle_from_fun_t
<
F
>
spawn_in_groups
(
const
Gs
&
gs
,
F
fun
,
Ts
&&
...
xs
)
{
actor_config
cfg
;
return
spawn_
in_groups_impl
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
return
spawn_
fun_in_groups
<
Os
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
...
...
@@ -403,7 +407,8 @@ public:
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
infer_handle_from_fun_t
<
F
>
spawn_in_group
(
const
group
&
grp
,
F
fun
,
Ts
&&
...
xs
)
{
return
spawn_in_groups
({
grp
},
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
xs
)...);
return
spawn_fun_in_groups
<
Os
>
({
grp
},
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
xs
)...);
}
/// Returns a new class-based actor subscribed to all groups in `gs`.
...
...
@@ -411,7 +416,7 @@ public:
infer_handle_from_class_t
<
T
>
spawn_in_groups
(
std
::
initializer_list
<
group
>
gs
,
Ts
&&
...
xs
)
{
actor_config
cfg
;
return
spawn_
in_groups_impl
<
T
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
return
spawn_
class_in_groups
<
T
,
Os
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
std
::
forward
<
Ts
>
(
xs
)...);
}
...
...
@@ -420,7 +425,7 @@ public:
infer_handle_from_class_t
<
T
>
spawn_in_groups
(
const
Gs
&
gs
,
Ts
&&
...
xs
)
{
actor_config
cfg
;
return
spawn_
in_groups_impl
<
T
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
return
spawn_
class_in_groups
<
T
,
Os
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
std
::
forward
<
Ts
>
(
xs
)...);
}
...
...
@@ -428,7 +433,7 @@ public:
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
...
Ts
>
infer_handle_from_class_t
<
T
>
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
xs
)
{
return
spawn_in_groups
<
T
>
({
grp
},
std
::
forward
<
Ts
>
(
xs
)...);
return
spawn_in_groups
<
T
,
Os
>
({
grp
},
std
::
forward
<
Ts
>
(
xs
)...);
}
/// Returns whether this actor system calls `await_all_actors_done`
...
...
libcaf_core/caf/local_actor.hpp
View file @
043aa21d
...
...
@@ -140,39 +140,39 @@ public:
class
...
Ts
>
actor
spawn_in_groups
(
const
Groups
&
gs
,
Ts
&&
...
xs
)
{
actor_config
cfg
{
context
()};
return
eval_opts
(
Os
,
system
().
spawn_
in_groups_impl
<
T
,
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
std
::
forward
<
Ts
>
(
xs
)...));
return
eval_opts
(
Os
,
system
().
spawn_
class_in_groups
<
T
,
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
std
::
forward
<
Ts
>
(
xs
)...));
}
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
...
Ts
>
actor
spawn_in_groups
(
std
::
initializer_list
<
group
>
gs
,
Ts
&&
...
xs
)
{
actor_config
cfg
{
context
()};
return
eval_opts
(
Os
,
system
().
spawn_
in_groups_impl
<
T
,
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
std
::
forward
<
Ts
>
(
xs
)...));
return
eval_opts
(
Os
,
system
().
spawn_
class_in_groups
<
T
,
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
std
::
forward
<
Ts
>
(
xs
)...));
}
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
...
Ts
>
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
xs
)
{
actor_config
cfg
{
context
()};
auto
first
=
&
grp
;
return
eval_opts
(
Os
,
system
().
spawn_
in_groups_impl
<
T
,
make_unbound
(
Os
)
>
(
cfg
,
first
,
first
+
1
,
std
::
forward
<
Ts
>
(
xs
)...));
return
eval_opts
(
Os
,
system
().
spawn_
class_in_groups
<
T
,
make_unbound
(
Os
)
>
(
cfg
,
first
,
first
+
1
,
std
::
forward
<
Ts
>
(
xs
)...));
}
template
<
spawn_options
Os
=
no_spawn_options
,
class
Groups
,
class
F
,
class
...
Ts
>
actor
spawn_in_groups
(
const
Groups
&
gs
,
F
fun
,
Ts
&&
...
xs
)
{
actor_config
cfg
{
context
()};
return
eval_opts
(
Os
,
system
().
spawn_
in_groups_impl
<
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
return
eval_opts
(
Os
,
system
().
spawn_
fun_in_groups
<
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
}
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
actor
spawn_in_groups
(
std
::
initializer_list
<
group
>
gs
,
F
fun
,
Ts
&&
...
xs
)
{
actor_config
cfg
{
context
()};
return
eval_opts
(
Os
,
system
().
spawn_
in_groups_impl
<
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
return
eval_opts
(
Os
,
system
().
spawn_
fun_in_groups
<
make_unbound
(
Os
)
>
(
cfg
,
gs
.
begin
(),
gs
.
end
(),
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
}
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
actor
spawn_in_group
(
const
group
&
grp
,
F
fun
,
Ts
&&
...
xs
)
{
actor_config
cfg
{
context
()};
auto
first
=
&
grp
;
return
eval_opts
(
Os
,
system
().
spawn_
in_groups_impl
<
make_unbound
(
Os
)
>
(
cfg
,
first
,
first
+
1
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
return
eval_opts
(
Os
,
system
().
spawn_
fun_in_groups
<
make_unbound
(
Os
)
>
(
cfg
,
first
,
first
+
1
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
}
// -- sending asynchronous messages ------------------------------------------
...
...
libcaf_core/test/local_group.cpp
View file @
043aa21d
...
...
@@ -28,10 +28,30 @@
using
namespace
caf
;
namespace
{
using
msg_atom
=
atom_constant
<
atom
(
"msg"
)
>
;
using
timeout_atom
=
atom_constant
<
atom
(
"timeout"
)
>
;
behavior
testee
(
event_based_actor
*
self
)
{
class
testee1
:
public
event_based_actor
{
public:
testee1
(
actor_config
&
cfg
)
:
event_based_actor
(
cfg
),
x_
(
0
)
{
// nop
}
behavior
make_behavior
()
override
{
return
{
[
=
](
put_atom
,
int
x
)
{
x_
=
x
;
},
[
=
](
get_atom
)
{
return
x_
;
}
};
}
private:
int
x_
;
};
behavior
testee2
(
event_based_actor
*
self
)
{
auto
counter
=
std
::
make_shared
<
int
>
(
0
);
auto
grp
=
self
->
system
().
groups
().
get_local
(
"test"
);
self
->
join
(
grp
);
...
...
@@ -53,8 +73,35 @@ behavior testee(event_based_actor* self) {
};
}
CAF_TEST
(
test_local_group
)
{
actor_system_config
cfg
;
actor_system
system
{
cfg
};
system
.
spawn
(
testee
);
struct
fixture
{
actor_system_config
config
;
actor_system
system
{
config
};
scoped_actor
self
{
system
};
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
group_tests
,
fixture
)
CAF_TEST
(
function_based_self_joining
)
{
system
.
spawn
(
testee2
);
}
CAF_TEST
(
class_based_joined_at_spawn
)
{
auto
grp
=
system
.
groups
().
get_local
(
"test"
);
auto
tst
=
system
.
spawn_in_group
<
testee1
>
(
grp
);
self
->
send
(
grp
,
put_atom
::
value
,
42
);
self
->
request
(
tst
,
infinite
,
get_atom
::
value
).
receive
(
[
&
](
int
x
)
{
CAF_REQUIRE_EQUAL
(
x
,
42
);
},
[
&
](
const
error
&
e
)
{
CAF_FAIL
(
"error: "
<<
system
.
render
(
e
));
}
);
// groups holds a reference to testee, stop manually
self
->
send_exit
(
tst
,
exit_reason
::
user_shutdown
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
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