Drop 'fork' (#619)

This commit is contained in:
Tom Christie 2019-12-08 19:52:46 +00:00 committed by GitHub
parent 83fc0921c1
commit eba29da632
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1 additions and 113 deletions

View File

@ -268,28 +268,6 @@ class AsyncioBackend(ConcurrencyBackend):
finally:
self._loop = loop
async def fork(
self,
coroutine1: typing.Callable,
args1: typing.Sequence,
coroutine2: typing.Callable,
args2: typing.Sequence,
) -> None:
task1 = self.loop.create_task(coroutine1(*args1))
task2 = self.loop.create_task(coroutine2(*args2))
try:
await asyncio.gather(task1, task2)
finally:
pending: typing.Set[asyncio.Future[typing.Any]] # Please mypy.
_, pending = await asyncio.wait({task1, task2}, timeout=0)
for task in pending:
task.cancel()
try:
await task
except asyncio.CancelledError:
pass
def get_semaphore(self, limits: PoolLimits) -> BasePoolSemaphore:
return PoolSemaphore(limits)

View File

@ -51,12 +51,3 @@ class AutoBackend(ConcurrencyBackend):
def create_event(self) -> BaseEvent:
return self.backend.create_event()
async def fork(
self,
coroutine1: typing.Callable,
args1: typing.Sequence,
coroutine2: typing.Callable,
args2: typing.Sequence,
) -> None:
return await self.backend.fork(coroutine1, args1, coroutine2, args2)

View File

@ -120,21 +120,3 @@ class ConcurrencyBackend:
def create_event(self) -> BaseEvent:
raise NotImplementedError() # pragma: no cover
async def fork(
self,
coroutine1: typing.Callable,
args1: typing.Sequence,
coroutine2: typing.Callable,
args2: typing.Sequence,
) -> None:
"""
Run two coroutines concurrently.
This should start 'coroutine1' with '*args1' and 'coroutine2' with '*args2',
and wait for them to finish.
In case one of the coroutines raises an exception, cancel the other one then
raise. If the other coroutine had also raised an exception, ignore it.
"""
raise NotImplementedError() # pragma: no cover

View File

@ -168,22 +168,6 @@ class TrioBackend(ConcurrencyBackend):
functools.partial(coroutine, **kwargs) if kwargs else coroutine, *args
)
async def fork(
self,
coroutine1: typing.Callable,
args1: typing.Sequence,
coroutine2: typing.Callable,
args2: typing.Sequence,
) -> None:
try:
async with trio.open_nursery() as nursery:
nursery.start_soon(coroutine1, *args1)
nursery.start_soon(coroutine2, *args2)
except trio.MultiError as exc:
# In practice, we don't actually care about raising both
# exceptions, so let's raise either indeterminantly.
raise exc.exceptions[0]
def get_semaphore(self, limits: PoolLimits) -> BasePoolSemaphore:
return PoolSemaphore(limits)

View File

@ -8,7 +8,7 @@ from httpx.concurrency.asyncio import AsyncioBackend
from httpx.concurrency.base import lookup_backend
from httpx.concurrency.trio import TrioBackend
from httpx.config import SSLConfig
from tests.concurrency import get_cipher, run_concurrently, sleep
from tests.concurrency import get_cipher, run_concurrently
async def read_response(stream, timeout: Timeout, should_contain: bytes) -> bytes:
@ -99,53 +99,6 @@ async def test_concurrent_read(server, backend):
await stream.close()
async def test_fork(backend):
backend = lookup_backend(backend)
ok_counter = 0
async def ok(delay: int) -> None:
nonlocal ok_counter
await sleep(backend, delay)
ok_counter += 1
async def fail(message: str, delay: int) -> None:
await sleep(backend, delay)
raise RuntimeError(message)
await backend.fork(ok, [0], ok, [0])
assert ok_counter == 2
with pytest.raises(RuntimeError, match="Oops"):
await backend.fork(ok, [0], fail, ["Oops", 0.01])
assert ok_counter == 3
with pytest.raises(RuntimeError, match="Oops"):
await backend.fork(ok, [0.01], fail, ["Oops", 0])
assert ok_counter == 3
with pytest.raises(RuntimeError, match="Oops"):
await backend.fork(fail, ["Oops", 0.01], ok, [0])
assert ok_counter == 4
with pytest.raises(RuntimeError, match="Oops"):
await backend.fork(fail, ["Oops", 0], ok, [0.01])
assert ok_counter == 4
with pytest.raises(RuntimeError, match="My bad"):
await backend.fork(fail, ["My bad", 0], fail, ["Oops", 0.01])
with pytest.raises(RuntimeError, match="Oops"):
await backend.fork(fail, ["My bad", 0.01], fail, ["Oops", 0])
# No 'match', since we can't know which will be raised first.
with pytest.raises(RuntimeError):
await backend.fork(fail, ["My bad", 0], fail, ["Oops", 0])
def test_lookup_backend():
assert isinstance(lookup_backend("asyncio"), AsyncioBackend)
assert isinstance(lookup_backend("trio"), TrioBackend)