1 package net.avcompris.commons3.dao.impl;
2
3 import static com.google.common.base.Preconditions.checkNotNull;
4
5 import java.io.IOException;
6 import java.sql.SQLException;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10
11 import net.avcompris.commons3.utils.Clock;
12
13 public abstract class AbstractDao {
14
15 private static final Log logger = LogFactory.getLog(AbstractDao.class);
16
17 protected final Clock clock;
18
19 protected AbstractDao(final Clock clock) {
20
21 this.clock = checkNotNull(clock, "clock");
22 }
23
24 @FunctionalInterface
25 protected interface Action<T> {
26
27 T action() throws SQLException, IOException;
28 }
29
30 protected static final <T> T retryUntil(final long timeoutMs, final long delayMs, final Action<T> action)
31 throws SQLException, IOException {
32
33 return retryUntil(timeoutMs, delayMs, true, action);
34 }
35
36 protected static final <T> T retryUntil(final long timeoutMs, final long delayMs,
37 final boolean throwExceptionInCaseOfTimeout, final Action<T> action) throws SQLException, IOException {
38
39 checkNotNull(action, "action");
40
41 for (final long startMs = System.currentTimeMillis(); System.currentTimeMillis() < startMs + timeoutMs;) {
42
43 T result = null;
44
45 try {
46
47 result = action.action();
48
49 } catch (final SQLException | IOException | RuntimeException | Error e) {
50
51 throw e;
52
53 } catch (final Exception e) {
54
55 throw new RuntimeException(e);
56 }
57
58 if (result != null) {
59
60 return result;
61 }
62
63 try {
64
65 Thread.sleep(delayMs);
66
67 } catch (final InterruptedException e) {
68
69 e.printStackTrace();
70
71
72 }
73 }
74
75 logger.error("A timeout occurs (" + timeoutMs + " ms)");
76
77 if (throwExceptionInCaseOfTimeout) {
78
79 throw new RuntimeException("Timeout after: " + timeoutMs + " ms");
80
81 } else {
82
83 return null;
84 }
85 }
86 }