Boost logo

Boost Users :

Subject: [Boost-users] [asio] Advice on implementing rate-limiting for async_write
From: Kyle Ketterer (reminisc3_at_[hidden])
Date: 2018-10-24 22:53:32


Hello fellow Boost friends,

I am looking into some advice on implementing rate-limiting using using
Boost ASIO with async_write. I am working on a Enterprise File Backup
solution named Vessel @ https://github.com/VesselEnterprise/vessel-backup.
My project uses Boost through and through.

The use case is as follows:

   - Many users on the same network/subnet may be transferring files at once
   - I want to add the feature of being able to limit upload speed to the
   storage provider (AWS, Azure, etc)

The request starts as follows: (pseudo code)

Let's say we have a string of 1000 bytes we want to send to a server:

const std::string& request //Passed to member function and make_shared<>()
> to member var on stack to ensure lifetime of async operation

Let's also say we want to limit the transfer speed to 100 bytes/second

size_t transfer_max = 100;

 Should we start the request with async_write() on the socket?

 //Ensure that no more than transfer_max bytes are sent during the first
write

> boost::asio::async_write(*m_socket, boost::asio::buffer(http_request,
> transfer_max), boost::bind(&HttpClient::handle_write, this,
> boost::asio::placeholders::error,
> boost::asio::placeholders::bytes_transferred )) ;
>

Here is where I have questions. In the completion handler
handle_write(...), we need to continue to call async_write() until all
bytes have been written and determine the current transfer rate, and sleep
the thread if necessary. When sending the next set of bytes, is it best to
explicitly declare a buffer and consume or use a pointer to the char array?

void HttpClient::handle_write( const boost::system::error_code& e, size_t
> bytes_transferred )
> {
> /**
> ** Do some stuff here to determine transfer rate, and sleep if
> necessary...
> */
>
> //Pseudocode
> if ( transfer_rate > transfer_max )
> {
> //Possibility 1?
> auto buffer = boost::asio::buffer(request, transfer_max);
> buffer.consume(total_bytes_transferred_so_far);
> boost::asio::async_write(*m_socket, buffer,
> boost::bind(&HttpClient::handle_write, this,
> boost::asio::placeholders::error,
> boost::asio::placeholders::bytes_transferred )) ;
>

    //Possibility 2?
> boost::asio::async_write(*m_socket,
> boost::asio::buffer(&request[total_bytes_transferred_so_far],
> transfer_max), boost::bind(&HttpClient::handle_write, this,
> boost::asio::placeholders::error,
> boost::asio::placeholders::bytes_transferred )) ;
> return;
>
> }
> //...eof
> }

Advice on the topic is greatly appreciated. If I am way off, just let me
know :)

Thanks!

-- 
Kyle Ketterer
<reminisc3_at_[hidden]>


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net