You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Patch `asyncio.wait_for`
Async wait_for shim raise cancellation right away
Deferring the cancellation makes it much harder to reason about and might make
the Python driver behave in a surprising way when cancelled.
* Fix unit tests
Copy file name to clipboardExpand all lines: docs/source/api.rst
+22-13Lines changed: 22 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -511,6 +511,8 @@ To construct a :class:`neo4j.Session` use the :meth:`neo4j.Driver.session` metho
511
511
512
512
513
513
Sessions will often be created and destroyed using a *with block context*.
514
+
This is the recommended approach as it takes care of closing the session
515
+
properly even when an exception is raised.
514
516
515
517
.. code-block:: python
516
518
@@ -536,6 +538,8 @@ Session
536
538
537
539
.. automethod:: close
538
540
541
+
.. automethod:: closed
542
+
539
543
.. automethod:: run
540
544
541
545
.. automethod:: last_bookmarks
@@ -643,7 +647,7 @@ context of the impersonated user. For this, the user for which the
643
647
.. Note::
644
648
645
649
The server or all servers of the cluster need to support impersonation when.
646
-
Otherwise, the driver will raise :py:exc:`.ConfigurationError`
650
+
Otherwise, the driver will raise :exc:`.ConfigurationError`
647
651
as soon as it encounters a server that does not.
648
652
649
653
@@ -708,15 +712,15 @@ Neo4j supports three kinds of transaction:
708
712
+ :ref:`explicit-transactions-ref`
709
713
+ :ref:`managed-transactions-ref`
710
714
711
-
Each has pros and cons but if in doubt, use a managed transaction with a `transaction function`.
715
+
Each has pros and cons but if in doubt, use a managed transaction with a *transaction function*.
712
716
713
717
714
718
.. _auto-commit-transactions-ref:
715
719
716
720
Auto-commit Transactions
717
721
========================
718
722
Auto-commit transactions are the simplest form of transaction, available via
719
-
:py:meth:`neo4j.Session.run`. These are easy to use but support only one
723
+
:meth:`neo4j.Session.run`. These are easy to use but support only one
720
724
statement per transaction and are not automatically retried on failure.
721
725
722
726
Auto-commit transactions are also the only way to run ``PERIODIC COMMIT``
@@ -756,7 +760,7 @@ Example:
756
760
757
761
Explicit Transactions
758
762
=====================
759
-
Explicit transactions support multiple statements and must be created with an explicit :py:meth:`neo4j.Session.begin_transaction` call.
763
+
Explicit transactions support multiple statements and must be created with an explicit :meth:`neo4j.Session.begin_transaction` call.
760
764
761
765
This creates a new :class:`neo4j.Transaction` object that can be used to run Cypher.
762
766
@@ -766,16 +770,16 @@ It also gives applications the ability to directly control ``commit`` and ``roll
766
770
767
771
.. automethod:: run
768
772
769
-
.. automethod:: close
770
-
771
-
.. automethod:: closed
772
-
773
773
.. automethod:: commit
774
774
775
775
.. automethod:: rollback
776
776
777
+
.. automethod:: close
778
+
779
+
.. automethod:: closed
780
+
777
781
Closing an explicit transaction can either happen automatically at the end of a ``with`` block,
778
-
or can be explicitly controlled through the :py:meth:`neo4j.Transaction.commit`, :py:meth:`neo4j.Transaction.rollback` or :py:meth:`neo4j.Transaction.close` methods.
782
+
or can be explicitly controlled through the :meth:`neo4j.Transaction.commit`, :meth:`neo4j.Transaction.rollback` or :meth:`neo4j.Transaction.close` methods.
779
783
780
784
Explicit transactions are most useful for applications that need to distribute Cypher execution across multiple functions for the same transaction.
Copy file name to clipboardExpand all lines: docs/source/async_api.rst
+94-10Lines changed: 94 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -287,6 +287,8 @@ To construct a :class:`neo4j.AsyncSession` use the :meth:`neo4j.AsyncDriver.sess
287
287
288
288
289
289
Sessions will often be created and destroyed using a *with block context*.
290
+
This is the recommended approach as it takes care of closing the session
291
+
properly even when an exception is raised.
290
292
291
293
.. code-block:: python
292
294
@@ -311,8 +313,43 @@ AsyncSession
311
313
312
314
.. autoclass:: neo4j.AsyncSession()
313
315
316
+
.. note::
317
+
318
+
Some asyncio utility functions (e.g., :func:`asyncio.wait_for` and
319
+
:func:`asyncio.shield`) will wrap work in a :class:`asyncio.Task`.
320
+
This introduces concurrency and can lead to undefined behavior as
321
+
:class:`AsyncSession` is not concurrency-safe.
322
+
323
+
Consider this **wrong** example::
324
+
325
+
async def dont_do_this(driver):
326
+
async with driver.session() as session:
327
+
await asyncio.shield(session.run("RETURN 1"))
328
+
329
+
If ``dont_do_this`` gets cancelled while waiting for ``session.run``,
330
+
``session.run`` itself won't get cancelled (it's shielded) so it will
331
+
continue to use the session in another Task. Concurrently, will the
332
+
async context manager (``async with driver.session()``) on exit clean
333
+
up the session. That's two Tasks handling the session concurrently.
334
+
Therefore, this yields undefined behavior.
335
+
336
+
In this particular example, the problem could be solved by shielding
337
+
the whole coroutine ``dont_do_this`` instead of only the
338
+
``session.run``. Like so::
339
+
340
+
async def thats_better(driver):
341
+
async def inner()
342
+
async with driver.session() as session:
343
+
await session.run("RETURN 1")
344
+
345
+
await asyncio.shield(inner())
346
+
314
347
.. automethod:: close
315
348
349
+
.. automethod:: cancel
350
+
351
+
.. automethod:: closed
352
+
316
353
.. automethod:: run
317
354
318
355
.. automethod:: last_bookmarks
@@ -346,15 +383,15 @@ Neo4j supports three kinds of async transaction:
346
383
+ :ref:`async-explicit-transactions-ref`
347
384
+ :ref:`async-managed-transactions-ref`
348
385
349
-
Each has pros and cons but if in doubt, use a managed transaction with a `transaction function`.
386
+
Each has pros and cons but if in doubt, use a managed transaction with a *transaction function*.
350
387
351
388
352
389
.. _async-auto-commit-transactions-ref:
353
390
354
391
Auto-commit Transactions
355
392
========================
356
393
Auto-commit transactions are the simplest form of transaction, available via
357
-
:py:meth:`neo4j.Session.run`. These are easy to use but support only one
394
+
:meth:`neo4j.Session.run`. These are easy to use but support only one
358
395
statement per transaction and are not automatically retried on failure.
359
396
360
397
Auto-commit transactions are also the only way to run ``PERIODIC COMMIT``
@@ -398,7 +435,7 @@ Example:
398
435
399
436
Explicit Async Transactions
400
437
===========================
401
-
Explicit transactions support multiple statements and must be created with an explicit :py:meth:`neo4j.AsyncSession.begin_transaction` call.
438
+
Explicit transactions support multiple statements and must be created with an explicit :meth:`neo4j.AsyncSession.begin_transaction` call.
402
439
403
440
This creates a new :class:`neo4j.AsyncTransaction` object that can be used to run Cypher.
404
441
@@ -408,16 +445,18 @@ It also gives applications the ability to directly control ``commit`` and ``roll
408
445
409
446
.. automethod:: run
410
447
411
-
.. automethod:: close
412
-
413
-
.. automethod:: closed
414
-
415
448
.. automethod:: commit
416
449
417
450
.. automethod:: rollback
418
451
452
+
.. automethod:: close
453
+
454
+
.. automethod:: cancel
455
+
456
+
.. automethod:: closed
457
+
419
458
Closing an explicit transaction can either happen automatically at the end of a ``async with`` block,
420
-
or can be explicitly controlled through the :py:meth:`neo4j.AsyncTransaction.commit`, :py:meth:`neo4j.AsyncTransaction.rollback`or :py:meth:`neo4j.AsyncTransaction.close` methods.
459
+
or can be explicitly controlled through the :meth:`neo4j.AsyncTransaction.commit`, :meth:`neo4j.AsyncTransaction.rollback`, :meth:`neo4j.AsyncTransaction.close` or :meth:`neo4j.AsyncTransaction.cancel` methods.
421
460
422
461
Explicit transactions are most useful for applications that need to distribute Cypher execution across multiple functions for the same transaction.
0 commit comments