RatePolicy documentation

This commit is contained in:
Vinnie Falco
2019-02-19 20:29:35 -08:00
parent eaa3d5f975
commit fd4b080a4a
11 changed files with 269 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
Version 217:
* websocket idle pings
* RatePolicy documentation
--------------------------------------------------------------------------------

View File

@@ -19,6 +19,7 @@ This section describes all of the concepts defined by the library.
[include Fields.qbk]
[include FieldsWriter.qbk]
[include File.qbk]
[include RatePolicy.qbk]
[include Streams.qbk]
[endsect]

View File

@@ -0,0 +1,124 @@
[/
Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Official repository: https://github.com/boostorg/beast
]
[section:RatePolicy RatePolicy]
An instance of [*RatePolicy] is associated with a
[link beast.ref.boost__beast__basic_stream `basic_stream`],
and controls the rate at which bytes may be independently sent and
received. This may be used to achieve fine-grained bandwidth management
and flow control.
[heading Associated Types]
* [link beast.ref.boost__beast__rate_policy_access `rate_policy_access`]
[warning
These requirements may undergo non-backward compatible
changes in subsequent versions.
]
[heading Requirements]
In this table:
* `P` denotes a type that meets the requirements of [*RatePolicy].
* `x` denotes an xvalue of type `P`
* `a` denotes a value of type `P`.
* `n` denotes a value of type `std::size_t`
[table Valid expressions
[[Expression] [Type] [Semantics, Pre/Post-conditions]]
[
[`P a(x)`]
[]
[
Requires ['MoveConstructible].
]
][
[`friend rate_policy_access`]
[]
[
The member functions required in `P` should be private.
[link beast.ref.boost__beast__rate_policy_access `rate_policy_access`]
must be a friend of `P` for the implementation to gain access
to the required member functions.
]
][
[`a.available_read_bytes()`]
[`std::size_t`]
[
This function is called by the implementation to determine
the maximum number of allowed bytes to be transferred
in the next read operation. The actual number of bytes
subsequently transferred may be less than this number.
If the policy returns a value of zero, the read operation
will asynchronously wait until the next timer interval
before retrying. When the retry occurs, this function will
be called again.
]
][
[`a.available_write_bytes()`]
[`std::size_t`]
[
This function is called by the implementation to determine
the maximum number of allowed bytes to be transferred
in the next write operation. The actual number of bytes
subsequently transferred may be less than this number.
If the policy returns a value of zero, the read operation
will asynchronously wait until the next timer interval
before retrying. When the retry occurs, this function will
be called again.
]
][
[`a.transfer_read_bytes(n)`]
[]
[
The implementation calls this function to inform the
policy that `n` bytes were successfully transferred
in the most recent read operation. The policy object
may optionally use this information to calculate
throughputs and/or inform the algorithm used to
determine subsequently queried transfer maximums.
]
][
[`a.transfer_write_bytes(n)`]
[]
[
The implementation calls this function to inform the
policy that `n` bytes were successfully transferred
in the most recent write operation. The policy object
may optionally use this information to calculate
throughputs and/or inform the algorithm used to
determine subsequently queried transfer limits.
]
][
[`a.on_timer()`]
[]
[
The implementation calls this function every time the
internal timer expires. The policy object may optionally
use this opportunity to calculate elapsed time and
throughput, and/or inform the algorithm used to
determine subsequently queried transfer limits.
]
]]
[heading Exemplar]
[concept_RatePolicy]
[heading Models]
* [link beast.ref.boost__beast__simple_rate_policy `simple_rate_policy`]
* [link beast.ref.boost__beast__unlimited_rate_policy `unlimited_rate_policy`]
[endsect]

View File

@@ -134,6 +134,8 @@
[import ../../test/doc/core_3_layers.cpp]
[import ../../test/doc/websocket_3_handshake.cpp]
[import ../../test/beast/core/rate_policy.cpp]
[section:quickref Reference]
'''
<emphasis role="green">&#128946;</emphasis> indicates an item that is new in this version.

View File

@@ -104,6 +104,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.concepts.streams.AsyncStream">AsyncStream</link></member>
<member><link linkend="beast.concepts.File">File</link></member>
<member><link linkend="beast.concepts.RatePolicy">RatePolicy</link>&nbsp;<emphasis role="green">&#128946;</emphasis></member>
<member><link linkend="beast.concepts.streams.Stream">Stream</link></member>
<member><link linkend="beast.concepts.streams.SyncStream">SyncStream</link></member>
</simplelist>

View File

@@ -63,6 +63,9 @@
<xsl:when test="type = 'class RangeConnectHandler'">
<xsl:text>class __RangeConnectHandler__</xsl:text>
</xsl:when>
<xsl:when test="type = 'class RatePolicy'">
<xsl:text>class ``[link beast.concepts.RatePolicy [*RatePolicy]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'ReadHandler' or type = 'class ReadHandler'">
<xsl:text>class __ReadHandler__</xsl:text>
</xsl:when>

View File

@@ -239,7 +239,12 @@ private:
template<class... Args>
explicit
impl_type(Args&&...);
impl_type(std::false_type, Args&&...);
template<class RatePolicy_, class... Args>
explicit
impl_type(std::true_type,
RatePolicy_&& policy, Args&&...);
impl_type& operator=(impl_type&&) = delete;
@@ -317,9 +322,43 @@ public:
@param args A list of parameters forwarded to the constructor of
the underlying socket.
*/
#if BOOST_BEAST_DOXYGEN
template<class... Args>
explicit
basic_stream(Args&&... args);
#else
template<class Arg0, class... Args,
class = typename std::enable_if<
! std::is_constructible<RatePolicy, Arg0>::value>::type>
explicit
basic_stream(Arg0&& argo, Args&&... args);
#endif
/** Constructor
This constructor creates the stream with the specified rate
policy, and forwards all remaining arguments to the underlying
socket. The socket then needs to be open and connected or
accepted before data can be sent or received on it.
@param policy The rate policy object to use. The stream will
take ownership of this object by decay-copy.
@param args A list of parameters forwarded to the constructor of
the underlying socket.
*/
#if BOOST_BEAST_DOXYGEN
template<class RatePolicy_, class... Args>
explicit
basic_stream(RatePolicy_&& policy, Args&&... args);
#else
template<class RatePolicy_, class Arg0, class... Args,
class = typename std::enable_if<
std::is_constructible<
RatePolicy, RatePolicy_>::value>::type>
basic_stream(
RatePolicy_&& policy, Arg0&& arg, Args&&... args);
#endif
/** Move constructor

View File

@@ -33,7 +33,7 @@ template<class Protocol, class Executor, class RatePolicy>
template<class... Args>
basic_stream<Protocol, Executor, RatePolicy>::
impl_type::
impl_type(Args&&... args)
impl_type(std::false_type, Args&&... args)
: socket(std::forward<Args>(args)...)
, read(ex())
, write(ex())
@@ -42,6 +42,23 @@ impl_type(Args&&... args)
reset();
}
template<class Protocol, class Executor, class RatePolicy>
template<class RatePolicy_, class... Args>
basic_stream<Protocol, Executor, RatePolicy>::
impl_type::
impl_type(std::true_type,
RatePolicy_&& policy, Args&&... args)
: boost::empty_value<RatePolicy>(
boost::empty_init_t{},
std::forward<RatePolicy_>(policy))
, socket(std::forward<Args>(args)...)
, read(ex())
, write(ex())
, timer(ex())
{
reset();
}
template<class Protocol, class Executor, class RatePolicy>
template<class Executor2>
void
@@ -650,10 +667,25 @@ basic_stream<Protocol, Executor, RatePolicy>::
}
template<class Protocol, class Executor, class RatePolicy>
template<class... Args>
template<class Arg0, class... Args, class>
basic_stream<Protocol, Executor, RatePolicy>::
basic_stream(Args&&... args)
basic_stream(Arg0&& arg0, Args&&... args)
: impl_(boost::make_shared<impl_type>(
std::false_type{},
std::forward<Arg0>(arg0),
std::forward<Args>(args)...))
{
}
template<class Protocol, class Executor, class RatePolicy>
template<class RatePolicy_, class Arg0, class... Args, class>
basic_stream<Protocol, Executor, RatePolicy>::
basic_stream(
RatePolicy_&& policy, Arg0&& arg0, Args&&... args)
: impl_(boost::make_shared<impl_type>(
std::true_type{},
std::forward<RatePolicy_>(policy),
std::forward<Arg0>(arg0),
std::forward<Args>(args)...))
{
}

View File

@@ -102,36 +102,35 @@ private:
*/
class unlimited_rate_policy
{
friend class rate_policy_access;
static std::size_t constexpr all =
(std::numeric_limits<std::size_t>::max)();
private:
friend class rate_policy_access;
std::size_t
available_read_bytes()
available_read_bytes() const noexcept
{
return all;
}
std::size_t
available_write_bytes()
available_write_bytes() const noexcept
{
return all;
}
void
transfer_read_bytes(std::size_t)
transfer_read_bytes(std::size_t) const noexcept
{
}
void
transfer_write_bytes(std::size_t)
transfer_write_bytes(std::size_t) const noexcept
{
}
void
on_timer()
on_timer() const noexcept
{
}
};
@@ -162,13 +161,13 @@ class simple_rate_policy
std::size_t wr_limit_ = all;
std::size_t
available_read_bytes()
available_read_bytes() const noexcept
{
return rd_remain_;
}
std::size_t
available_write_bytes()
available_write_bytes() const noexcept
{
return wr_remain_;
}

View File

@@ -417,6 +417,34 @@ public:
opt = false;
BEAST_EXPECT(! opt.value());
}
// rate policies
{
basic_stream<tcp,
net::io_context::executor_type,
simple_rate_policy> s(ioc);
}
{
basic_stream<tcp,
net::io_context::executor_type,
simple_rate_policy> s(
simple_rate_policy{}, ioc);
}
{
basic_stream<tcp,
net::io_context::executor_type,
unlimited_rate_policy> s(ioc);
}
{
basic_stream<tcp,
net::io_context::executor_type,
unlimited_rate_policy> s(
unlimited_rate_policy{}, ioc);
}
}
class handler

View File

@@ -13,6 +13,31 @@
#include <boost/beast/_experimental/unit_test/suite.hpp>
//[concept_RatePolicy
class RatePolicy
{
friend class rate_policy_access;
static std::size_t constexpr all =
(std::numeric_limits<std::size_t>::max)();
std::size_t
available_read_bytes();
std::size_t
available_write_bytes();
void
transfer_read_bytes(std::size_t);
void
transfer_write_bytes(std::size_t);
void
on_timer();
};
//]
namespace boost {
namespace beast {