Copyright | (c) 2020 Jonathan Fischoff (c) 2016 Moritz Kiefer (c) 2011-2015 Leon P Smith (c) 2012 Joey Adams |
---|---|
License | BSD3 |
Maintainer | Moritz Kiefer <[email protected]> |
Safe Haskell | None |
Language | Haskell2010 |
Database.PostgreSQL.LibPQ.Notify
Contents
Description
Support for receiving asynchronous notifications via PostgreSQL's Listen/Notify mechanism. See http://www.postgresql.org/docs/9.4/static/sql-notify.html for more information.
Note that on Windows, getNotification
currently uses a polling loop
of 1 second to check for more notifications, due to some inadequacies
in GHC's IO implementation and interface on that platform. See GHC
issue #7353 for more information. While this workaround is less than
ideal, notifications are still better than polling the database directly.
Notifications do not create any extra work for the backend, and are
likely cheaper on the client side as well.
http://hackage.haskell.org/trac/ghc/ticket/7353
PostgreSQL notifications support using the same connection for sending and receiving notifications. This pattern is particularly useful in tests and probably not that useful otherwise.
This library relies on receiving OS notifications that new data is available to read from the connection's socket. However both epoll_wait and kqueue do not return if recvfrom is able to clear the socket receive buffer before they verify there is data available.
This race between recvfrom and the event processing in kqueue/epoll_wait is common and largely unavoidable if one is using the same connection for sending and receiving notifications on different threads simultaneously.
To support this pattern the library provides an advanced API which allows custom
interrupt to be used in addition to the socket read ready notification.
See getNotificationWithConfig
for more details.
Synopsis
- getNotification :: (forall a. c -> (Connection -> IO a) -> IO a) -> c -> IO (Either IOError Notify)
- getNotificationWithConfig :: Config -> (forall a. c -> (Connection -> IO a) -> IO a) -> c -> IO (Either IOError Notify)
- defaultConfig :: Config
- data Config = Config {
- interrupt :: Maybe (IO ())
- interrupted :: IO ()
- threadWaitReadReturned :: IO ()
- startLoop :: IO ()
- beforeWait :: IO ()
Documentation
Arguments
:: (forall a. c -> (Connection -> IO a) -> IO a) | This is a way to get a connection from a |
-> c | A type that can used to provide a connection when used with the former argument. Typically a concurrency primitive like 'MVar PQ.Connection' |
-> IO (Either IOError Notify) |
Returns a single notification. If no notifications are
available, getNotification
blocks until one arrives.
If getNotification
is called and afterwards on a different thread
NOTIFY
is called using the same connection, getNotification
can
block even if a notification is sent.
To support this behavior one must use getNotificationWithConfig
instead.
Note that PostgreSQL does not deliver notifications while a connection is inside a transaction.
Advanced API
getNotificationWithConfig Source #
Arguments
:: Config | |
-> (forall a. c -> (Connection -> IO a) -> IO a) | This is a way to get a connection from a |
-> c | A type that can used to provide a connection when used with the former argument. Typically a concurrency primitive like 'MVar PQ.Connection' |
-> IO (Either IOError Notify) |
Returns a single notification. If no notifications are
available, getNotificationWithConfig
blocks until one arrives.
Unlike getNotification
, getNotificationWithConfig
takes in an
additional Config
parameter which provides custom interrupt
and
various event hooks for operational insight.
Using a custom interrupt
is necessary if one would like to call
getNotificationWithConfig
on one thread and NOTIFY
on another
thread using the same connection.
To support this behavior one must cause interrupt
to return after the
call to NOTIFY
checks it's result from the server.
See the test file of this package for an example of how to use a custom
interrupt
.
Note that PostgreSQL does not deliver notifications while a connection is inside a transaction.
defaultConfig :: Config Source #
Default configuration
Options for controlling and instrumenting the behavior of getNotificationWithConfig
Constructors
Config | |
Fields
|