public void run()

in src/main/java/org/apache/sling/discovery/commons/providers/base/AsyncEventSender.java [85:147]


    public void run() {
        logger.info("AsyncEventSender.run: started.");
        try{
            while(true) {
                try{
                    final AsyncEvent asyncEvent;
                    synchronized(eventQ) {
                        isSending = false;
                        while(!stopped && eventQ.isEmpty()) {
                            try {
                                eventQ.wait();
                            } catch (InterruptedException e) {
                                // issue a log debug but otherwise continue
                                logger.debug("AsyncEventSender.run: interrupted while waiting for async events");
                            }
                        }
                        if (stopped) {
                            if (eventQ.isEmpty()) {
                                // then we have flushed, so we can now finally stop
                                logger.info("AsyncEventSender.run: flush finished. stopped.");
                                return;
                            } else {
                                // otherwise the eventQ is not yet empty, so we are still in flush mode
                                logger.info("AsyncEventSender.run: flushing another event. (pending {})", eventQ.size());
                            }
                        }
                        asyncEvent = eventQ.remove(0);
                        if (logger.isDebugEnabled()) {
                            logger.debug("AsyncEventSender.run: dequeued event {}, remaining: {}", asyncEvent, eventQ.size());
                        }
                        isSending = asyncEvent!=null;
                    }
                    if (asyncEvent!=null) {
                        asyncEvent.trigger();
                    }
                } catch(Throwable th) {
                    // Even though we should never catch Error or RuntimeException
                    // here's the thinking about doing it anyway:
                    //  * in case of a RuntimeException that would be less dramatic
                    //    and catching it is less of an issue - we rather want
                    //    the background thread to be able to continue than
                    //    having it finished just because of a RuntimeException
                    //  * catching an Error is of course not so nice.
                    //    however, should we really give up this thread even in
                    //    case of an Error? It could be an OOM or some other 
                    //    nasty one, for sure. But even if. Chances are that
                    //    other parts of the system would also get that Error
                    //    if it is very dramatic. If not, then catching it
                    //    sounds feasible. 
                    // My two cents..
                    // the goal is to avoid quitting the AsyncEventSender thread
                    logger.error("AsyncEventSender.run: Throwable occurred. Sleeping 5sec. Throwable: "+th, th);
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        logger.warn("AsyncEventSender.run: interrupted while sleeping");
                    }
                }
            }
        } finally {
            logger.info("AsyncEventSender.run: quits (finally).");
        }
    }