Skip to content
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

Deprecate BlockingTrioPortal in favor of from_thread.run and from_thread.run_sync #1122

Merged
merged 12 commits into from
Jul 21, 2019
2 changes: 1 addition & 1 deletion docs/source/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ Upcoming breaking changes with warnings (i.e., stuff that in 0.2.0

* We took the opportunity to refactor ``run_in_trio_thread`` and
``await_in_trio_thread`` into the new class
:class:`trio.BlockingTrioPortal`
``trio.BlockingTrioPortal``

* The hazmat function ``current_call_soon_thread_and_signal_safe``
is being replaced by :class:`trio.hazmat.TrioToken`
Expand Down
11 changes: 6 additions & 5 deletions docs/source/reference-core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1472,8 +1472,8 @@ for working with real, operating-system level,
:mod:`threading`\-module-style threads. First, if you're in Trio but
need to push some blocking I/O into a thread, there's
:func:`run_sync_in_thread`. And if you're in a thread and need
to communicate back with Trio, you can use a
:class:`BlockingTrioPortal`.
to communicate back with Trio, you can use
:func:`trio.from_thread.run` and :func:`trio.from_thread.run_sync`.


.. _worker-thread-limiting:
Expand Down Expand Up @@ -1611,14 +1611,15 @@ Putting blocking I/O into worker threads
Getting back into the Trio thread from another thread
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: BlockingTrioPortal
:members:
.. autofunction:: trio.from_thread.run

.. autofunction:: trio.from_thread.run_sync

This will probably be clearer with an example. Here we demonstrate how
to spawn a child thread, and then use a :ref:`memory channel
<channels>` to send messages between the thread and a Trio task:

.. literalinclude:: reference-core/blocking-trio-portal-example.py
.. literalinclude:: reference-core/from-thread-example.py


Exceptions and warnings
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import trio

def thread_fn(portal, receive_from_trio, send_to_trio):

def thread_fn(receive_from_trio, send_to_trio):
while True:
# Since we're in a thread, we can't call methods on Trio
# objects directly -- so we use our portal to call them.
try:
request = portal.run(receive_from_trio.receive)
request = trio.from_thread.run(receive_from_trio.receive)
except trio.EndOfChannel:
portal.run(send_to_trio.aclose)
trio.from_thread.run(send_to_trio.aclose)
return
else:
response = request + 1
portal.run(send_to_trio.send, response)
trio.from_thread.run(send_to_trio.send, response)


async def main():
portal = trio.BlockingTrioPortal()
send_to_thread, receive_from_trio = trio.open_memory_channel(0)
send_to_trio, receive_from_thread = trio.open_memory_channel(0)

async with trio.open_nursery() as nursery:
# In a background thread, run:
# thread_fn(portal, receive_from_trio, send_to_trio)
nursery.start_soon(
trio.run_sync_in_thread,
thread_fn, portal, receive_from_trio, send_to_trio
trio.run_sync_in_thread, thread_fn, receive_from_trio, send_to_trio
)

# prints "1"
Expand All @@ -40,4 +40,5 @@ async def main():
# When we exit the nursery, it waits for the background thread to
# exit.


trio.run(main)
4 changes: 2 additions & 2 deletions docs/source/reference-hazmat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,11 @@ These transitions are accomplished using two function decorators:
function).

An example of where you'd use this is in implementing something
like :meth:`trio.BlockingTrioPortal.run`, which uses
like :func:`trio.from_thread.run`, which uses
:meth:`TrioToken.run_sync_soon` to get into the Trio
thread. :meth:`~TrioToken.run_sync_soon` callbacks are run with
:exc:`KeyboardInterrupt` protection enabled, and
:meth:`~trio.BlockingTrioPortal.run` takes advantage of this to safely set up
:func:`trio.from_thread.run` takes advantage of this to safely set up
the machinery for sending a response back to the original thread, but
then uses :func:`disable_ki_protection` when entering the
user-provided function.
Expand Down
14 changes: 11 additions & 3 deletions trio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@
Event, CapacityLimiter, Semaphore, Lock, StrictFIFOLock, Condition
)

from ._threads import (
run_sync_in_thread, current_default_thread_limiter, BlockingTrioPortal
)
from ._threads import (run_sync_in_thread, current_default_thread_limiter)
from ._threads import BlockingTrioPortal as _BlockingTrioPortal

from ._highlevel_generic import aclose_forcefully, StapledStream

Expand Down Expand Up @@ -72,6 +71,7 @@
from . import hazmat
from . import socket
from . import abc
from . import from_thread
# Not imported by default: testing
if False:
from . import testing
Expand Down Expand Up @@ -142,6 +142,13 @@
"0.12.0",
issue=878,
),
"BlockingTrioPortal":
_deprecate.DeprecatedAttribute(
_BlockingTrioPortal,
"0.12.0",
issue=810,
instead=from_thread,
),
}

# Having the public path in .__module__ attributes is important for:
Expand All @@ -155,6 +162,7 @@
fixup_module_metadata(hazmat.__name__, hazmat.__dict__)
fixup_module_metadata(socket.__name__, socket.__dict__)
fixup_module_metadata(abc.__name__, abc.__dict__)
fixup_module_metadata(from_thread.__name__, from_thread.__dict__)
fixup_module_metadata(__name__ + ".ssl", _deprecated_ssl_reexports.__dict__)
fixup_module_metadata(
__name__ + ".subprocess", _deprecated_subprocess_reexports.__dict__
Expand Down
2 changes: 1 addition & 1 deletion trio/_core/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class TrioInternalError(Exception):


class RunFinishedError(RuntimeError):
"""Raised by `BlockingTrioPortal.run` and similar functions if the
"""Raised by `trio.from_thread.run` and similar functions if the
corresponding call to :func:`trio.run` has already finished.

"""
Expand Down
Loading