namespace crimson::osd {
-// PeeringFacade -- a facade (in the GoF-defined meaning) simplifying
-// the interface of PeeringState. The motivation is to have an inventory
-// of behaviour that must be provided by a unit test's mock.
-struct BackfillState::PeeringFacade {
+// PeeringFacade -- main implementation of the BackfillState::PeeringFacade
+// interface. We have the abstraction to decuple BackfillState from Peering
+// State, and thus cut depedencies in unit testing. The second implemention
+// is BackfillFixture::PeeringFacade and sits in test_backfill.cc.
+struct PeeringFacade final : BackfillState::PeeringFacade {
PeeringState& peering_state;
- decltype(auto) earliest_backfill() const {
+ hobject_t earliest_backfill() const override {
return peering_state.earliest_backfill();
}
- decltype(auto) get_backfill_targets() const {
+ const std::set<pg_shard_t>& get_backfill_targets() const override {
return peering_state.get_backfill_targets();
}
- decltype(auto) get_peer_last_backfill(pg_shard_t peer) const {
+ const hobject_t& get_peer_last_backfill(pg_shard_t peer) const override {
return peering_state.get_peer_info(peer).last_backfill;
}
- decltype(auto) get_last_update() const {
+ const eversion_t& get_last_update() const override {
return peering_state.get_info().last_update;
}
- decltype(auto) get_log_tail() const {
+ const eversion_t& get_log_tail() const override {
return peering_state.get_info().log_tail;
}
- template <class... Args>
- void scan_log_after(Args&&... args) const {
- peering_state.get_pg_log().get_log().scan_log_after(
- std::forward<Args>(args)...);
+ void scan_log_after(eversion_t v, scan_log_func_t f) const override {
+ peering_state.get_pg_log().get_log().scan_log_after(v, std::move(f));
}
- bool is_backfill_target(pg_shard_t peer) const {
+ bool is_backfill_target(pg_shard_t peer) const override {
return peering_state.is_backfill_target(peer);
}
void update_complete_backfill_object_stats(const hobject_t &hoid,
- const pg_stat_t &stats) {
- return peering_state.update_complete_backfill_object_stats(hoid, stats);
+ const pg_stat_t &stats) override {
+ peering_state.update_complete_backfill_object_stats(hoid, stats);
}
- bool is_backfilling() const {
+ bool is_backfilling() const override {
return peering_state.is_backfilling();
}
// PGFacade -- a facade (in the GoF-defined meaning) simplifying the huge
// interface of crimson's PG class. The motivation is to have an inventory
// of behaviour that must be provided by a unit test's mock.
-struct BackfillState::PGFacade {
+struct PGFacade final : BackfillState::PGFacade {
PG& pg;
- decltype(auto) get_projected_last_update() const {
+ const eversion_t& get_projected_last_update() const override {
return pg.projected_last_update;
}
#include <boost/type_index.hpp>
#include "crimson/osd/backfill_state.h"
-#ifndef BACKFILL_UNITTEST
-#include "crimson/osd/backfill_facades.h"
-#else
-#include "test/crimson/test_backfill_facades.h"
-#endif
namespace {
seastar::logger& logger() {
virtual ~BackfillListener() = default;
};
+// PeeringFacade -- a facade (in the GoF-defined meaning) simplifying
+// the interface of PeeringState. The motivation is to have an inventory
+// of behaviour that must be provided by a unit test's mock.
+struct BackfillState::PeeringFacade {
+ virtual hobject_t earliest_backfill() const = 0;
+ virtual const std::set<pg_shard_t>& get_backfill_targets() const = 0;
+ virtual const hobject_t& get_peer_last_backfill(pg_shard_t peer) const = 0;
+ virtual const eversion_t& get_last_update() const = 0;
+ virtual const eversion_t& get_log_tail() const = 0;
+
+ // the performance impact of `std::function` has not been considered yet.
+ // If there is any proof (from e.g. profiling) about its significance, we
+ // can switch back to the template variant.
+ using scan_log_func_t = std::function<void(const pg_log_entry_t&)>;
+ virtual void scan_log_after(eversion_t, scan_log_func_t) const = 0;
+
+ virtual bool is_backfill_target(pg_shard_t peer) const = 0;
+ virtual void update_complete_backfill_object_stats(const hobject_t &hoid,
+ const pg_stat_t &stats) = 0;
+ virtual bool is_backfilling() const = 0;
+ virtual ~PeeringFacade() {}
+};
+
+// PGFacade -- a facade (in the GoF-defined meaning) simplifying the huge
+// interface of crimson's PG class. The motivation is to have an inventory
+// of behaviour that must be provided by a unit test's mock.
+struct BackfillState::PGFacade {
+ virtual const eversion_t& get_projected_last_update() const = 0;
+ virtual ~PGFacade() {}
+};
+
class BackfillState::ProgressTracker {
// TODO: apply_stat,
enum class op_stage_t {
friend class PeeringEvent;
friend class RepRequest;
friend class BackfillRecovery;
- friend struct BackfillState::PGFacade;
+ friend struct PGFacade;
private:
seastar::future<bool> find_unfound() {
return seastar::make_ready_future<bool>(true);
using BackfillState = crimson::osd::BackfillState;
backfill_state = std::make_unique<BackfillState>(
*this,
- std::make_unique<BackfillState::PeeringFacade>(pg->get_peering_state()),
- std::make_unique<BackfillState::PGFacade>(
+ std::make_unique<crimson::osd::PeeringFacade>(pg->get_peering_state()),
+ std::make_unique<crimson::osd::PGFacade>(
*static_cast<crimson::osd::PG*>(pg)));
// yes, it's **not** backfilling yet. The PG_STATE_BACKFILLING
// will be set after on_backfill_reserved() returns.
${PROJECT_SOURCE_DIR}/src/crimson/osd/backfill_state.cc
${PROJECT_SOURCE_DIR}/src/osd/recovery_types.cc)
add_ceph_unittest(unittest-crimson-backfill)
-target_compile_definitions(unittest-crimson-backfill PRIVATE -DBACKFILL_UNITTEST)
target_link_libraries(unittest-crimson-backfill crimson GTest::Main)
add_executable(unittest-seastar-buffer
#include "common/hobject.h"
#include "crimson/osd/backfill_state.h"
#include "osd/recovery_types.h"
-#include "test/crimson/test_backfill_facades.h"
// The sole purpose is to convert from the string representation.
: public crimson::osd::BackfillState::PeeringFacade {
FakePrimary& backfill_source;
std::map<pg_shard_t, FakeReplica>& backfill_targets;
+ // sorry, this is duplicative but that's the interface
+ std::set<pg_shard_t> backfill_targets_as_set;
PeeringFacade(FakePrimary& backfill_source,
std::map<pg_shard_t, FakeReplica>& backfill_targets)
: backfill_source(backfill_source),
backfill_targets(backfill_targets) {
+ std::transform(
+ std::begin(backfill_targets), std::end(backfill_targets),
+ std::inserter(backfill_targets_as_set, std::end(backfill_targets_as_set)),
+ [](auto pair) {
+ return pair.first;
+ });
}
hobject_t earliest_backfill() const override {
}
return e;
}
- std::set<pg_shard_t> get_backfill_targets() const override {
- std::set<pg_shard_t> result;
- std::transform(
- std::begin(backfill_targets), std::end(backfill_targets),
- std::inserter(result, std::end(result)),
- [](auto pair) {
- return pair.first;
- });
- return result;
+ const std::set<pg_shard_t>& get_backfill_targets() const override {
+ return backfill_targets_as_set;
}
const hobject_t& get_peer_last_backfill(pg_shard_t peer) const override {
return backfill_targets.at(peer).last_backfill;
const eversion_t& get_log_tail() const override {
return backfill_source.log_tail;
}
- template <class... Args>
- void scan_log_after(Args&&... args) const {
+
+ void scan_log_after(eversion_t, scan_log_func_t) const override {
+ /* NOP */
}
bool is_backfill_target(pg_shard_t peer) const override {
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#pragma once
-
-#include "crimson/osd/backfill_state.h"
-
-namespace crimson::osd {
-
-// PeeringFacade -- a facade (in the GoF-defined meaning) simplifying
-// the interface of PeeringState. The motivation is to have an inventory
-// of behaviour that must be provided by a unit test's mock.
-struct BackfillState::PeeringFacade {
- virtual hobject_t earliest_backfill() const = 0;
- virtual std::set<pg_shard_t> get_backfill_targets() const = 0;
- virtual const hobject_t& get_peer_last_backfill(pg_shard_t peer) const = 0;
- virtual const eversion_t& get_last_update() const = 0;
- virtual const eversion_t& get_log_tail() const = 0;
-
- template <class... Args>
- void scan_log_after(Args&&... args) const {
- }
-
- virtual bool is_backfill_target(pg_shard_t peer) const = 0;
- virtual void update_complete_backfill_object_stats(const hobject_t &hoid,
- const pg_stat_t &stats) = 0;
- virtual bool is_backfilling() const = 0;
- virtual ~PeeringFacade() {}
-};
-
-// PGFacade -- a facade (in the GoF-defined meaning) simplifying the huge
-// interface of crimson's PG class. The motivation is to have an inventory
-// of behaviour that must be provided by a unit test's mock.
-struct BackfillState::PGFacade {
- virtual const eversion_t& get_projected_last_update() const = 0;
- virtual ~PGFacade() {}
-};
-
-} // namespace crimson::osd