-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libevent-based http server #2176
Conversation
Based on #2175, merge that first. |
How sure are we that this resolves #1680? |
@str4d Just checking, allmention/trace of rpckeepalive has been removed? Are there libevent improvements to backport? @daira So from empirical testing with local scripts which make repeated calls to the RPC interface, this libevent based server appears faster, but the python scripts will report I'm fine with merging this. |
@bitcartel wrote:
Yes.
Ooh, yes I have now spotted a couple of additional PRs. I will add them to this PR. |
a93d092
to
5779978
Compare
@bitcartel it expanded from a "couple" of PRs 😅 Most of the additional PRs are trivial, but we can always split off a few into 1.0.9 if necessary. |
@zkbot try |
libevent-based http server Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#5677 - bitcoin/bitcoin#6695 - bitcoin/bitcoin#6899 - bitcoin/bitcoin#7016 - bitcoin/bitcoin#7964 - bitcoin/bitcoin#8722 - bitcoin/bitcoin#8730 - bitcoin/bitcoin#9073 - bitcoin/bitcoin#9265 - bitcoin/bitcoin#9387 - bitcoin/bitcoin#9471 - bitcoin/bitcoin#9647 - bitcoin/bitcoin#9903 Closes #1593 and #1856.
☀️ Test successful - zcash |
…rom upstream." This reverts commit f4404d7.
This option was a temporary workaround, and is no longer necessary with the new web server.
Dropping all use of boost::asio.
Sending a request body with GET request is not valid in HTTP spec, and not compatible with evhttpd.
- *Replace usage of boost::asio with [libevent2](http://libevent.org/)*. boost::asio is not part of C++11, so unlike other boost there is no forwards-compatibility reason to stick with it. Together with zcash#4738 (convert json_spirit to UniValue), this rids Bitcoin Core of the worst offenders with regard to compile-time slowness. - *Replace spit-and-duct-tape http server with evhttp*. Front-end http handling is handled by libevent, a work queue (with configurable depth and parallelism) is used to handle application requests. - *Wrap HTTP request in C++ class*; this makes the application code mostly HTTP-server-neutral - *Refactor RPC to move all http-specific code to a separate file*. Theoreticaly this can allow building without HTTP server but with another RPC backend, e.g. Qt's debug console (currently not implemented) or future RPC mechanisms people may want to use. - *HTTP dispatch mechanism*; services (e.g., RPC, REST) register which URL paths they want to handle. By using a proven, high-performance asynchronous networking library (also used by Tor) and HTTP server, problems such as zcash#5674, zcash#5655, zcash#344 should be avoided. What works? bitcoind, bitcoin-cli, bitcoin-qt. Unit tests and RPC/REST tests pass. The aim for now is everything but SSL support. Configuration options: - `-rpcthreads`: repurposed as "number of work handler threads". Still defaults to 4. - `-rpcworkqueue`: maximum depth of work queue. When this is reached, new requests will return a 500 Internal Error. - `-rpctimeout`: inactivity time, in seconds, after which to disconnect a client. - `-debug=http`: low-level http activity logging
Implement RPCTimerHandler for Qt RPC console, so that `walletpassphrase` works with GUI and `-server=0`. Also simplify HTTPEvent-related code by using boost::function directly. Zcash: QT changes ommitted
…entBase() Split StartHTTPServer into InitHTTPServer and StartHTTPServer to give clients a window to register their handlers without race conditions. Thanks @ajweiss for figuring this out.
Make it possible to reuse sockets. This is necessary to make the RPC tests work in WINE.
Rebased on master. This PR now only contains the libevent commits, but annoyingly GitHub now shows them in date order instead of branch order... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please respond to comments.
qa/pull-tester/rpc-tests.sh
Outdated
if [ "x${EXEEXT}" = "x.exe" ]; then | ||
echo "Win tests currently disabled" | ||
exit 0 | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh. I'd prefer to let them fail on Windows than disable them. Was there any other upstream PR to fix them for Windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, they are still disabled by default upstream, and bitcoin/bitcoin#5677 (comment) is referenced as the reason for disabling. In upstream's migration of this script from Bash to Python (bitcoin/bitcoin#6616), an override flag was added, so we will gain that as well once I pull that in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yuck. I don't want to hide the fact that these tests are failing on Windows. Please revert the disabling.
self.__conn.request(method, path, postdata, headers) | ||
return self._get_response() | ||
except httplib.BadStatusLine as e: | ||
if e.line == "''": # if connection was closed, try again |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having read https://bugs.python.org/issue356 , I'm not sure this will actually work in Python 3.5+, because that will throw a ConnectionResetError
which, while it does inherit from BadStatusLine
, does not necessarily have e.line == "''"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we also want bitcoin/bitcoin#8139 and bitcoin/bitcoin#8839.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm feeling quite smug about spotting that it wouldn't work just from reading the Python issue :-) 👍 on including those PRs.
$(LIBZCASH) \ | ||
$(LIBBITCOIN_CRYPTO) \ | ||
$(LIBZCASH_LIBS) | ||
|
||
# bitcoin-cli binary # | ||
zcash_cli_SOURCES = bitcoin-cli.cpp | ||
zcash_cli_CPPFLAGS = $(BITCOIN_INCLUDES) | ||
zcash_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not also $(EVENT_PTHREADS_CFLAGS)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked with upstream, and they don't have $(EVENT_PTHREADS_CFLAGS)
in current master, so unlikely I made a mistake while cherry-picking. I wouldn't expect it to be necessary anyway, as the threading side should only be needed in zcashd
.
const char *http_errorstring(int code) | ||
{ | ||
switch(code) { | ||
#if LIBEVENT_VERSION_NUMBER >= 0x02010300 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know the version is always at least this, so the conditional compilation is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK; I'd like to address this in a separate PR so we can also send it upstream.
} | ||
} | ||
|
||
#if LIBEVENT_VERSION_NUMBER >= 0x02010300 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional compilation is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
#ifndef EVENT_LOG_WARN | ||
// EVENT_LOG_WARN was added in 2.0.19; but before then _EVENT_LOG_WARN existed. | ||
# define EVENT_LOG_WARN _EVENT_LOG_WARN | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional block is unnecessary; we should always be using libevent >= 2.0.19.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #2176 (comment)
|
||
// Redirect libevent's logging to our own log | ||
event_set_log_callback(&libevent_log_cb); | ||
#if LIBEVENT_VERSION_NUMBER >= 0x02010100 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditional compilation unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #2176 (comment)
src/httpserver.cpp
Outdated
break; | ||
if (i != iend) | ||
{ | ||
LogPrint("http", "Unregistering HTTP handler for %s (exactmath %d)\n", prefix, exactMatch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: s/exactmath/exactmatch/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll pull in bitcoin/bitcoin#6640.
* nStatus is the HTTP status code to send. | ||
* strReply is the body of the reply. Keep it empty to send a standard message. | ||
* | ||
* @note Can be called only once. As this will give the request back to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really calls out for session types. Oh well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a ticket we can open, or is this a missing language feature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing language feature. I was just griping about C++'s inexpressiveness.
src/rpcserver.h
Outdated
* RPC will call the function to create a timer that will call func in *millis* milliseconds. | ||
* @note As the RPC mechanism is backend-neutral, it can use different implementations of timers. | ||
* This is needed to cope with the case in which there is no HTTP server, but | ||
* only GUI RPC console, and to break the dependency of pcserver on httprpc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: s/pcserver/rpcserver/
... but not yet in trivial tree
This is necessary on FreeBSD and MacOSX, at least. See bitcoin/bitcoin#8834 (comment)
@daira comments responded to, and mostly addressed (just waiting on #2176 (comment) and #2176 (comment)). |
Please revert the disabling of RPC tests on Windows, and fix the "pcserver" typo. Otherwise utACK. |
This reverts commit 7fd5d4e. We need to un-revert this before pulling in bitcoin/bitcoin#6616
This is a fantastic cherry-pick, I'm ACK. Nice and clean. |
ACK @zkbot r+ |
📌 Commit 3da13e8 has been approved by |
libevent-based http server Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#5677 - bitcoin/bitcoin#6695 - bitcoin/bitcoin#6899 - bitcoin/bitcoin#7016 - bitcoin/bitcoin#7964 - bitcoin/bitcoin#8722 - bitcoin/bitcoin#8730 - bitcoin/bitcoin#9073 - bitcoin/bitcoin#9265 - bitcoin/bitcoin#9387 - bitcoin/bitcoin#9471 - bitcoin/bitcoin#9647 - bitcoin/bitcoin#9903 - bitcoin/bitcoin#6640 - bitcoin/bitcoin#8139 - bitcoin/bitcoin#8839 Closes #1593 and #1856.
☀️ Test successful - zcash |
Post-hoc utACK for the last three commits. |
Cherry-picked from the following upstream PRs:
Closes #1593 and #1856.