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
26d23666
Commit
26d23666
authored
Apr 14, 2023
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix demand signaling in the merge operator
parent
6742ddcd
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
229 additions
and
151 deletions
+229
-151
libcaf_core/caf/defaults.hpp
libcaf_core/caf/defaults.hpp
+10
-0
libcaf_core/caf/flow/op/merge.hpp
libcaf_core/caf/flow/op/merge.hpp
+188
-148
libcaf_core/test/flow/mixed.cpp
libcaf_core/test/flow/mixed.cpp
+27
-0
libcaf_core/test/flow/op/merge.cpp
libcaf_core/test/flow/op/merge.cpp
+4
-3
No files found.
libcaf_core/caf/defaults.hpp
View file @
26d23666
...
...
@@ -141,10 +141,20 @@ constexpr auto network_backend = std::string_view{"default"};
namespace
caf
::
defaults
::
flow
{
/// Defines how much demand should accumulate before signaling demand upstream.
/// A minimum demand is used by operators such as `observe_on` to avoid overly
/// frequent signaling across asynchronous barriers.
constexpr
auto
min_demand
=
size_t
{
8
};
/// Defines how many items a single batch may contain.
constexpr
auto
batch_size
=
size_t
{
32
};
/// Limits how many items an operator buffers internally.
constexpr
auto
buffer_size
=
size_t
{
128
};
/// Limits the number of concurrent subscriptions for operators such as `merge`.
constexpr
auto
max_concurrent
=
size_t
{
8
};
}
// namespace caf::defaults::flow
namespace
caf
::
defaults
::
net
{
...
...
libcaf_core/caf/flow/op/merge.hpp
View file @
26d23666
This diff is collapsed.
Click to expand it.
libcaf_core/test/flow/mixed.cpp
View file @
26d23666
...
...
@@ -12,6 +12,7 @@
#include "caf/flow/observable.hpp"
#include "caf/flow/observable_builder.hpp"
#include "caf/flow/scoped_coordinator.hpp"
#include "caf/scheduled_actor/flow.hpp"
using
namespace
caf
;
...
...
@@ -68,4 +69,30 @@ SCENARIO("sum up all the multiples of 3 or 5 below 1000") {
}
}
TEST_CASE
(
"GH-1399 regression"
)
{
// Original issue: flat_map does not limit the demand it signals upstream.
// When running flat_map on an unbound sequence like iota-observable, it
// produces an infinite amount of observables without ever giving downstream
// operators the opportunity to cut off the flow items.
auto
worker_fn
=
[]()
->
behavior
{
return
{
[](
int
x
)
{
return
-
x
;
},
};
};
auto
worker
=
sys
.
spawn
(
worker_fn
);
auto
results
=
std
::
make_shared
<
std
::
vector
<
int
>>
();
auto
run_fn
=
[
worker
,
results
](
caf
::
event_based_actor
*
self
)
{
self
->
make_observable
()
.
iota
(
1
)
.
flat_map
([
self
,
worker
](
int
x
)
{
return
self
->
request
(
worker
,
infinite
,
x
).
as_observable
<
int32_t
>
();
})
.
take
(
10
)
.
for_each
([
results
](
int
value
)
{
results
->
push_back
(
value
);
});
};
sys
.
spawn
(
run_fn
);
run
();
CHECK_EQ
(
*
results
,
ls
(
-
1
,
-
2
,
-
3
,
-
4
,
-
5
,
-
6
,
-
7
,
-
8
,
-
9
,
-
10
));
}
END_FIXTURE_SCOPE
()
libcaf_core/test/flow/op/merge.cpp
View file @
26d23666
...
...
@@ -43,8 +43,9 @@ struct fixture : test_coordinator_fixture<> {
template
<
class
T
,
class
...
Ts
>
auto
raw_sub
(
flow
::
observer
<
T
>
out
,
Ts
&&
...
xs
)
{
using
flow
::
observable
;
auto
ptr
=
make_counted
<
flow
::
op
::
merge_sub
<
T
>>
(
ctx
.
get
(),
out
);
(
ptr
->
subscribe_to
(
xs
),
...);
auto
ptr
=
make_counted
<
flow
::
op
::
merge_sub
<
T
>>
(
ctx
.
get
(),
out
,
sizeof
...(
Ts
));
(
ptr
->
on_next
(
xs
),
...);
out
.
on_subscribe
(
flow
::
subscription
{
ptr
});
return
ptr
;
}
...
...
@@ -54,7 +55,7 @@ struct fixture : test_coordinator_fixture<> {
BEGIN_FIXTURE_SCOPE
(
fixture
)
SCENARIO
(
"the merge operator combine inputs"
)
{
SCENARIO
(
"the merge operator combine
s
inputs"
)
{
GIVEN
(
"two observables"
)
{
WHEN
(
"merging them to a single observable"
)
{
THEN
(
"the observer receives the output of both sources"
)
{
...
...
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