> Setting the JooqLogger as a listener will be the default if no
> listener is configured.

Maybe I misunderstand: are you saying there would always be one logger
listening or that users can simply "addLogger(new JooqLogger())"?
If the latter, then no problem for me.

> So from a jOOQ-point-of-view, one interface
> instance per Factory might be the most general solution. What do you
> think?

I acknowledge your point of view and maybe this is more a conceptual discussion.

I tend to think in terms of user convenience, and if a user wants to
monitor the activity of all factories, then it becomes very hard.
Follow this logic:
- Factory is not multi threaded.
- An application generates short lived threads for SQL background
loading activity.
- Each of these threads needs to create its own Factory.
- The user wants to monitor whatever happens to all factories.
- The user needs to implement complex tracking of factory creation,
thread destruction (or factory GC...), with auto add/remove of the
listeners.

Compare this to:

JooqDebugger.addLogger(new JooqLoggerImpl());

JooqLoggerImpl implements JooqLogger {
  public void someEvent(Factory factory, otherParams) {
    // Can filter on the factory, which is anyway the one of this thread.
    // So we can also filter on the current thread (name, instance, etc)
  }
}

If you think about it, threading is very easy in this case, except
that you have the cost of a lock (which in general is not that
expensive).

public void JooqDebugger {
  private JooqDebugger() {}
  private static final Object LOCK = new Object();
  private static final List<Logger> loggerList = new ArrayList();
  public static void addLogger(Logger logger) {
    synchronized(LOCK) {
      loggerList.add(logger);
    }
  }
  public static void removeLogger(Logger logger) {
    synchronized(LOCK) {
      loggerList.remove(logger);
    }
  }
  /*
   * @return an immutable list of all the loggers currently registered.
   */
  public static List<Logger> getLoggerList() {
    synchronized(LOCK) {
      if(loggerList.isEmpty()) {
        // No cost when no loggers
        return Collections.emptyList();
      }
      // Small cost: copy collection and make it immutable.
      // Generally, no more than one or two listeners in the list.
      return Collections.unmodifiableList(new ArrayList(loggerList));
    }
  }
}

All that jOOQ API has to do when propagating an event is:

List<Logger> loggerList = JooqDebugger.getLoggerList();
if(!loggerList.isEmpty()) {
  // Create the event and send it to all loggers.
}

-Christopher

Reply via email to