Skip to content

Commit a73d403

Browse files
committed
Remove flush and close, change write semantics
With this commit we're changing the rules a little bit. The idea is a write should immediately copy the range, linearize it in batches, and schedule asynchronous writes in the process. In case there are any errors encountered, this is reported to the handler primarily through a mechanism like a function call to an explicit error handler in the function. In later revisions, it may be deemed that all calls to write should take a completion handler function that takes an error code. This might make the asynchronous handler programming a little more cumbersome, but will open up doors to more powerful handler implementations.
1 parent 6b940f2 commit a73d403

File tree

2 files changed

+27
-25
lines changed

2 files changed

+27
-25
lines changed

boost/network/protocol/http/server/async_connection.hpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@
1717
#include <boost/asio/buffer.hpp>
1818
#include <iterator>
1919

20+
#ifndef BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE
21+
/** Here we define a page's worth of header connection buffer data.
22+
* This can be tuned to reduce the memory cost of connections, but this
23+
* default size is set to be friendly to typical service applications.
24+
* This is the maximum size though and Boost.Asio's internal representation
25+
* of a streambuf would make appropriate decisions on how big a buffer
26+
* is to begin with.
27+
*/
28+
#define BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE 4096
29+
#endif /* BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE */
30+
2031
namespace boost { namespace network { namespace http {
2132

2233
template <class Tag, class Handler>
@@ -51,31 +62,31 @@ namespace boost { namespace network { namespace http {
5162
, strand(io_service)
5263
, handler(handler)
5364
, thread_pool_(thread_pool)
54-
, headers_already_set(false)
65+
, headers_already_sent(false)
66+
, headers_buffer(BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE)
5567
{}
5668

5769
/** Function: template <class Range> set_headers(Range headers)
58-
* Precondition: headers have not been set yet
59-
* Postcondition: headers have been set, and cannot be modified anymore.
60-
* Throws: std::logic_error in case the headers have already been set
61-
* and the precondition is not satisfied.
70+
* Precondition: headers have not been sent yet
71+
* Postcondition: headers have been linearized to a buffer.
72+
* Throws: std::logic_error in case the headers have already been sent.
6273
*
6374
* A call to set_headers takes a Range where each element models the
6475
* Header concept. This Range will be linearized onto a buffer, which is
6576
* then sent as soon as the first call to `write` or `flush` commences.
6677
*/
6778
template <class Range>
6879
void set_headers(Range headers) {
69-
if (headers_already_set)
70-
boost::throw_exception(std::logic_error("Headers have already been set."));
80+
if (headers_already_sent)
81+
boost::throw_exception(std::logic_error("Headers have already been sent."));
7182

7283
bool commit = false;
73-
BOOST_SCOPE_EXIT_TPL((&commit)(&headers_already_set)) {
74-
if (!commit) headers_already_set = false;
84+
BOOST_SCOPE_EXIT_TPL((&commit)(&headers_already_sent)) {
85+
if (!commit) headers_already_sent = false;
7586
} BOOST_SCOPE_EXIT_END
7687

7788
typedef constants<Tag> consts;
78-
89+
headers_buffer.consume(headers_buffer.size());
7990
std::ostream stream(&headers_buffer);
8091
if (!boost::empty(headers)) {
8192
typedef typename Range::const_iterator iterator;
@@ -88,7 +99,7 @@ namespace boost { namespace network { namespace http {
8899
stream << consts::crlf();
89100
}
90101
stream << consts::crlf();
91-
commit = headers_already_set = true;
102+
commit = true;
92103
}
93104

94105
void set_status(status_t new_status) {
@@ -97,21 +108,14 @@ namespace boost { namespace network { namespace http {
97108

98109
template <class Range>
99110
void write(Range) {
111+
if (!headers_already_sent) {
112+
// TODO write out the headers that are already
113+
// linearized to the headers_buffer.
114+
}
100115
// linearize the range into a shared array
101116
// schedule a stranded asynchronous write
102117
}
103118

104-
void flush() {
105-
// use this as a synchronization point to ensure
106-
// that data has been written; use a unique_future
107-
}
108-
109-
void close() {
110-
flush();
111-
socket_.shutdown(asio::ip::tcp::socket::shutdown_both);
112-
socket_.close();
113-
}
114-
115119
asio::ip::tcp::socket & socket() { return socket_; }
116120
utils::thread_pool & thread_pool() { return thread_pool_; }
117121

@@ -120,7 +124,7 @@ namespace boost { namespace network { namespace http {
120124
asio::io_service::strand strand;
121125
Handler & handler;
122126
utils::thread_pool & thread_pool_;
123-
bool headers_already_set;
127+
bool headers_already_sent;
124128
asio::streambuf headers_buffer;
125129

126130
typedef boost::array<char, BOOST_NETWORK_HTTP_SERVER_CONNECTION_BUFFER_SIZE>

libs/network/test/http_async_server.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ struct async_hello_world {
3030
connection.set_status(server::connection::ok);
3131
connection.write("Hello, World!");
3232
}
33-
connection.flush();
34-
connection.close();
3533
}
3634
};
3735

0 commit comments

Comments
 (0)