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
cec81950
Unverified
Commit
cec81950
authored
Mar 01, 2023
by
Noir
Committed by
GitHub
Mar 01, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1381
Limit how many actions actors may run in one go
parents
b3164d5b
0e5a90e1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
37 additions
and
1 deletion
+37
-1
CHANGELOG.md
CHANGELOG.md
+4
-0
libcaf_core/caf/defaults.hpp
libcaf_core/caf/defaults.hpp
+5
-0
libcaf_core/caf/scheduled_actor.hpp
libcaf_core/caf/scheduled_actor.hpp
+11
-0
libcaf_core/src/scheduled_actor.cpp
libcaf_core/src/scheduled_actor.cpp
+17
-1
No files found.
CHANGELOG.md
View file @
cec81950
...
...
@@ -41,6 +41,10 @@ is based on [Keep a Changelog](https://keepachangelog.com).
-
The
`mcast`
and
`ucast`
operators now stop calling
`on_next`
immediately when
disposed.
-
Actors no longer terminate despite having open streams (#1377).
-
Actors reading from external sources such as SPSC buffers via a local flow
could end up in a long-running read loop. To avoid potentially starving other
actors or activities, scheduled actors now limit the amount of actions that
may run in one iteration (#1364).
## [0.19.0-rc.1] - 2022-10-31
...
...
libcaf_core/caf/defaults.hpp
View file @
cec81950
...
...
@@ -32,6 +32,11 @@ constexpr parameter<T> make_parameter(std::string_view name, T fallback) {
return
{
name
,
fallback
};
}
/// Configures how many actions scheduled_actor::delay may add to the internal
/// queue for scheduled_actor::run_actions before being forced to push them to
/// the mailbox instead.
constexpr
auto
max_inline_actions_per_run
=
size_t
{
10
};
}
// namespace caf::defaults
namespace
caf
::
defaults
::
stream
{
...
...
libcaf_core/caf/scheduled_actor.hpp
View file @
cec81950
...
...
@@ -829,6 +829,11 @@ private:
/// message.
std
::
vector
<
action
>
actions_
;
/// Counter for scheduled_actor::delay to make sure
/// scheduled_actor::run_actions does not end up in a busy loop that might
/// starve other activities.
size_t
delayed_actions_this_run_
=
0
;
/// Stores ongoing activities such as flows that block the actor from
/// terminating.
std
::
vector
<
disposable
>
watched_disposables_
;
...
...
@@ -844,6 +849,12 @@ private:
/// Maps the ID of incoming stream batches to local state that allows the
/// actor to push received batches into the local flow.
std
::
unordered_map
<
uint64_t
,
detail
::
stream_bridge_sub_ptr
>
stream_bridges_
;
/// Special-purpose behavior for scheduled_actor::delay. When pushing an
/// action to the mailbox, we register this behavior as the response handler.
/// This is to make sure that actor does not terminate because it thinks it's
/// done before processing the delayed action.
behavior
delay_bhvr_
;
};
}
// namespace caf
libcaf_core/src/scheduled_actor.cpp
View file @
cec81950
...
...
@@ -491,7 +491,22 @@ void scheduled_actor::schedule(action what) {
}
void
scheduled_actor
::
delay
(
action
what
)
{
actions_
.
emplace_back
(
std
::
move
(
what
));
// Happy path: push it to `actions_`, where we run it from `run_actions`.
if
(
delayed_actions_this_run_
++
<
defaults
::
max_inline_actions_per_run
)
{
actions_
.
emplace_back
(
std
::
move
(
what
));
return
;
}
// Slow path: we send a "request" with the action to ourselves. The pending
// request makes sure that the action keeps the actor alive until processed.
if
(
!
delay_bhvr_
)
{
delay_bhvr_
=
behavior
{[](
action
&
f
)
{
CAF_LOG_DEBUG
(
"run delayed action"
);
f
.
run
();
}};
}
auto
res_id
=
new_request_id
(
message_priority
::
normal
).
response_id
();
enqueue
(
nullptr
,
res_id
,
make_message
(
std
::
move
(
what
)),
context_
);
add_multiplexed_response_handler
(
res_id
,
delay_bhvr_
);
}
disposable
scheduled_actor
::
delay_until
(
steady_time_point
abs_time
,
...
...
@@ -971,6 +986,7 @@ void scheduled_actor::deregister_stream(uint64_t stream_id) {
}
void
scheduled_actor
::
run_actions
()
{
delayed_actions_this_run_
=
0
;
if
(
!
actions_
.
empty
())
{
// Note: can't use iterators here since actions may add to the vector.
for
(
auto
index
=
size_t
{
0
};
index
<
actions_
.
size
();
++
index
)
{
...
...
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