27
27
#include < boost/assert.hpp>
28
28
#include < boost/core/ignore_unused.hpp>
29
29
#include < boost/asio/ssl/stream.hpp>
30
+ #include < boost/asio/read_until.hpp>
31
+ #include < boost/asio/buffer.hpp>
30
32
31
33
#include < algorithm>
32
34
#include < array>
33
35
#include < chrono>
34
36
#include < deque>
35
- #include < limits>
36
37
#include < memory>
37
38
#include < string_view>
38
39
#include < type_traits>
@@ -112,10 +113,13 @@ class read_next_op {
112
113
// some data in the read bufer.
113
114
if (conn_->read_buffer_ .empty ()) {
114
115
115
- if (conn_->use_ssl ())
116
- BOOST_ASIO_CORO_YIELD asio::async_read_until (conn_->next_layer (), conn_->make_dynamic_buffer (), " \r\n " , std::move (self));
117
- else
118
- BOOST_ASIO_CORO_YIELD asio::async_read_until (conn_->next_layer ().next_layer (), conn_->make_dynamic_buffer (), " \r\n " , std::move (self));
116
+ if (conn_->use_ssl ()) {
117
+ BOOST_ASIO_CORO_YIELD
118
+ asio::async_read_until (conn_->next_layer (), conn_->dbuf_ , resp3::parser::sep, std::move (self));
119
+ } else {
120
+ BOOST_ASIO_CORO_YIELD
121
+ asio::async_read_until (conn_->next_layer ().next_layer (), conn_->dbuf_ , resp3::parser::sep, std::move (self));
122
+ }
119
123
120
124
BOOST_REDIS_CHECK_OP1 (conn_->cancel (operation::run););
121
125
if (info_->stop_requested ()) {
@@ -134,10 +138,13 @@ class read_next_op {
134
138
}
135
139
// -----------------------------------
136
140
137
- if (conn_->use_ssl ())
138
- BOOST_ASIO_CORO_YIELD redis::detail::async_read (conn_->next_layer (), conn_->make_dynamic_buffer (), make_adapter (), std::move (self));
139
- else
140
- BOOST_ASIO_CORO_YIELD redis::detail::async_read (conn_->next_layer ().next_layer (), conn_->make_dynamic_buffer (), make_adapter (), std::move (self));
141
+ if (conn_->use_ssl ()) {
142
+ BOOST_ASIO_CORO_YIELD
143
+ redis::detail::async_read (conn_->next_layer (), conn_->dbuf_ , make_adapter (), std::move (self));
144
+ } else {
145
+ BOOST_ASIO_CORO_YIELD
146
+ redis::detail::async_read (conn_->next_layer ().next_layer (), conn_->dbuf_ , make_adapter (), std::move (self));
147
+ }
141
148
142
149
++index_;
143
150
@@ -147,6 +154,7 @@ class read_next_op {
147
154
return ;
148
155
}
149
156
157
+ conn_->dbuf_ .consume (n);
150
158
read_size_ += n;
151
159
152
160
BOOST_ASSERT (cmds_ != 0 );
@@ -162,7 +170,6 @@ template <class Conn, class Adapter>
162
170
struct receive_op {
163
171
Conn* conn_;
164
172
Adapter adapter;
165
- std::size_t read_size = 0 ;
166
173
asio::coroutine coro{};
167
174
168
175
template <class Self >
@@ -182,10 +189,13 @@ struct receive_op {
182
189
}
183
190
}
184
191
185
- if (conn_->use_ssl ())
186
- BOOST_ASIO_CORO_YIELD redis::detail::async_read (conn_->next_layer (), conn_->make_dynamic_buffer (), adapter, std::move (self));
187
- else
188
- BOOST_ASIO_CORO_YIELD redis::detail::async_read (conn_->next_layer ().next_layer (), conn_->make_dynamic_buffer (), adapter, std::move (self));
192
+ if (conn_->use_ssl ()) {
193
+ BOOST_ASIO_CORO_YIELD
194
+ redis::detail::async_read (conn_->next_layer (), conn_->dbuf_ , adapter, std::move (self));
195
+ } else {
196
+ BOOST_ASIO_CORO_YIELD
197
+ redis::detail::async_read (conn_->next_layer ().next_layer (), conn_->dbuf_ , adapter, std::move (self));
198
+ }
189
199
190
200
if (ec || is_cancelled (self)) {
191
201
conn_->cancel (operation::run);
@@ -194,13 +204,13 @@ struct receive_op {
194
204
return ;
195
205
}
196
206
197
- read_size = n ;
207
+ conn_-> dbuf_ . consume (n) ;
198
208
199
209
if (!conn_->is_next_push ()) {
200
210
conn_->read_op_timer_ .cancel ();
201
211
}
202
212
203
- self.complete ({}, read_size );
213
+ self.complete ({}, n );
204
214
return ;
205
215
}
206
216
}
@@ -214,7 +224,6 @@ struct exec_op {
214
224
request const * req = nullptr ;
215
225
Adapter adapter{};
216
226
std::shared_ptr<req_info_type> info = nullptr ;
217
- std::size_t read_size = 0 ;
218
227
asio::coroutine coro{};
219
228
220
229
template <class Self >
@@ -283,8 +292,6 @@ struct exec_op {
283
292
conn->async_read_next (adapter, std::move (self));
284
293
BOOST_REDIS_CHECK_OP1 (;);
285
294
286
- read_size = n;
287
-
288
295
if (info->stop_requested ()) {
289
296
// Don't have to call remove_request as it has already
290
297
// been by cancel(exec).
@@ -301,7 +308,7 @@ struct exec_op {
301
308
conn->read_timer_ .cancel_one ();
302
309
}
303
310
304
- self.complete ({}, read_size );
311
+ self.complete ({}, n );
305
312
}
306
313
}
307
314
};
@@ -417,9 +424,9 @@ struct reader_op {
417
424
BOOST_ASIO_CORO_REENTER (coro) for (;;)
418
425
{
419
426
if (conn->use_ssl ())
420
- BOOST_ASIO_CORO_YIELD asio::async_read_until (conn->next_layer (), conn->make_dynamic_buffer () , " \r\n " , std::move (self));
427
+ BOOST_ASIO_CORO_YIELD asio::async_read_until (conn->next_layer (), conn->dbuf_ , " \r\n " , std::move (self));
421
428
else
422
- BOOST_ASIO_CORO_YIELD asio::async_read_until (conn->next_layer ().next_layer (), conn->make_dynamic_buffer () , " \r\n " , std::move (self));
429
+ BOOST_ASIO_CORO_YIELD asio::async_read_until (conn->next_layer ().next_layer (), conn->dbuf_ , " \r\n " , std::move (self));
423
430
424
431
if (ec == asio::error::eof) {
425
432
conn->cancel (operation::run);
@@ -491,25 +498,23 @@ class connection_base {
491
498
using this_type = connection_base<Executor>;
492
499
493
500
// / Constructs from an executor.
494
- connection_base (executor_type ex, asio::ssl::context::method method = asio::ssl::context::tls_client)
501
+ connection_base (
502
+ executor_type ex,
503
+ asio::ssl::context::method method,
504
+ std::size_t max_read_size)
495
505
: ctx_{method}
496
506
, stream_{std::make_unique<next_layer_type>(ex, ctx_)}
497
507
, writer_timer_{ex}
498
508
, read_timer_{ex}
499
509
, read_op_timer_{ex}
500
510
, runner_{ex, {}}
511
+ , dbuf_{read_buffer_, max_read_size}
501
512
{
502
513
writer_timer_.expires_at (std::chrono::steady_clock::time_point::max ());
503
514
read_timer_.expires_at (std::chrono::steady_clock::time_point::max ());
504
515
read_op_timer_.expires_at (std::chrono::steady_clock::time_point::max ());
505
516
}
506
517
507
- // / Contructs from an execution context.
508
- explicit
509
- connection_base (asio::io_context& ioc, asio::ssl::context::method method = asio::ssl::context::tls_client)
510
- : connection_base(ioc.get_executor(), method)
511
- { }
512
-
513
518
// / Returns the ssl context.
514
519
auto const & get_ssl_context () const noexcept
515
520
{ return ctx_;}
@@ -547,15 +552,8 @@ class connection_base {
547
552
cancel_impl (op);
548
553
}
549
554
550
- template <
551
- class Response = ignore_t ,
552
- class CompletionToken = asio::default_completion_token_t <executor_type>
553
- >
554
- auto
555
- async_exec (
556
- request const & req,
557
- Response& resp = ignore,
558
- CompletionToken token = CompletionToken{})
555
+ template <class Response , class CompletionToken >
556
+ auto async_exec (request const & req, Response& resp, CompletionToken token)
559
557
{
560
558
using namespace boost ::redis::adapter;
561
559
auto f = boost_redis_adapt (resp);
@@ -567,14 +565,8 @@ class connection_base {
567
565
>(redis::detail::exec_op<this_type, decltype (f)>{this , &req, f}, token, writer_timer_);
568
566
}
569
567
570
- template <
571
- class Response = ignore_t ,
572
- class CompletionToken = asio::default_completion_token_t <executor_type>
573
- >
574
- auto
575
- async_receive (
576
- Response& response,
577
- CompletionToken token = CompletionToken{})
568
+ template <class Response , class CompletionToken >
569
+ auto async_receive (Response& response, CompletionToken token)
578
570
{
579
571
using namespace boost ::redis::adapter;
580
572
auto g = boost_redis_adapt (response);
@@ -594,15 +586,6 @@ class connection_base {
594
586
return runner_.async_run (*this , l, std::move (token));
595
587
}
596
588
597
- void set_max_buffer_read_size (std::size_t max_read_size) noexcept
598
- {max_read_size_ = max_read_size;}
599
-
600
- void reserve (std::size_t read, std::size_t write)
601
- {
602
- read_buffer_.reserve (read);
603
- write_buffer_.reserve (write);
604
- }
605
-
606
589
private:
607
590
using clock_type = std::chrono::steady_clock;
608
591
using clock_traits_type = asio::wait_traits<clock_type>;
@@ -839,9 +822,6 @@ class connection_base {
839
822
writer_timer_.cancel ();
840
823
}
841
824
842
- auto make_dynamic_buffer ()
843
- { return asio::dynamic_buffer (read_buffer_, max_read_size_); }
844
-
845
825
template <class CompletionToken >
846
826
auto reader (CompletionToken&& token)
847
827
{
@@ -927,10 +907,12 @@ class connection_base {
927
907
timer_type read_op_timer_;
928
908
runner_type runner_;
929
909
910
+ using dyn_buffer_type = asio::dynamic_string_buffer<char , std::char_traits<char >, std::allocator<char >>;
911
+
930
912
std::string read_buffer_;
913
+ dyn_buffer_type dbuf_;
931
914
std::string write_buffer_;
932
915
reqs_type reqs_;
933
- std::size_t max_read_size_ = (std::numeric_limits<std::size_t >::max)();
934
916
};
935
917
936
918
} // boost::redis::detail
0 commit comments