common/async: add co_throttle for bounded concurrency with c++20 coroutines#49720
common/async: add co_throttle for bounded concurrency with c++20 coroutines#49720cbodley wants to merge 3 commits intoceph:wip-coro-after-reeffrom
Conversation
dc207c4 to
a593508
Compare
|
to expand on the flavors of
|
6c3db31 to
e722723
Compare
|
updates:
|
4b3189b to
6f3e58e
Compare
Signed-off-by: Casey Bodley <cbodley@redhat.com>
Signed-off-by: Casey Bodley <cbodley@redhat.com>
…utines Signed-off-by: Casey Bodley <cbodley@redhat.com>
6f3e58e to
9fcd2e8
Compare
|
rebased on wip-coro-after-reef |
|
Is this ready for me to pull onto coro-after-reef? |
|
@adamemerson yep! |
|
Merging to #49737 |
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
in the initial design of co_throttle described in ceph#49720, the cancel_on_error option only applied to errors from awaitable<error_code> but not to exceptions from awaitable<void> coroutines with the decision to use exceptions as the default method of error handling in rgw multisite, this design choice no longer makes sense. i've removed the error_code overloads entirely, and changed the exception handling logic to match the previous behavior for error codes the unit tests were rewritten with co_waiter instead of timers to make them deterministic and faster. co_waiter's cancellation behavior exposed some issues where the cancellation signal could cause the completions to recurse, so on_complete() was restructured to tolerate that Signed-off-by: Casey Bodley <cbodley@redhat.com>
design goals
allow a parent coroutine to spawn many child coroutines and wait for them to complete, while enforcing an upper bound on concurrency
this follows a similar pattern to rgw multisite's yield_spawn_window() macro
simple interface
expressive interface with minimal boilerplate. construct a
co_throttle,spawn()children,wait()for all completions. error handling is optionalerror handling
spawn()is overloaded for bothawaitable<void>andawaitable<error_code>. error codes returned by spawned coroutines are reported by the next call tospawn()orwait(). ifwait()encounters an error, it still drains other outstanding coroutines before returning the original error codein response to an error, other coroutines may optionally be canceled:
cancel_on_error::noneno spawned coroutines are canceled on failure (default)cancel_on_error::aftercancel coroutines spawned after the failed coroutinecancel_on_error::allcancel all spawned coroutines on failureafter an error is reported by
spawn()orwait(), new coroutines can bespawn()ed as normalexceptions
the first unhandled exception thrown by a child coroutine gets rethrown in the parent's next call to
spawn()orwait(). this way, exceptions compose from child->parent->grandparent...cancellation
cancel()cancels all spawned coroutines and causes pendingspawn()andwait()calls to fail with operation_aborted. the destructor callscancel()cancellation support allows us to control the scope of spawned coroutines, so that child coroutines can safely access memory from the parent's stack
Show available Jenkins commands
jenkins retest this pleasejenkins test classic perfjenkins test crimson perfjenkins test signedjenkins test make checkjenkins test make check arm64jenkins test submodulesjenkins test dashboardjenkins test dashboard cephadmjenkins test apijenkins test docsjenkins render docsjenkins test ceph-volume alljenkins test ceph-volume toxjenkins test windows