Ben Darnell [Sun, 2 Dec 2018 17:33:07 +0000 (12:33 -0500)]
httpclient: Fix warning logged by sync HTTPClient destructor
If an HTTPClient is closed from its destructor instead of an explicit
close() call, it sometimes logs an "inconsistent AsyncHTTPClient
cache" error because the weakrefs appear to get cleaned up in an
unexpected order. Relax the checks in AsyncHTTPClient.close to allow
for a missing value in the instance cache.
Ben Darnell [Fri, 2 Nov 2018 16:57:09 +0000 (12:57 -0400)]
http1connection: Fix some weird formatting
`black` refused to move the operator across the comment, leaving it
stranded on a line by its own. The most recent version of pycodestyle
complains about this.
Gasper Zejn [Fri, 2 Nov 2018 12:38:22 +0000 (13:38 +0100)]
Add support for source IP address to SimpleAsyncHTTPClient.
Extend support for HTTPRequest's network_interface parameter to
SimpleAsyncHTTPClient. This enables binding to specific local IP and
enables connecting to WebSockets via a specific IP address.
To use it you create a HTTPRequest with network_interface parameter set
to local IP address to be used as source IP. websocket_connect then
passes the request to SimpleAsyncHTTPClient.
Note that even though the parameter name is `network_interface`, the
CurlAsyncHTTPClient may support (OS dependant) passing in interface
name, resolvable hostname or IP address, while this patch only adds
IP address support to SimpleAsyncHTTPClient.
Ben Darnell [Sun, 7 Oct 2018 16:06:52 +0000 (12:06 -0400)]
travis: Run docs CI on py37
We were running it on py36 as a bit of manual bin-packing to optimize
total CI runtime, but sphinx-on-py36 has some bugs in annotation
introspection that we run into.
Ben Darnell [Sun, 7 Oct 2018 03:03:26 +0000 (23:03 -0400)]
*: Adopt black as code formatter
It occasionally makes some odd-looking decisions and uses a lot of
vertical space but overall it's a big improvement, especially for the
dense type signatures.
Ben Darnell [Mon, 1 Oct 2018 02:20:00 +0000 (22:20 -0400)]
websocket: Add type annotations
This is more invasive than usual because it defines a Protocol to be
shared between WebSocketHandler and WebSocketClientConnection (and
fixes a bug: an uncaught exception in the callback mode of
WebSocketClientConnection would fail due to the missing log_exception
method).
Matthew Rocklin [Sun, 16 Sep 2018 20:09:40 +0000 (16:09 -0400)]
Add thread identity check to add_callback (#2469)
* Add thread identity check to add_callback
Fixes #2463
This reduces the overhead of add_callback when called on the same thread
as the event loop. This uses asyncio's call_soon rather than
call_soon_threadsafe.
Ben Darnell [Sat, 11 Aug 2018 16:20:49 +0000 (12:20 -0400)]
build: Test on newer pypy
Originally motivated by segfaults seen when adding type annotations to
gen.py. It didn't actually fix those crashes, but we might as well
update anyway.
Ben Darnell [Sat, 11 Aug 2018 15:27:13 +0000 (11:27 -0400)]
gen: Type annotate the module
This is a tricky module to type. In some cases mypy just isn't able to
express things (e.g. decorators that preserve the parameter types of
their functions but change the return type), and in others I think
it's possible to do better but I haven't figured out how (preserving
types passed through with_timeout).
Ben Darnell [Sat, 11 Aug 2018 16:14:07 +0000 (12:14 -0400)]
test: Deflake autoreload_test on windows
This sometimes fails with a "file in use" error while cleaning up the
temp directory. Add a sleep and retry in case we've reached our
teardown before the child process has released its locks.
Ben Darnell [Sun, 29 Jul 2018 14:25:04 +0000 (10:25 -0400)]
websocket: Improve detection of closing websocket connections
This eliminates the possibility of messages (especially pings) being
sent in the middle of the closing process (which is generally harmless
but results in errors being logged).
Putting getaddrinfo result in a set to eliminate duplicates causes race
conditions because sets are unordered
For example consider 2 applications try to bind to many random ports at once
in both IPV4 and IPV6.
App1: Bind to random IPV4 address and get port 50000
App2: Bind to random IPV6 address and get port 50000
App2: Try to bind to same port on IPV4 and fails as App1 already bound to it
The same goes for App1
To resolve this, we create the set explicitly outside the loop.
We order the returned list of getaddrinfo based on Address family.
We skip the iteration if the iteration tuple already in the set.
Otherwise we execute the loop.