PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

LISTEN/NOTIFY pgconnection cai java?


Os ouvintes de notificação são mantidos internamente por essa biblioteca como referências fracas, o que significa que você precisa manter uma referência rígida externamente para que eles não sejam coletados como lixo. Confira as linhas 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));
    }

}

Se o GC pegar seu ouvinte, as chamadas para "get" na referência fraca retornarão null e não serão disparadas como visto nas linhas 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);
      }

    }

}

Para corrigir isso, adicione seus ouvintes de notificação da seguinte forma:
/// 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);

Um caso de uso bastante estranho para referências fracas na minha opinião ...