PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

LISTEN/NOTIFY pgconnection tombe en panne java ?

Les écouteurs de notification sont gérés en interne par cette bibliothèque en tant que références faibles, ce qui signifie que vous devez conserver une référence matérielle en externe afin qu'ils ne soient pas ramassés. Découvrez les lignes de classe BasicContext 642 - 655 :

public void addNotificationListener(String name, String channelNameFilter, NotificationListener listener) {

    name = nullToEmpty(name);
    channelNameFilter = channelNameFilter != null ? channelNameFilter : ".*";

    Pattern channelNameFilterPattern = Pattern.compile(channelNameFilter);

    NotificationKey key = new NotificationKey(name, channelNameFilterPattern);

    synchronized (notificationListeners) {
      notificationListeners.put(key, new WeakReference<NotificationListener>(listener));
    }

}

Si le GC capte votre écouteur, les appels à "get" sur la référence faible renverront null et ne se déclencheront pas comme on le voit depuis les lignes 690 - 710

  @Override
  public synchronized void reportNotification(int processId, String channelName, String payload) {

    Iterator<Map.Entry<NotificationKey, WeakReference<NotificationListener>>> iter = notificationListeners.entrySet().iterator();
    while (iter.hasNext()) {

      Map.Entry<NotificationKey, WeakReference<NotificationListener>> entry = iter.next();

      NotificationListener listener = entry.getValue().get();
      if (listener == null) {

        iter.remove();
      }
      else if (entry.getKey().channelNameFilter.matcher(channelName).matches()) {

        listener.notification(processId, channelName, payload);
      }

    }

}

Pour résoudre ce problème, ajoutez vos écouteurs de notification en tant que tels :

/// Do not let this reference go out of scope!
    PGNotificationListener listener = new PGNotificationListener() {

    @Override
    public void notification(int processId, String channelName, String payload) {
        // interesting code
    };
};
    pgConnection.addNotificationListener(listener);

Un cas d'utilisation assez étrange pour les références faibles à mon avis...