.. _dbevent-example: Catching DBEvents ================= .. NOTE:: Basic knowledge of ``asyncio`` is assumed for this example. DBEvent notifications are sent to the OpenAPI when it is actively interacting with the DBMS. The :func:`!dbevent_catcher` coroutine shown below retrieves the notifications. DBEvents can have an optional message attached. Refer to :ref:`varchar-handling-example` to understand how the buffer for the optional event message is allocated and to see how a :func:`!varchar` function can be defined to assist. For the sake of illustrating a reaction to a notification :func:`!dbevent_catcher` places the details of the DBEvent in an :func:`!asyncio.Queue`, to be conveniently available to the main application. :func:`IIapi_catchEvent` is not awaitable. :func:`!dbevent_catcher` uses a busy-wait loop to check for notifications. A global :func:`!asyncio.Event` called :attr:`!stop` is used to terminate the loop. To ensure prompt reaction to events during idle periods when the application is not actively interacting with the DBMS the :func:`!dbevent_getter` coroutine uses a timer to periodically request delivery of notifications. These coroutines would be run as concurrent tasks together with the main application task. When run that way they could disrupt an :ref:`openapi-protocol` initiated by the main task unless their operation is coordinated with the main task. All the tasks need to take and release a global :func:`!asyncio.Lock` to ensure safe shared use of the DBMS session. In this example the lock is called :attr:`!session_mutex`. :download:`Download <./examples/dbevent.py>` .. LITERALINCLUDE:: ./examples/dbevent.py :linenos: :download:`Download <./examples/dbevent.py>`