Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
TaskRetryUtil.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.threadutils;
20 
21 import java.util.List;
22 import java.util.concurrent.Callable;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.ScheduledFuture;
25 import java.util.concurrent.ScheduledThreadPoolExecutor;
26 import java.util.concurrent.TimeUnit;
27 import java.util.concurrent.TimeoutException;
28 import java.util.concurrent.atomic.AtomicLong;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31 
38 public class TaskRetryUtil {
39 
40  private static final AtomicLong totalTasks = new AtomicLong();
41  private static final AtomicLong totalTaskRetries = new AtomicLong();
42  private static final AtomicLong totalTaskAttemptTimeOuts = new AtomicLong();
43  private static final AtomicLong totalFailedTasks = new AtomicLong();
44 
49  public static class TaskAttempt {
50 
51  private final Long delay;
52  private final Long timeOut;
53  private final TimeUnit timeUnit;
54 
60  public TaskAttempt() {
61  this.delay = 0L;
62  this.timeOut = 0L;
63  this.timeUnit = TimeUnit.SECONDS;
64  }
65 
75  public TaskAttempt(Long delay, TimeUnit timeUnit) {
76  if (delay == null || delay < 0) {
77  throw new IllegalArgumentException(String.format("Argument for delay parameter = %d, must be zero or any positive integer", delay));
78  }
79  if (timeUnit == null) {
80  throw new IllegalArgumentException("Argument for timeUnit parameter is null");
81  }
82  this.delay = delay;
83  this.timeOut = 0L;
84  this.timeUnit = timeUnit;
85  }
86 
98  public TaskAttempt(Long delay, Long timeOut, TimeUnit timeUnit) {
99  if (delay == null || delay < 0) {
100  throw new IllegalArgumentException(String.format("Argument for delay parameter = %d, must be zero or any positive integer", delay));
101  }
102  if (timeOut == null || timeOut < 0) {
103  throw new IllegalArgumentException(String.format("Argument for timeOut parameter = %d, must be zero or any positive integer", delay));
104  }
105  if (timeUnit == null) {
106  throw new IllegalArgumentException("Argument for timeUnit parameter is null");
107  }
108  this.delay = delay;
109  this.timeOut = timeOut;
110  this.timeUnit = timeUnit;
111  }
112 
119  public Long getDelay() {
120  return delay;
121  }
122 
129  public Long getTimeout() {
130  return timeOut;
131  }
132 
139  public TimeUnit getTimeUnit() {
140  return timeUnit;
141  }
142 
143  }
144 
149  public interface Terminator {
150 
157  boolean stopTaskAttempts();
158 
159  }
160 
183  public static <T> T attemptTask(Callable<T> task, List<TaskAttempt> attempts, ScheduledThreadPoolExecutor executor, Terminator terminator, Logger logger, String taskDesc) throws InterruptedException {
184  T result = null;
185  String taskDescForLog = taskDesc != null ? taskDesc : "Task";
186  int attemptCounter = 0;
187  if (attempts.size() > 0) {
188  totalTasks.incrementAndGet();
189  }
190  while (result == null && attemptCounter < attempts.size()) {
191  if (terminator != null && terminator.stopTaskAttempts()) {
192  if (logger != null) {
193  logger.log(Level.WARNING, String.format("Attempts to execute '%s' terminated ", taskDescForLog));
194  }
195  break;
196  }
197  TaskAttempt attempt = attempts.get(attemptCounter);
198  if (logger != null) {
199  logger.log(Level.INFO, String.format("SCHEDULING '%s' (attempt = %d, delay = %d %s, timeout = %d %s)", taskDescForLog, attemptCounter + 1, attempt.getDelay(), attempt.getTimeUnit(), attempt.getTimeout(), attempt.getTimeUnit()));
200  }
201  if (attemptCounter > 0) {
202  totalTaskRetries.incrementAndGet();
203  }
204  ScheduledFuture<T> future = executor.schedule(task, attempt.getDelay(), attempt.getTimeUnit());
205  try {
206  result = future.get(attempt.getDelay() + attempt.getTimeout(), attempt.getTimeUnit());
207  } catch (InterruptedException ex) {
208  if (logger != null) {
209  logger.log(Level.SEVERE, String.format("Interrupted executing '%s'", taskDescForLog), ex);
210  }
211  throw ex;
212  } catch (ExecutionException ex) {
213  if (logger != null) {
214  logger.log(Level.SEVERE, String.format("Error executing '%s'", taskDescForLog), ex);
215  }
216  } catch (TimeoutException ex) {
217  if (logger != null) {
218  logger.log(Level.SEVERE, String.format("Time out executing '%s'", taskDescForLog), ex);
219  }
220  totalTaskAttemptTimeOuts.incrementAndGet();
221  future.cancel(true);
222  }
223  ++attemptCounter;
224  }
225  if (result == null) {
226  if (terminator == null || !terminator.stopTaskAttempts()) {
227  totalFailedTasks.incrementAndGet();
228  }
229  }
230  return result;
231  }
232 
238  public static long getTotalTasksCount() {
239  return totalTasks.get();
240  }
241 
247  public static long getTotalTaskRetriesCount() {
248  return totalTaskRetries.get();
249  }
250 
256  public static long getTotalTaskAttemptTimeOutsCount() {
257  return totalTaskAttemptTimeOuts.get();
258  }
259 
266  public static long getTotalFailedTasksCount() {
267  return totalFailedTasks.get();
268  }
269 
273  private TaskRetryUtil() {
274  }
275 
276 }
static< T > T attemptTask(Callable< T > task, List< TaskAttempt > attempts, ScheduledThreadPoolExecutor executor, Terminator terminator, Logger logger, String taskDesc)
TaskAttempt(Long delay, Long timeOut, TimeUnit timeUnit)

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.