|
Boost : |
From: Ruben Perez (rubenperez038_at_[hidden])
Date: 2022-03-31 21:46:04
Hi Marcelo,
Thank you for taking your time to look into the library. Let me explain
inline my design decisions and what can be changed or not.
On Thu, 31 Mar 2022 at 18:14, Marcelo Zimbres Silva via Boost <
boost_at_[hidden]> wrote:
> Hi Ruben,
>
> I have had a look into your library and some questions arise
>
> >
> https://anarthal.github.io/mysql/mysql/ref/boost__mysql__resultset/async_read_all.html
> > The handler signature for this operation is
> void(boost::mysql::error_code, std::vector<boost::mysql::row>).
> > etc.
>
> Having a std::vector in the signature of the completion handler is
> unusual in ASIO. In general large objects should be passed as
> parameters in the async operation e.g. socket::async_read gets a
> dynamic_buffer which is a lightweight view to storage.
>
> Additionally, there is not support for custom allocators. That
> wouldn't be a big problem to me if I could reuse the same memory for
> each request but the interface above prevents me from doing so.
>
The rationale behind that function was to provide an easy-to-use interface.
You can use resultset::async_read_one
<https://anarthal.github.io/mysql/mysql/ref/boost__mysql__resultset/async_read_one.html>
to read rows one-by-one, reusing memory storage
and thus maximizing efficiency.
That being said, I think your point is valid. If the community agrees with
you in this,
I can replace the current resultset::async_read_many
<https://anarthal.github.io/mysql/mysql/ref/boost__mysql__resultset/async_read_many.html>
and resultset::async_read_all
<https://anarthal.github.io/mysql/mysql/ref/boost__mysql__resultset/async_read_all.html>
by functions taking an rvalue reference to a std::vector<rows>. It would be
trivial then
to support vectors with custom allocators.
> >
> https://anarthal.github.io/mysql/mysql/ref/boost__mysql__connection/async_query/overload1.html
> > The handler signature for this operation is
> void(boost::mysql::error_code, boost::mysql::resultset<Stream>)
>
> Hier the completion handler is returning an io object i.e.
> boost::mysql::resultset, which is also unusual as far as I can see.
> Does that play nice with executors? I would prefer having the
> completion handler return config parameters with which I can
> instantiate a boost::mysql::resultset myself in my desired executor.
>
The three I/O objects this library provides (connection, resultset and
prepared_statement)
are just proxies for the underlying Stream I/O object in terms of the
executor (i.e. they
just return the underlying Stream::get_executor() value).
>
> > https://anarthal.github.io/mysql/mysql/ref/boost__mysql__connection.html
>
> I don't see a reason for this class, or at least I fail to see what
> state does the mysql protocol imposes on you that would justify this
> class. I would prefer free funcitions much more here, for example, in
> the same way as beast::http::async_read.
>
The connection object keeps the following protocol state:
- The sequence number. This is an int that gets incremented for each
frame
received and sent by the protocol. Some operations reset this sequence
number
(e.g. query), but others don't (e.g. resultset::read_one).
- The capabilities. This is a bitmask negotiated between client and
server during
handshake, applicable to the lifespan of the connection, and used to
serialize
and deserialize some packages.
- An SSL state flag. This is applicable for SSL-enabled
<https://anarthal.github.io/mysql/mysql/ssl.html#mysql.ssl.streams>
Stream types, only, and is
used to implement SSL negotiation
<https://anarthal.github.io/mysql/mysql/ssl.html#mysql.ssl.negotiation>.
If your Stream supports SSL, then you have
the option to always use it, use it only if the server supports it, or
never use it
(as per the ssl_mode
<https://anarthal.github.io/mysql/mysql/ref/boost__mysql__ssl_mode.html>
option). This is inspired by the official MySQL client
--ssl-mode
<https://dev.mysql.com/doc/refman/8.0/en/connection-options.html#option_general_ssl-mode>
flag. If the negotiation determines that no SSL is to be used,
this fact is kept in the connection object and the next layer to the SSL
stream
object is used for I/O.
Additionally, the connection object also stores a dynamic buffer (based on
a vector<uint8_t>
using the default allocator) to store frames. This buffer is used to
serialize all outgoing
messages, and to store all incoming messages except for rows and metadata
objects.
The connection also instantiates an object of the passed Stream type.
If you are curious about the code, please have a look at the channel
<https://github.com/anarthal/mysql/blob/master/include/boost/mysql/detail/protocol/channel.hpp>
I/O object
(which is not part of the interface, but an internal object that actually
holds the state I mentioned).
A single channel object is created per connection, and connections,
resultsets and prepared_statements
just hold pointers to it.
I know not being able to configure the send/receive buffer is also unusual,
specially when
compared with Beast. I'm not keen on accepting an arbitrary DynamicBuffer
in this context,
as I think optimizing that buffer requires knowledge about the MySQL
protocol, which is better handled
by the library (I'm currently writing a more optimized version of the
buffering strategy that shouldn't
change the library's interface). I'm open to suggestions though.
>
> >
> https://anarthal.github.io/mysql/mysql/ref/boost__mysql__value/get_std_optional.html
> >
> https://anarthal.github.io/mysql/mysql/ref/boost__mysql__value/get_optional.html
>
> Sounds also unusual to have two member functions for the different
> versions of optional.
>
Could you please suggest an alternative?
>
> Regards,
> Marcelo
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
Regards,
Ruben.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk