Beispiel #1
0
    public void run() {
      if (_log.shouldLog(Log.DEBUG)) _log.debug("Running: " + this);
      long before = System.currentTimeMillis();
      long delay = 0;
      synchronized (this) {
        if (_rescheduleAfterRun)
          throw new IllegalStateException("rescheduleAfterRun cannot be true here");

        switch (_state) {
          case CANCELLED:
            return; // goodbye
          case IDLE: // fall through
          case RUNNING:
            throw new IllegalStateException("not possible to be in " + _state);
          case SCHEDULED: // proceed, switch to IDLE in case I need to reschedule
            _state = TimedEventState.IDLE;
        }

        // if I was rescheduled by the user, re-submit myself to the executor.
        int difference = (int) (_nextRun - before); // careful with long uptimes
        if (difference > _fuzz) {
          schedule(difference);
          return;
        }

        // else proceed to run
        _state = TimedEventState.RUNNING;
      }
      // cancel()-ing after this point only works if the event supports it explicitly
      // none of these _future checks should be necessary anymore
      if (_future != null) delay = _future.getDelay(TimeUnit.MILLISECONDS);
      else if (_log.shouldLog(Log.WARN)) _log.warn(_pool + " wtf, no _future " + this);
      // This can be an incorrect warning especially after a schedule(0)
      if (_log.shouldLog(Log.WARN) && delay > 100)
        _log.warn(_pool + " wtf, early execution " + delay + ": " + this);
      else if (_log.shouldLog(Log.WARN) && delay < -1000)
        _log.warn(" wtf, late execution " + (0 - delay) + ": " + this + _pool.debug());
      try {
        timeReached();
      } catch (Throwable t) {
        _log.log(
            Log.CRIT, _pool + ": Timed task " + this + " exited unexpectedly, please report", t);
      } finally { // must be in finally
        synchronized (this) {
          switch (_state) {
            case SCHEDULED: // fall through
            case IDLE:
              throw new IllegalStateException("can't be " + _state);
            case CANCELLED:
              break; // nothing
            case RUNNING:
              _state = TimedEventState.IDLE;
              // do we need to reschedule?
              if (_rescheduleAfterRun) {
                _rescheduleAfterRun = false;
                schedule(_nextRun - System.currentTimeMillis());
              }
          }
        }
      }
      long time = System.currentTimeMillis() - before;
      if (time > 500 && _log.shouldLog(Log.WARN))
        _log.warn(_pool + " wtf, event execution took " + time + ": " + this);
      if (_log.shouldLog(Log.INFO)) {
        // this call is slow - iterates through a HashMap -
        // would be better to have a local AtomicLong if we care
        long completed = _pool.getCompletedTaskCount();
        if (completed % 250 == 0) _log.info(_pool.debug());
      }
    }