mirror of
https://github.com/ceph/ceph
synced 2025-02-24 03:27:10 +00:00
crimson/common/operation: trim AggregateBlockingEvent::events entries
PglogBasedRecovery and BackfillRecovery reuse the same Operation until their respective operations are complete. Each recovery operation adds an entry to AggregateBlockingEvent::events. This way, we only retain entries that are currently blocking. Signed-off-by: Samuel Just <sjust@redhat.com>
This commit is contained in:
parent
d0708b5452
commit
29a00b4482
@ -232,28 +232,58 @@ private:
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct AggregateBlockingEvent {
|
struct AggregateBlockingEvent {
|
||||||
struct TriggerI {
|
struct TriggerI {
|
||||||
|
protected:
|
||||||
|
struct TriggerContainerI {
|
||||||
|
virtual typename T::TriggerI& get_trigger() = 0;
|
||||||
|
virtual ~TriggerContainerI() = default;
|
||||||
|
};
|
||||||
|
using TriggerContainerIRef = std::unique_ptr<TriggerContainerI>;
|
||||||
|
virtual TriggerContainerIRef create_part_trigger() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
template <class FutureT>
|
template <class FutureT>
|
||||||
auto maybe_record_blocking(FutureT&& fut,
|
auto maybe_record_blocking(FutureT&& fut,
|
||||||
const typename T::Blocker& blocker) {
|
const typename T::Blocker& blocker) {
|
||||||
// AggregateBlockingEvent is supposed to be used on relatively cold
|
// AggregateBlockingEvent is supposed to be used on relatively cold
|
||||||
// paths (recovery), so we don't need to worry about the dynamic
|
// paths (recovery), so we don't need to worry about the dynamic
|
||||||
// polymothps / dynamic memory's overhead.
|
// polymothps / dynamic memory's overhead.
|
||||||
return create_part_trigger()->maybe_record_blocking(
|
auto tcont = create_part_trigger();
|
||||||
std::move(fut), blocker);
|
return tcont->get_trigger().maybe_record_blocking(
|
||||||
|
std::move(fut), blocker
|
||||||
|
).finally([tcont=std::move(tcont)] {});
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::unique_ptr<typename T::TriggerI> create_part_trigger() = 0;
|
|
||||||
virtual ~TriggerI() = default;
|
virtual ~TriggerI() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class OpT>
|
template <class OpT>
|
||||||
struct Trigger : TriggerI {
|
struct Trigger final : TriggerI {
|
||||||
Trigger(AggregateBlockingEvent& event, const OpT& op)
|
Trigger(AggregateBlockingEvent& event, const OpT& op)
|
||||||
: event(event), op(op) {}
|
: event(event), op(op) {}
|
||||||
|
|
||||||
std::unique_ptr<typename T::TriggerI> create_part_trigger() override {
|
class TriggerContainer final : public TriggerI::TriggerContainerI {
|
||||||
return std::make_unique<typename T::template Trigger<OpT>>(
|
AggregateBlockingEvent& event;
|
||||||
event.events.emplace_back(), op);
|
typename decltype(event.events)::iterator iter;
|
||||||
|
typename T::template Trigger<OpT> trigger;
|
||||||
|
|
||||||
|
typename T::TriggerI &get_trigger() final {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
TriggerContainer(AggregateBlockingEvent& _event, const OpT& op) :
|
||||||
|
event(_event),
|
||||||
|
iter(event.events.emplace(event.events.end())),
|
||||||
|
trigger(*iter, op) {}
|
||||||
|
|
||||||
|
~TriggerContainer() final {
|
||||||
|
event.events.erase(iter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typename TriggerI::TriggerContainerIRef create_part_trigger() final {
|
||||||
|
return std::make_unique<TriggerContainer>(event, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user