Baratine on GitHub

Timers Service

Overview

Timers is a service to schedule tasks to be run once or multiple times on a schedule. The scheme for the Timers is timer`.

Using a Timer

The following creates an internal timer for a service, calling its own onTimer() method every hour.

The timer is initialized in the @OnInit method. The service has @Startup to start it when the web server starts.

@Service
@Startup
public class MyService {
  @Inject Timers _timer;

  @OnInit
  public void onInit() {
    _timer.runEvery(h -> onTimer(), 1, TimeUnit.HOUR, Result.ignore());
  }

  private void onTimer() {
    ...
  }
}

Obtaining the Timer Service Programmatically

Services manager = Services.current();

Timers timer = manager.service(Timers.class);

timer.runAt(...);

Timers API

@Service("timer:")
public interface Timers
{
  void runAt(@Pin Consumer<? super Cancel> task,
             long epochMillis,
             Result<? super Cancel> result);

  void runAfter(@Pin Consumer<? super Cancel> task,
                long delay,
                TimeUnit unit,
                Result<? super Cancel> result);

  void runEvery(@Pin Consumer<? super Cancel> task,
                long delay,
                TimeUnit unit,
                Result<? super Cancel> result);

  void schedule(@Pin Consumer<? super Cancel> task,
                LongUnaryOperator nextTime,
                Result<? super Cancel> result);
}

The following synchronous API is for services that are allowed to block and for testing:

public interface TimersSync extends Timers
{
  Cancel runAt(@Pin Consumer<? super Cancel> task,
               long time);

  Cancel runAfter(@Pin Consumer<? super Cancel> task,
                  long delay,
                  TimeUnit unit);

  Cancel runEvery(@Pin Consumer<? super Cancel> task,
                  long delay,
                  TimeUnit unit);

  Cancel schedule(@Pin Consumer<? super Cancel> task,
                  LongUnaryOperator nextTime);
}

Running a Task Once

Consumer<Cancel> task = cancel -> {
  System.out.println("ran on: " + System.currentTimeMillis());
};

timer.runAfter(task, 5, TimeUnit.SECONDS, Result.ignore());

Running a Task With a Custom Scheduler That Runs Exactly 5 Times

timer.schedule(
  task,
  new LongUnaryOperator() {
      int count = 0;

      public long applyAsLong(long now) {
        if (count++ >= 5) {
          return -1; // negative value to cancel
        }
        else {
          return now + 2000; // run again 2 seconds from now
        }
      }
  },
  Result.ignore()
);

Cancelling a Task

public class MyClass {
  @Inject
  private Timers _timer;

  private CancelHandle _cancel;

  @OnInit
  void init() {
    timer.runAfter(new MyTask(), 5, TimeUnit.SECONDS, (c, e) -> { _cancel = c; });
  }

  void cancel() {
    if (_cancel != null) {
      _cancel.cancel();
    }
  }
}