33 const Function<
void (
bool drop_all_packets)>& timer_fired)
37 node_task_engine, sock_drop_timeout, std::move(sock),
43 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: contemporary events group: START.");
58 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: packet [" << packet_id <<
"] now In-flight.");
63 const auto insert_result =
67 assert(insert_result.second);
77 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: packet [" << packet_id <<
"] acknowledged.");
86 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: acknowledged packet [" << packet_id <<
"] replaces "
94 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: packet [" << packet_id <<
"] now no longer In-flight.");
99 const size_t num_erased =
102 assert(num_erased == 1);
107 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: all packets now no longer In-flight. Send pipe empty.");
120 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: contemporary events group: END.");
133 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: send pipe no longer empty (first packet In-flight).");
157 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: send pipe's left edge moved to the right.");
240 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"]: out of order acknowledgment detected.");
284 if (
m_sock->opt(
m_sock->m_opts.m_st_out_of_order_ack_restarts_drop_timer))
298 const Function<
void (
bool drop_all_packets)>& timer_fired) :
300 m_node_task_engine(*node_task_engine),
301 m_sock_drop_timeout(*sock_drop_timeout),
302 m_sock(std::move(sock)),
303 m_timer(m_node_task_engine),
304 m_timer_running(false),
305 m_current_wait_id(0),
307 m_timer_failure(timer_failure),
308 m_timer_fired(timer_fired),
309 m_at_events_start_oldest_flying_packet(0),
310 m_during_events_newest_acked_packet(0),
311 m_in_events_group(false)
328 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"] permanently disabled.");
350 using boost::asio::post;
351 using boost::chrono::microseconds;
352 using boost::chrono::milliseconds;
353 using boost::chrono::round;
380 bool use_time_pt_over_duration;
381 if (
m_sock->opt(
m_sock->m_opts.m_st_drop_packet_exactly_after_drop_timeout))
386 assert(!
m_sock->m_snd_flying_pkts_by_sent_when.empty());
388 =
m_sock->m_snd_flying_pkts_by_sent_when.const_back().second->m_sent_when.back().m_sent_time;
391 use_time_pt_over_duration =
true;
397 fire_duration_vs_now = fire_time_pt - Fine_clock::now();
404 use_time_pt_over_duration =
false;
408 "[" << round<milliseconds>(fire_duration_vs_now) <<
"] from now; "
419 const auto this_ptr = shared_from_this();
423 use_time_pt_over_duration
424 ?
m_timer.expires_at(fire_time_pt, sys_err_code)
425 :
m_timer.expires_from_now(fire_duration_vs_now, sys_err_code);
444 m_timer.async_wait([
this, this_ptr, this_wait_id](
const Error_code& sys_err_code)
454 using boost::chrono::milliseconds;
455 using boost::chrono::round;
466 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"] disabling; was set to fire in "
467 "[" << round<milliseconds>(
m_timer.expires_from_now()) <<
"]; "
482 using boost::chrono::milliseconds;
483 using boost::chrono::round;
486 || (sys_err_code == boost::asio::error::operation_aborted)
490 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"] fired but obsolete/canceled; "
491 "done = [" <<
m_done <<
"]; "
492 "aborted = [" << (sys_err_code == boost::asio::error::operation_aborted) <<
"]; "
494 "wait_id = [" << wait_id <<
"]; current_wait_id = [" <<
m_current_wait_id <<
"].");
499 FLOW_LOG_TRACE(
"Drop_timer [" <<
this <<
"] fired; wait_id = [" << wait_id <<
"].");
517 unsigned int backoff_factor;
521 backoff_factor =
m_sock->m_opts.m_dyn_drop_timeout_backoff_factor;
522 ceiling =
m_sock->m_opts.m_dyn_drop_timeout_ceiling;
525 if (backoff_factor != 1)
527 assert(backoff_factor != 0);
530 FLOW_LOG_TRACE(
"Increased DTO by factor [" << backoff_factor <<
"] with "
531 "ceiling [" << round<milliseconds>(ceiling) <<
"] to "
const Component & get_log_component() const
Returns reference to the stored Component object, particularly as many FLOW_LOG_*() macros expect.
Logger * get_logger() const
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect.
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
virtual bool should_log(Sev sev, const Component &component) const =0
Given attributes of a hypothetical message that would be logged, return true if that message should b...
Sequence_number::seq_num_t packet_id_t
Type to uniquely identify a packet sent over the wire in the socket to which this Drop_timer applies.
packet_id_t m_during_events_newest_acked_packet
During the time period starting with the last start_contemporaneous_events() call and ending with the...
Function< void(const Error_code &err_code)> m_timer_failure
Called on error. See Drop_timer constructor.
packet_id_t m_at_events_start_oldest_flying_packet
The packet ID of the least recently sent In-flight packet at last start_contemporaneous_events() call...
void timer_failure(Ptr prevent_destruction, const Error_code &err_code)
Called by boost.asio after we post it, in the event of some timer error.
void end_contemporaneous_events()
Finishes the group started by start start_contemporaneous_events().
void on_ack(packet_id_t packet_id)
Indicates that a packet for which on_packet_in_flight() was called has just been validly acked.
void start_timer()
Starts a new wait on the timer, so that is it asynchronously triggered according to the current DTO v...
void on_packet_no_longer_in_flight(packet_id_t packet_id)
Indicates that a packet for which on_packet_in_flight() was called is now no longer considered In-fli...
static Ptr create_drop_timer(log::Logger *logger_ptr, util::Task_engine *node_task_engine, Fine_duration *sock_drop_timeout, Peer_socket::Const_ptr &&sock, const Function< void(const Error_code &err_code)> &timer_failure, const Function< void(bool drop_all_packets)> &timer_fired)
Constructs Drop_timer and returns a ref-counted pointer wrapping it.
const Peer_socket::Const_ptr m_sock
The containing Peer_socket (note that this is read-only access).
std::set< packet_id_t > m_flying_packets
Packet IDs of packets to have been sent over wire and still considered In-flight, ordered from earlie...
Function< void(bool drop_all_packets)> m_timer_fired
Called on Drop Timeout. See Drop_timer constructor.
bool m_timer_running
Is there an active (non-obsolete, not-canceled) asynchronous wait in progress on m_timer?...
Drop_timer(log::Logger *logger, util::Task_engine *node_task_engine, Fine_duration *sock_drop_timeout, Peer_socket::Const_ptr &&sock, const Function< void(const Error_code &err_code)> &timer_failure, const Function< void(bool drop_all_packets)> &timer_fired)
Constructs Drop_timer as described in the factory constructor create_drop_timer().
bool m_done
true if and only if done() has been called. Starts at false, can only change to true.
timer_wait_id_t m_current_wait_id
Unique (within this object) identifier of the last start_timer() call.
void handle_timer_firing(Ptr prevent_destruction, timer_wait_id_t wait_id, const Error_code &sys_err_code)
Called by boost.asio when the Drop Timer fires; disables timer and calls an outside action callback (...
void done()
Causes the Drop_timer to guarantee none of the action callbacks provided at construction will be call...
void start_contemporaneous_events()
Indicates the start of a series of zero or more contemporary on_*() event calls, to be marked as fini...
util::Task_engine & m_node_task_engine
Node::m_task_engine of the containing Node. Used to schedule timer events.
void on_no_packets_in_flight_any_longer()
Equivalent to on_packet_no_longer_in_flight(P), for all P currently In-flight as registered by on_pac...
util::Timer m_timer
The Drop Timer itself.
void disable_timer()
Invalidates the running asynchronous wait on m_timer. Pre-condition: m_timer_running.
uint64_t timer_wait_id_t
The counter type used to distinguish a given start_timer() call from any other such call (for this ob...
Fine_duration & m_sock_drop_timeout
Reference to the containing Peer_socket's Peer_socket::m_snd_drop_timeout data member (= DTO,...
bool m_in_events_group
true if and only if the last start_contemporaneous_events() call exists, and either end_contemporaneo...
void on_packet_in_flight(packet_id_t packet_id)
Indicates that a packet identified by the given unique ID has just been sent over the wire (the low-l...
util::Lock_guard< Options_mutex > Options_lock
Short-hand for lock that acquires exclusive access to an Options_mutex.
boost::shared_ptr< Drop_timer > Ptr
Short-hand for ref-counted pointer to mutable values of type Target_type::element_type (a-la T*).
Const_target_ptr Const_ptr
Short-hand for ref-counted pointer to immutable values of type Target_type::element_type (a-la T cons...
#define FLOW_ERROR_SYS_ERROR_LOG_WARNING()
Logs a warning about the (often errno-based or from a library) error code in sys_err_code.
#define FLOW_LOG_TRACE(ARG_stream_fragment)
Logs a TRACE message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
Sev
Enumeration containing one of several message severity levels, ordered from highest to lowest.
@ S_INTERNAL_ERROR_SYSTEM_ERROR_ASIO_TIMER
Internal error: System error: Something went wrong with boost.asio timer subsystem.
Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...
bool key_exists(const Container &container, const typename Container::key_type &key)
Returns true if and only if the given key is present at least once in the given associative container...
boost::asio::io_service Task_engine
Short-hand for boost.asio event service, the central class of boost.asio.
boost::system::error_code Error_code
Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...
Flow_log_component
The flow::log::Component payload enumeration comprising various log components used by Flow's own int...
Fine_clock::duration Fine_duration
A high-res time duration as computed from two Fine_time_pts.
Fine_clock::time_point Fine_time_pt
A high-res time point as returned by Fine_clock::now() and suitable for precise time math in general.