Anyone want a couple of listen/notify helper classes? - Mailing list pgsql-jdbc
From | Craig Ringer |
---|---|
Subject | Anyone want a couple of listen/notify helper classes? |
Date | |
Msg-id | 4B207EB6.50602@postnewspapers.com.au Whole thread Raw |
List | pgsql-jdbc |
Hi folks I've just put together a couple of helper classes for the use of listen/notify in Java, and was wondering if anybody might be interested in using them. If so, I'll tidy them up a bit and pop them on the wiki for general use. The two classes are: * PgNotificationHelper A fairly simple manager of listen/notify events on a connection. Provides `observer'-style listener interface and list of listeners so that Java objects may easily receive NOTIFY events without having to care about the SQL guts. Also provides helpers for managing the list of events listened to in the database, so that you can easily call "helper.listen(name)" etc to add/remove listeners. Tracks the list of listened-to names its self, and can re-listen to them if passed a new connection after a connection break. Plays well with others - can be used without problems on a connection you're using for other things. PgNotificationHelper doesn't do periodic polling, you need to do that. It also expects you to handle any exceptions it reports while working with the conennection you supplied to it. PgNotificationHelper is well suited to apps that use the JDBC APIs quite directly. * PgNotificationPoller Uses PgNotificationHelper behind the scenes to provide a listen/notify interface that does its own periodic polling. To do this it uses a dedicated JDBC connection it creates and manages its self using user-supplied credentials. The connection will be re-created (with appropriate failure backoff) if it drops. A daemon thread is used to do the database work. PgNotificationPoller is completely thread-safe and no public methods ever block to wait for database work. All public methods may be called safely from any thread. All communication between the PgNotificationPoller and the worker thread is by asynchronous messaging. PgNotificationHelper is well suited to apps that use connection pooling and some kind of ORM layer, where low-level connection management is done behind the scenes. However, it doesn't depend on any interfaces from any connection pools or ORMs, and works fine in their absence. Unlike PgNotificationHelper, though, it does cost you an extra JDBC connection to the database. All listeners' methods are always sent on the EDT, for ease of use in Swing apps. (This could be easily changed if required). Currently the user has absolutely no access to the PgNotificationPoller's connection. I may extend the class to allow a user to "borrow" the connection from the poller to do work on it, though, if there's interest in that. Extensions may also be made to allow the PgNotificationPoller to manage advisory locks. I haven't attached the current code, as it needs some JavaDoc love and I need to fill out the test cases a bit. I thought this might be a common enough task to tackle, though, that people might be interested in nicer-to-use interfaces for working with these database features. After all, something like this is a *wee* bit nicer to use than direct listen/notify via JDBC: class MyClass implements PgNotificationPoller.PgNotificationListener { // In practice you'd usually maintain one poller for the whole // app and pass it in as a param, but for the sake of the example: private final PgNotificationPoller poller = new PgNotificationPoller( "jdbc:postgresql://localhost/dbname", "username", "password"); public MyClass() { poller.addNotificationListener(this); // Tell the poller to issue a LISTEN CUSTOMERS_CHANGED, which // will be executed next time the poller's connection is idle. poller.listen("CUSTOMERS_CHANGED"); } @Override public void notified( PgNotificationPoller poller, Connection connection, PGNotification n ) { System.out.println("Received notification: " + n.getName() + " from " + n.getPID() + " with param " + n.getParameter()); } @Override public void pollerStatusChanged( PgNotificationPoller poller, Status oldStatus, Status newStatus ) { // Allows you to act on broken connections and reconnects // that might mean you have to compensate for lost notifications. } }
pgsql-jdbc by date: