db.postgres: implement wait() and post() based on Postgres notifications #428
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Postgres supports publish-subscribe feature. One client listens on a channel
(provided as a string), while another (or same) client send a notification.
It can be used to send notifications accross machines and nginx workers.
The notification can be delivered with any read operation. To decouple
receiving notifications from reading results of normal queries, a
background handler with independent database socket is created. The
handler starts two light threads: a reader and a writer. The reader reads
new notifications from the database. The writer pushes commands "listen"
and "unlisten" to the database. Signals to/from the background handler
are delivered using openresty's semaphores.
Two new methods of "lapis.db.postgres" (and "lapis.db") were added:
Returns a payload passed by caller of post().
All waiting light threads in nginx worker share the same database socket.
All light threads waiting on the same channel use the same semaphore
object which is triggered by reader light thread of the background handler.
When new channel is started being listened, it is provided to writer light
thread of the background handler and it sends command "listen channel".
When a notification is received, the corresponding channel is "unlistened"
by writer light thread and the corresponding semaphore is removed. It is
needed to prevent resource leaks in nginx worker and in database worker.
All methods are 100% non-blocking.
Notifications add zero overhead when not used.
Example:
In another terminal:
The first terminal should output "bar".
This pull request depends on leafo/pgmoon#28