namespace crimson::net {
-#ifdef UNIT_TESTS_BUILT
-class Interceptor;
-#endif
-
using seq_num_t = uint64_t;
+/**
+ * Connection
+ *
+ * Abstraction for messenger connections.
+ *
+ * Except when otherwise specified, methods must be invoked from the core on which
+ * the connection originates.
+ */
class Connection : public seastar::enable_shared_from_this<Connection> {
- entity_name_t peer_name = {0, -1};
+ public:
+ using clock_t = seastar::lowres_system_clock;
- protected:
- entity_addr_t peer_addr;
+ Connection() {}
- // which of the peer_addrs we're connecting to (as client)
- // or should reconnect to (as peer)
- entity_addr_t target_addr;
+ virtual ~Connection() {}
- using clock_t = seastar::lowres_system_clock;
- clock_t::time_point last_keepalive;
- clock_t::time_point last_keepalive_ack;
+ /**
+ * get_shard_id
+ *
+ * The shard id where the Connection is dispatching events and handling I/O.
+ *
+ * May be changed with the accept/connect events.
+ */
+ virtual const seastar::shard_id get_shard_id() const = 0;
- void set_peer_type(entity_type_t peer_type) { peer_name._type = peer_type; }
- void set_peer_id(int64_t peer_id) { peer_name._num = peer_id; }
- void set_peer_name(entity_name_t name) { peer_name = name; }
+ virtual const entity_name_t &get_peer_name() const = 0;
- public:
- uint64_t peer_global_id = 0;
+ entity_type_t get_peer_type() const { return get_peer_name().type(); }
+ int64_t get_peer_id() const { return get_peer_name().num(); }
+ bool peer_is_mon() const { return get_peer_name().is_mon(); }
+ bool peer_is_mgr() const { return get_peer_name().is_mgr(); }
+ bool peer_is_mds() const { return get_peer_name().is_mds(); }
+ bool peer_is_osd() const { return get_peer_name().is_osd(); }
+ bool peer_is_client() const { return get_peer_name().is_client(); }
- protected:
- uint64_t features = 0;
+ virtual const entity_addr_t &get_peer_addr() const = 0;
- public:
- void set_features(uint64_t new_features) {
- features = new_features;
- }
- auto get_features() const {
- return features;
- }
- bool has_feature(uint64_t f) const {
- return features & f;
+ const entity_addrvec_t get_peer_addrs() const {
+ return entity_addrvec_t(get_peer_addr());
}
- public:
- Connection() {}
- virtual ~Connection() {}
+ virtual const entity_addr_t &get_peer_socket_addr() const = 0;
-#ifdef UNIT_TESTS_BUILT
- Interceptor *interceptor = nullptr;
-#endif
+ virtual uint64_t get_features() const = 0;
- virtual Messenger* get_messenger() const = 0;
- const entity_addr_t& get_peer_addr() const { return peer_addr; }
- const entity_addrvec_t get_peer_addrs() const {
- return entity_addrvec_t(peer_addr);
- }
- const auto& get_peer_socket_addr() const {
- return target_addr;
+ bool has_feature(uint64_t f) const {
+ return get_features() & f;
}
- const entity_name_t& get_peer_name() const { return peer_name; }
- entity_type_t get_peer_type() const { return peer_name.type(); }
- int64_t get_peer_id() const { return peer_name.num(); }
-
- bool peer_is_mon() const { return peer_name.is_mon(); }
- bool peer_is_mgr() const { return peer_name.is_mgr(); }
- bool peer_is_mds() const { return peer_name.is_mds(); }
- bool peer_is_osd() const { return peer_name.is_osd(); }
- bool peer_is_client() const { return peer_name.is_client(); }
/// true if the handshake has completed and no errors have been encountered
virtual bool is_connected() const = 0;
-#ifdef UNIT_TESTS_BUILT
- virtual bool is_closed() const = 0;
+ /**
+ * send
+ *
+ * Send a message over a connection that has completed its handshake.
+ *
+ * May be invoked from any core, but that requires to chain the returned
+ * future to preserve ordering.
+ */
+ virtual seastar::future<> send(MessageURef msg) = 0;
+
+ /**
+ * send_keepalive
+ *
+ * Send a keepalive message over a connection that has completed its
+ * handshake.
+ *
+ * May be invoked from any core, but that requires to chain the returned
+ * future to preserve ordering.
+ */
+ virtual seastar::future<> send_keepalive() = 0;
+
+ virtual clock_t::time_point get_last_keepalive() const = 0;
+
+ virtual clock_t::time_point get_last_keepalive_ack() const = 0;
+
+ // workaround for the monitor client
+ virtual void set_last_keepalive_ack(clock_t::time_point when) = 0;
+
+ // close the connection and cancel any any pending futures from read/send,
+ // without dispatching any reset event
+ virtual void mark_down() = 0;
- virtual bool peer_wins() const = 0;
-#endif
+ struct user_private_t {
+ virtual ~user_private_t() = default;
+ };
- /// send a message over a connection that has completed its handshake
- virtual seastar::future<> send(MessageRef msg) = 0;
+ virtual bool has_user_private() const = 0;
- /// send a keepalive message over a connection that has completed its
- /// handshake
- virtual seastar::future<> keepalive() = 0;
+ virtual user_private_t &get_user_private() = 0;
- // close the connection and cancel any any pending futures from read/send
- // Note it's OK to discard the returned future because Messenger::shutdown()
- // will wait for all connections closed
- virtual seastar::future<> close() = 0;
+ virtual void set_user_private(std::unique_ptr<user_private_t>) = 0;
- virtual void print(ostream& out) const = 0;
+ virtual void print(std::ostream& out) const = 0;
- void set_last_keepalive(clock_t::time_point when) {
- last_keepalive = when;
- }
- void set_last_keepalive_ack(clock_t::time_point when) {
- last_keepalive_ack = when;
- }
- auto get_last_keepalive() const { return last_keepalive; }
- auto get_last_keepalive_ack() const { return last_keepalive_ack; }
+#ifdef UNIT_TESTS_BUILT
+ virtual bool is_protocol_ready() const = 0;
- seastar::shared_ptr<Connection> get_shared() {
- return shared_from_this();
- }
+ virtual bool is_protocol_standby() const = 0;
- struct user_private_t {
- virtual ~user_private_t() = default;
- };
-private:
- unique_ptr<user_private_t> user_private;
-public:
- bool has_user_private() const {
- return user_private != nullptr;
- }
- void set_user_private(unique_ptr<user_private_t> new_user_private) {
- user_private = std::move(new_user_private);
- }
- user_private_t &get_user_private() {
- ceph_assert(user_private);
- return *user_private;
- }
+ virtual bool is_protocol_closed() const = 0;
+
+ virtual bool is_protocol_closed_clean() const = 0;
+
+ virtual bool peer_wins() const = 0;
+#endif
};
-inline ostream& operator<<(ostream& out, const Connection& conn) {
+inline std::ostream& operator<<(std::ostream& out, const Connection& conn) {
out << "[";
conn.print(out);
out << "]";
}
} // namespace crimson::net
+
+#if FMT_VERSION >= 90000
+template <> struct fmt::formatter<crimson::net::Connection> : fmt::ostream_formatter {};
+#endif