1 /*!
2  * \file
3  * \brief An implementation of time_limited_delivery envelope.
4  *
5  * \since
6  * v.1.2.0
7  */
8 
9 #pragma once
10 
11 #include <so_5_extra/enveloped_msg/just_envelope.hpp>
12 
13 #include <chrono>
14 
15 namespace so_5 {
16 
17 namespace extra {
18 
19 namespace enveloped_msg {
20 
21 //
22 // time_limited_delivery_t
23 //
24 /*!
25  * \brief A special envelope to perform time-limited delivery.
26  *
27  * This envelope checks the current time before processing/transformation
28  * of the enveloped message. If the current time is equal or greater than
29  * the specified deadline then message won't be processed/transformed.
30  *
31  * Usage example:
32  * \code
33  * namespace msg_ns = so_5::extra::enveloped_msg;
34  *
35  * // Use time_limited_delivery_t with wallclock deadline.
36  * msg_ns::make<my_message>(...)
37  * 		.envelope<msg_ns::time_limited_delivery_t>(
38  * 				// Limit lifetime of the message by 5 seconds from now.
39  * 				std::chrono::steady_clock::now() + 5s)
40  * 		.send_to(destination);
41  *
42  * // The same thing but less verbose:
43  * msg_ns::make<my_message>(...)
44  * 		.envelope<msg_ns::time_limited_delivery_t>(
45  * 				// Limit lifetime of the message by 5 seconds from now.
46  * 				5s)
47  * 		.send_to(destination);
48  * \endcode
49  *
50  * \since
51  * v.1.2.0
52  */
53 class time_limited_delivery_t final : public just_envelope_t
54 	{
55 		//! Delivery deadline.
56 		const std::chrono::steady_clock::time_point m_deadline;
57 
58 	public :
59 		//! Initializing constructor.
60 		/*!
61 		 * Receives wallclock time as deadline.
62 		 */
time_limited_delivery_t(message_ref_t message,std::chrono::steady_clock::time_point deadline)63 		time_limited_delivery_t(
64 			//! Message to be delivered.
65 			message_ref_t message,
66 			//! Delivery deadline.
67 			std::chrono::steady_clock::time_point deadline )
68 			:	just_envelope_t{ std::move(message) }
69 			,	m_deadline{ deadline }
70 			{}
71 
72 		//! Initializing constructor.
73 		/*!
74 		 * Receives time interval. Deadline will be calculated automatically
75 		 * from the current time.
76 		 */
time_limited_delivery_t(message_ref_t message,std::chrono::steady_clock::duration deadline)77 		time_limited_delivery_t(
78 			//! Message to be delivered.
79 			message_ref_t message,
80 			//! Time interval for calculation of deadline value.
81 			std::chrono::steady_clock::duration deadline )
82 			:	time_limited_delivery_t{
83 					std::move(message),
84 					std::chrono::steady_clock::now() + deadline }
85 			{}
86 
87 		// Implementation of inherited methods.
88 		void
access_hook(access_context_t,handler_invoker_t & invoker)89 		access_hook(
90 			access_context_t /*context*/,
91 			handler_invoker_t & invoker ) noexcept override
92 			{
93 				if( m_deadline > std::chrono::steady_clock::now() )
94 					invoker.invoke( whole_payload() );
95 			}
96 	};
97 
98 } /* namespace enveloped_msg */
99 
100 } /* namespace extra */
101 
102 } /* namespace so_5 */
103 
104