PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

ASCOLTA/NOTA pgconnection va giù java?

I listener di notifica sono mantenuti internamente da quella libreria come riferimenti deboli, il che significa che devi tenere un riferimento rigido esternamente in modo che non vengano raccolti. Dai un'occhiata alle righe di 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 il GC rileva il tuo listener, le chiamate per "ottenere" sul riferimento debole restituiranno null e non verranno attivate come si vede dalle righe 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);
      }

    }

}

Per risolvere questo problema, aggiungi i tuoi listener di notifiche come tali:

/// 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 caso d'uso piuttosto strano per riferimenti deboli secondo me...