001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.util.backoff; 018 019import java.util.concurrent.ScheduledExecutorService; 020import java.util.concurrent.TimeUnit; 021import java.util.function.BiConsumer; 022 023import org.apache.camel.util.function.ThrowingFunction; 024 025/** 026 * A simple timer utility that use a linked {@link BackOff} to determine when 027 * a task should be executed. 028 */ 029public class BackOffTimer { 030 private final ScheduledExecutorService scheduler; 031 032 public BackOffTimer(ScheduledExecutorService scheduler) { 033 this.scheduler = scheduler; 034 } 035 036 /** 037 * Schedule the given function/task to be executed some time in the future 038 * according to the given backOff. 039 */ 040 public Task schedule(BackOff backOff, ThrowingFunction<Task, Boolean, Exception> function) { 041 final BackOffTimerTask task = new BackOffTimerTask(backOff, scheduler, function); 042 043 long delay = task.next(); 044 if (delay != BackOff.NEVER) { 045 scheduler.schedule(task, delay, TimeUnit.MILLISECONDS); 046 } else { 047 task.cancel(); 048 } 049 050 return task; 051 } 052 053 // **************************************** 054 // TimerTask 055 // **************************************** 056 057 public interface Task { 058 enum Status { 059 Active, 060 Inactive, 061 Exhausted 062 } 063 064 /** 065 * The back-off associated with this task. 066 */ 067 BackOff getBackOff(); 068 069 /** 070 * Gets the task status. 071 */ 072 Status getStatus(); 073 074 /** 075 * The number of attempts so far. 076 */ 077 long getCurrentAttempts(); 078 079 /** 080 * The current computed delay. 081 */ 082 long getCurrentDelay(); 083 084 /** 085 * The current elapsed time. 086 */ 087 long getCurrentElapsedTime(); 088 089 /** 090 * The time the last attempt has been performed. 091 */ 092 long getLastAttemptTime(); 093 094 /** 095 * An indication about the time the next attempt will be made. 096 */ 097 long getNextAttemptTime(); 098 099 /** 100 * Reset the task. 101 */ 102 void reset(); 103 104 /** 105 * Cancel the task. 106 */ 107 void cancel(); 108 109 /** 110 * Action to execute when the context is completed (cancelled or exhausted) 111 * 112 * @param whenCompleted the consumer. 113 */ 114 void whenComplete(BiConsumer<Task, Throwable> whenCompleted); 115 } 116}