namespace crimson::osd {
-void OSDMapGate::OSDMapBlocker::dump_detail(Formatter *f) const
+template <OSDMapGateType OSDMapGateTypeV>
+void OSDMapGate<OSDMapGateTypeV>::OSDMapBlocker::dump_detail(Formatter *f) const
{
f->open_object_section("OSDMapGate");
f->dump_int("epoch", epoch);
f->close_section();
}
-blocking_future<epoch_t> OSDMapGate::wait_for_map(epoch_t epoch)
+template <OSDMapGateType OSDMapGateTypeV>
+blocking_future<epoch_t> OSDMapGate<OSDMapGateTypeV>::wait_for_map(epoch_t epoch)
{
if (__builtin_expect(stopping, false)) {
return make_exception_blocking_future<epoch_t>(
}
}
-void OSDMapGate::got_map(epoch_t epoch) {
+template <OSDMapGateType OSDMapGateTypeV>
+seastar::future<epoch_t> OSDMapGate<OSDMapGateTypeV>::wait_for_map(
+ typename OSDMapBlocker::BlockingEvent::TriggerI&& trigger,
+ epoch_t epoch)
+{
+ if (__builtin_expect(stopping, false)) {
+ return seastar::make_exception_future<epoch_t>(
+ crimson::common::system_shutdown_exception());
+ }
+ if (current >= epoch) {
+ return seastar::make_ready_future<epoch_t>(current);
+ } else {
+ logger().info("evt epoch is {}, i have {}, will wait", epoch, current);
+ auto &blocker = waiting_peering.emplace(
+ epoch, std::make_pair(blocker_type, epoch)).first->second;
+ auto fut = blocker.promise.get_shared_future();
+ if (shard_services) {
+ return trigger.maybe_record_blocking(
+ (*shard_services).get().osdmap_subscribe(current, true).then(
+ [fut=std::move(fut)]() mutable {
+ return std::move(fut);
+ }),
+ blocker);
+ } else {
+ return trigger.maybe_record_blocking(std::move(fut), blocker);
+ }
+ }
+}
+
+template <OSDMapGateType OSDMapGateTypeV>
+void OSDMapGate<OSDMapGateTypeV>::got_map(epoch_t epoch) {
current = epoch;
auto first = waiting_peering.begin();
auto last = waiting_peering.upper_bound(epoch);
waiting_peering.erase(first, last);
}
-seastar::future<> OSDMapGate::stop() {
+template <OSDMapGateType OSDMapGateTypeV>
+seastar::future<> OSDMapGate<OSDMapGateTypeV>::stop() {
logger().info("osdmap::stop");
stopping = true;
auto first = waiting_peering.begin();
return seastar::now();
}
-}
+template class OSDMapGate<OSDMapGateType::PG>;
+template class OSDMapGate<OSDMapGateType::OSD>;
+
+} // namespace crimson::osd
class ShardServices;
+enum class OSDMapGateType {
+ OSD,
+ PG,
+};
+
+template <OSDMapGateType OSDMapGateTypeV>
class OSDMapGate {
- struct OSDMapBlocker : public BlockerT<OSDMapBlocker> {
+public:
+ struct OSDMapBlocker : BlockerT<OSDMapBlocker> {
const char * type_name;
epoch_t epoch;
void dump_detail(Formatter *f) const final;
};
+private:
// order the promises in ascending order of the waited osdmap epoch,
// so we can access all the waiters expecting a map whose epoch is less
// than or equal to a given epoch
: blocker_type(blocker_type), shard_services(shard_services) {}
// wait for an osdmap whose epoch is greater or equal to given epoch
- blocking_future<epoch_t> wait_for_map(epoch_t epoch);
+ blocking_future<epoch_t>
+ wait_for_map(epoch_t epoch);
+ seastar::future<epoch_t>
+ wait_for_map(typename OSDMapBlocker::BlockingEvent::TriggerI&& trigger,
+ epoch_t epoch);
void got_map(epoch_t epoch);
seastar::future<> stop();
};
+using OSD_OSDMapGate = OSDMapGate<OSDMapGateType::OSD>;
+using PG_OSDMapGate = OSDMapGate<OSDMapGateType::PG>;
+
}