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
21316bb3
Unverified
Commit
21316bb3
authored
Jan 31, 2023
by
Noir
Committed by
GitHub
Jan 31, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1373
Handle void results in fan_out_request
parents
ecf585a7
cb478b5c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
84 additions
and
11 deletions
+84
-11
CHANGELOG.md
CHANGELOG.md
+2
-0
libcaf_core/caf/policy/select_all.hpp
libcaf_core/caf/policy/select_all.hpp
+40
-5
libcaf_core/test/mixin/requester.cpp
libcaf_core/test/mixin/requester.cpp
+25
-0
libcaf_test/caf/test/dsl.hpp
libcaf_test/caf/test/dsl.hpp
+17
-6
No files found.
CHANGELOG.md
View file @
21316bb3
...
...
@@ -19,6 +19,8 @@ is based on [Keep a Changelog](https://keepachangelog.com).
on the buffer that could cause indefinite hanging of an application.
-
Fused stages now properly forward errors during the initial subscription to
their observer.
-
The
`fan_out_request`
request now properly deals with actor handles that
respond with
`void`
(#1369).
## [0.19.0-rc.1] - 2022-10-31
...
...
libcaf_core/caf/policy/select_all.hpp
View file @
21316bb3
...
...
@@ -37,8 +37,11 @@ using select_all_helper_value_t =
typename
select_all_helper_value_oracle
<
Ts
...
>::
type
;
template
<
class
F
,
class
...
Ts
>
struct
select_all_helper
{
using
value_type
=
select_all_helper_value_t
<
Ts
...
>
;
struct
select_all_helper
;
template
<
class
F
,
class
T
,
class
...
Ts
>
struct
select_all_helper
<
F
,
T
,
Ts
...
>
{
using
value_type
=
select_all_helper_value_t
<
T
,
Ts
...
>
;
std
::
vector
<
value_type
>
results
;
std
::
shared_ptr
<
size_t
>
pending
;
disposable
timeouts
;
...
...
@@ -52,10 +55,10 @@ struct select_all_helper {
results
.
reserve
(
pending
);
}
void
operator
()(
Ts
&
...
xs
)
{
void
operator
()(
T
&
x
,
T
s
&
...
xs
)
{
CAF_LOG_TRACE
(
CAF_ARG2
(
"pending"
,
*
pending
));
if
(
*
pending
>
0
)
{
results
.
emplace_back
(
std
::
move
(
xs
)...);
results
.
emplace_back
(
std
::
move
(
x
),
std
::
move
(
x
s
)...);
if
(
--*
pending
==
0
)
{
timeouts
.
dispose
();
f
(
std
::
move
(
results
));
...
...
@@ -64,7 +67,34 @@ struct select_all_helper {
}
auto
wrap
()
{
return
[
this
](
Ts
&
...
xs
)
{
(
*
this
)(
xs
...);
};
return
[
this
](
T
&
x
,
Ts
&
...
xs
)
{
(
*
this
)(
x
,
xs
...);
};
}
};
template
<
class
F
>
struct
select_all_helper
<
F
>
{
std
::
shared_ptr
<
size_t
>
pending
;
disposable
timeouts
;
F
f
;
template
<
class
Fun
>
select_all_helper
(
size_t
pending
,
disposable
timeouts
,
Fun
&&
f
)
:
pending
(
std
::
make_shared
<
size_t
>
(
pending
)),
timeouts
(
std
::
move
(
timeouts
)),
f
(
std
::
forward
<
Fun
>
(
f
))
{
// nop
}
void
operator
()()
{
CAF_LOG_TRACE
(
CAF_ARG2
(
"pending"
,
*
pending
));
if
(
*
pending
>
0
&&
--*
pending
==
0
)
{
timeouts
.
dispose
();
f
();
}
}
auto
wrap
()
{
return
[
this
]
{
(
*
this
)();
};
}
};
...
...
@@ -82,6 +112,11 @@ struct select_select_all_helper<F, detail::type_list<std::vector<T>>> {
using
type
=
select_all_helper
<
F
,
T
>
;
};
template
<
class
F
>
struct
select_select_all_helper
<
F
,
detail
::
type_list
<>>
{
using
type
=
select_all_helper
<
F
>
;
};
template
<
class
F
>
using
select_all_helper_t
=
typename
select_select_all_helper
<
F
>::
type
;
...
...
libcaf_core/test/mixin/requester.cpp
View file @
21316bb3
...
...
@@ -21,6 +21,7 @@ namespace {
using
discarding_server_type
=
typed_actor
<
result
<
void
>
(
int
,
int
)
>
;
using
adding_server_type
=
typed_actor
<
result
<
int
>
(
int
,
int
)
>
;
using
no_op_server_type
=
typed_actor
<
result
<
void
>
(
int
,
int
)
>
;
using
result_type
=
std
::
variant
<
none_t
,
unit_t
,
int
>
;
...
...
@@ -167,6 +168,30 @@ CAF_TEST(requesters support fan_out_request) {
CHECK_EQ
(
*
sum
,
9
);
}
CAF_TEST
(
requesters
support
fan_out_request
with
result
<
void
>
)
{
using
policy
::
select_all
;
std
::
vector
<
no_op_server_type
>
workers
{
make_server
([](
int
,
int
)
{}),
make_server
([](
int
,
int
)
{}),
make_server
([](
int
,
int
)
{}),
};
run
();
auto
ran
=
std
::
make_shared
<
bool
>
(
false
);
auto
client
=
sys
.
spawn
([
=
](
event_based_actor
*
self
)
{
self
->
fan_out_request
<
select_all
>
(
workers
,
infinite
,
1
,
2
).
then
([
=
]()
{
*
ran
=
true
;
});
});
run_once
();
expect
((
int
,
int
),
from
(
client
).
to
(
workers
[
0
]).
with
(
1
,
2
));
expect
((),
from
(
workers
[
0
]).
to
(
client
));
expect
((
int
,
int
),
from
(
client
).
to
(
workers
[
1
]).
with
(
1
,
2
));
expect
((),
from
(
workers
[
1
]).
to
(
client
));
expect
((
int
,
int
),
from
(
client
).
to
(
workers
[
2
]).
with
(
1
,
2
));
expect
((),
from
(
workers
[
2
]).
to
(
client
));
CHECK_EQ
(
*
ran
,
true
);
}
#ifdef CAF_ENABLE_EXCEPTIONS
CAF_TEST
(
exceptions
while
processing
requests
trigger
error
messages
)
{
...
...
libcaf_test/caf/test/dsl.hpp
View file @
21316bb3
...
...
@@ -249,18 +249,29 @@ std::optional<std::tuple<T, Ts...>> try_extract(caf_handle x) {
/// Returns the content of the next mailbox element without taking it out of
/// the mailbox. Fails on an empty mailbox or if the content of the next
/// element does not match `<T, Ts...>`.
template
<
class
T
,
class
...
Ts
>
std
::
tuple
<
T
,
Ts
...
>
extract
(
caf_handle
x
,
int
src_line
)
{
if
(
auto
result
=
try_extract
<
T
,
Ts
...
>
(
x
))
{
return
std
::
move
(
*
result
);
template
<
class
...
Ts
>
std
::
tuple
<
Ts
...
>
extract
(
caf_handle
x
,
int
src_line
)
{
if
constexpr
(
sizeof
...(
Ts
)
>
0
)
{
if
(
auto
result
=
try_extract
<
Ts
...
>
(
x
))
{
return
std
::
move
(
*
result
);
}
else
{
auto
ptr
=
x
->
peek_at_next_mailbox_element
();
if
(
ptr
==
nullptr
)
CAF_FAIL
(
"cannot peek at the next message: mailbox is empty"
,
src_line
);
else
CAF_FAIL
(
"message does not match expected types: "
<<
to_string
(
ptr
->
content
()),
src_line
);
}
}
else
{
auto
ptr
=
x
->
peek_at_next_mailbox_element
();
if
(
ptr
==
nullptr
)
CAF_FAIL
(
"cannot peek at the next message: mailbox is empty"
,
src_line
);
else
CAF_FAIL
(
"message does not match
expected types
: "
else
if
(
!
ptr
->
content
().
empty
())
CAF_FAIL
(
"message does not match
(expected an empty message)
: "
<<
to_string
(
ptr
->
content
()),
src_line
);
return
{};
}
}
...
...
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