@@ -31,7 +31,7 @@ namespace aedis {
31
31
*/
32
32
template <class AsyncReadWriteStream = boost::asio::ip::tcp::socket>
33
33
class connection :
34
- public connection_base<
34
+ private connection_base<
35
35
typename AsyncReadWriteStream::executor_type,
36
36
connection<AsyncReadWriteStream>> {
37
37
public:
@@ -40,6 +40,10 @@ class connection :
40
40
41
41
// / Type of the next layer
42
42
using next_layer_type = AsyncReadWriteStream;
43
+ using base_type = connection_base<executor_type, connection<AsyncReadWriteStream>>;
44
+
45
+ // / List of operations that can be canceled.
46
+ using operation = typename base_type::operation;
43
47
44
48
/* * @brief Connection configuration parameters.
45
49
*/
@@ -67,6 +71,9 @@ class connection :
67
71
: connection(ioc.get_executor())
68
72
{ }
69
73
74
+ // / Returns the associated executor.
75
+ auto get_executor () {return stream_.get_executor ();}
76
+
70
77
// / Resets the underlying stream.
71
78
void reset_stream ()
72
79
{
@@ -174,28 +181,117 @@ class connection :
174
181
return base_type::async_run (ep, req, adapter, ts, std::move (token));
175
182
}
176
183
184
+ /* * @brief Executes a command on the Redis server asynchronously.
185
+ *
186
+ * This function will send a request to the Redis server and
187
+ * complete when the response arrives. If the request contains
188
+ * only commands that don't expect a response, the completion
189
+ * occurs after it has been written to the underlying stream.
190
+ * Multiple concurrent calls to this function will be
191
+ * automatically queued by the implementation.
192
+ *
193
+ * @param req Request object.
194
+ * @param adapter Response adapter.
195
+ * @param token Asio completion token.
196
+ *
197
+ * For an example see echo_server.cpp. The completion token must
198
+ * have the following signature
199
+ *
200
+ * @code
201
+ * void f(boost::system::error_code, std::size_t);
202
+ * @endcode
203
+ *
204
+ * Where the second parameter is the size of the response in
205
+ * bytes.
206
+ */
207
+ template <
208
+ class Adapter = detail::response_traits<void >::adapter_type,
209
+ class CompletionToken = boost::asio::default_completion_token_t <executor_type>>
210
+ auto async_exec (
211
+ resp3::request const & req,
212
+ Adapter adapter = adapt(),
213
+ CompletionToken token = CompletionToken{})
214
+ {
215
+ return base_type::async_exec (req, adapter, std::move (token));
216
+ }
217
+
218
+ /* * @brief Receives server side pushes asynchronously.
219
+ *
220
+ * Users that expect server pushes should call this function in a
221
+ * loop. If a push arrives and there is no reader, the connection
222
+ * will hang and eventually timeout.
223
+ *
224
+ * @param adapter The response adapter.
225
+ * @param token The Asio completion token.
226
+ *
227
+ * For an example see subscriber.cpp. The completion token must
228
+ * have the following signature
229
+ *
230
+ * @code
231
+ * void f(boost::system::error_code, std::size_t);
232
+ * @endcode
233
+ *
234
+ * Where the second parameter is the size of the push in
235
+ * bytes.
236
+ */
237
+ template <
238
+ class Adapter = detail::response_traits<void >::adapter_type,
239
+ class CompletionToken = boost::asio::default_completion_token_t <executor_type>>
240
+ auto async_receive_push (
241
+ Adapter adapter = adapt(),
242
+ CompletionToken token = CompletionToken{})
243
+ {
244
+ return base_type::async_receive_push (adapter, std::move (token));
245
+ }
246
+
247
+ /* * @brief Cancel operations.
248
+ *
249
+ * @li `operation::exec`: Cancels operations started with
250
+ * `async_exec`. Has precedence over
251
+ * `request::config::close_on_connection_lost`
252
+ * @li operation::run: Cancels the `async_run` operation. Notice
253
+ * that the preferred way to close a connection is to send a
254
+ * [QUIT](https://redis.io/commands/quit/) command to the server.
255
+ * An unresponsive Redis server will also cause the idle-checks to
256
+ * timeout and lead to `connection::async_run` completing with
257
+ * `error::idle_timeout`. Calling `cancel(operation::run)`
258
+ * directly should be seen as the last option.
259
+ * @li operation::receive_push: Cancels any ongoing callto
260
+ * `async_receive_push`.
261
+ *
262
+ * @param op: The operation to be cancelled.
263
+ * @returns The number of operations that have been canceled.
264
+ */
265
+ auto cancel (operation op) -> std::size_t
266
+ { return base_type::cancel (op); }
267
+
177
268
private:
178
- using base_type = connection_base<executor_type, connection<AsyncReadWriteStream>>;
179
269
using this_type = connection<next_layer_type>;
180
270
181
271
template <class , class > friend class connection_base ;
182
272
template <class , class > friend struct detail ::exec_read_op;
183
273
template <class , class > friend struct detail ::exec_op;
184
274
template <class , class > friend struct detail ::receive_push_op;
185
- template <class > friend struct detail ::ping_op;
186
275
template <class > friend struct detail ::check_idle_op;
187
276
template <class > friend struct detail ::reader_op;
188
277
template <class > friend struct detail ::writer_op;
189
- template <class > friend struct detail ::connect_with_timeout_op;
278
+ template <class , class > friend struct detail ::connect_with_timeout_op;
190
279
template <class > friend struct detail ::run_op;
280
+ template <class > friend struct aedis ::detail::ping_op;
191
281
192
- template <class CompletionToken >
193
- auto async_connect (timeouts ts, CompletionToken&& token)
282
+ template <class Timer , class CompletionToken >
283
+ auto
284
+ async_connect (
285
+ boost::asio::ip::tcp::resolver::results_type const & endpoints,
286
+ timeouts ts,
287
+ Timer& timer,
288
+ CompletionToken&& token)
194
289
{
195
290
return boost::asio::async_compose
196
291
< CompletionToken
197
292
, void (boost::system ::error_code)
198
- >(detail::connect_with_timeout_op<this_type>{this , ts}, token, stream_);
293
+ >(detail::connect_with_timeout_op<this_type, Timer>{this , &endpoints, ts, &timer},
294
+ token, stream_);
199
295
}
200
296
201
297
void close () { stream_.close (); }
0 commit comments