Skip to content

Commit 34f9788

Browse files
author
Chris Rossi
authored
Implement get_event_loop. (googleapis#6456)
Implement `get_event_loop`.
1 parent 07ab8a0 commit 34f9788

3 files changed

Lines changed: 50 additions & 11 deletions

File tree

ndb/src/google/cloud/ndb/_eventloop.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import threading
2222
import time
2323

24+
from google.cloud.ndb import exceptions
25+
2426
__all__ = [
2527
"add_idle",
2628
"async_context",
@@ -304,8 +306,9 @@ def async_context():
304306
context. Upon exiting the context, execution will block until all
305307
asynchronous calls loaded onto the event loop have finished execution.
306308
307-
Code within an asynchronous context should be single threaded. Internally, a
308-
:class:`threading.local` instance is used to track the current event loop.
309+
Code within an asynchronous context should be single threaded. Internally,
310+
a :class:`threading.local` instance is used to track the current event
311+
loop.
309312
310313
In the context of a web application, it is recommended that a single
311314
asynchronous context be used per HTTP request. This can typically be
@@ -321,11 +324,28 @@ def async_context():
321324
contexts.pop()
322325

323326

324-
def add_idle(*args, **kwargs):
325-
raise NotImplementedError
327+
def get_event_loop():
328+
"""Get the current event loop.
326329
330+
This function should be called within a context established by
331+
:func:`google.cloud.ndb.async_context`.
327332
328-
def get_event_loop(*args, **kwargs):
333+
Returns:
334+
EventLoop: The event loop for the current
335+
context.
336+
337+
Raises:
338+
exceptions.AsyncContextError: If called outside of a context
339+
established by :func:`google.cloud.ndb.async_context`.
340+
"""
341+
loop = contexts.current()
342+
if loop:
343+
return loop
344+
345+
raise exceptions.AsyncContextError()
346+
347+
348+
def add_idle(*args, **kwargs):
329349
raise NotImplementedError
330350

331351

ndb/src/google/cloud/ndb/exceptions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
__all__ = [
2424
"Error",
25+
"AsyncContextError",
2526
"BadValueError",
2627
"BadArgumentError",
2728
"Rollback",
@@ -33,6 +34,20 @@ class Error(Exception):
3334
"""Base datastore error type."""
3435

3536

37+
class AsyncContextError(Error):
38+
"""Indicates an async call being made without a context.
39+
40+
Raised whenever an asynchronous call is made outside of a context
41+
established by :func:`google.cloud.ndb.async_context`.
42+
"""
43+
44+
def __init__(self):
45+
super(AsyncContextError, self).__init__(
46+
"No currently running event loop. Asynchronous calls must be made "
47+
"in context established by google.cloud.ndb.async_context."
48+
)
49+
50+
3651
class BadValueError(Error):
3752
"""Indicates a property value or filter value is invalid.
3853

ndb/tests/unit/test__eventloop.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717

1818
import pytest
1919

20-
from google.cloud.ndb import _eventloop as eventloop
2120
import tests.unit.utils
2221

22+
from google.cloud.ndb import exceptions
23+
from google.cloud.ndb import _eventloop as eventloop
24+
2325

2426
def test___all__():
2527
tests.unit.utils.verify___all__(eventloop)
@@ -317,14 +319,16 @@ def test_async_context(EventLoop):
317319
one.run.assert_called_once_with()
318320

319321

320-
def test_add_idle():
321-
with pytest.raises(NotImplementedError):
322-
eventloop.add_idle()
322+
def test_get_event_loop():
323+
with pytest.raises(exceptions.AsyncContextError):
324+
eventloop.get_event_loop()
325+
with eventloop.async_context():
326+
assert isinstance(eventloop.get_event_loop(), eventloop.EventLoop)
323327

324328

325-
def test_get_event_loop():
329+
def test_add_idle():
326330
with pytest.raises(NotImplementedError):
327-
eventloop.get_event_loop()
331+
eventloop.add_idle()
328332

329333

330334
def test_queue_call():

0 commit comments

Comments
 (0)