• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ben-manes / caffeine / #5173

29 Dec 2025 05:27AM UTC coverage: 0.0% (-100.0%) from 100.0%
#5173

push

github

ben-manes
speed up development ci build

0 of 3838 branches covered (0.0%)

0 of 7869 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Scheduler.java
1
/*
2
 * Copyright 2019 Ben Manes. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.github.benmanes.caffeine.cache;
17

18
import static java.util.Objects.requireNonNull;
19

20
import java.io.Serializable;
21
import java.lang.System.Logger;
22
import java.lang.System.Logger.Level;
23
import java.util.concurrent.CompletableFuture;
24
import java.util.concurrent.Executor;
25
import java.util.concurrent.Future;
26
import java.util.concurrent.ScheduledExecutorService;
27
import java.util.concurrent.TimeUnit;
28

29
import org.jspecify.annotations.NullMarked;
30
import org.jspecify.annotations.Nullable;
31

32
/**
33
 * A scheduler that submits a task to an executor after a given delay.
34
 *
35
 * @author ben.manes@gmail.com (Ben Manes)
36
 */
37
@NullMarked
38
@FunctionalInterface
39
public interface Scheduler {
40

41
  /**
42
   * Returns a future that will submit the task to the executor after the given delay.
43
   *
44
   * @param executor the executor to run the task
45
   * @param command the runnable task to schedule
46
   * @param delay how long to delay, in units of {@code unit}
47
   * @param unit a {@code TimeUnit} determining how to interpret the {@code delay} parameter
48
   * @return a scheduled future representing the pending submission of the task
49
   */
50
  Future<? extends @Nullable Object> schedule(
51
      Executor executor, Runnable command, long delay, TimeUnit unit);
52

53
  /**
54
   * Returns a scheduler that always returns a successfully completed future.
55
   *
56
   * @return a scheduler that always returns a successfully completed future
57
   */
58
  static Scheduler disabledScheduler() {
59
    return DisabledScheduler.INSTANCE;
×
60
  }
61

62
  /**
63
   * Returns a scheduler that uses the system-wide scheduling thread by using
64
   * {@link CompletableFuture#delayedExecutor}.
65
   *
66
   * @return a scheduler that uses the system-wide scheduling thread
67
   */
68
  static Scheduler systemScheduler() {
69
    return SystemScheduler.INSTANCE;
×
70
  }
71

72
  /**
73
   * Returns a scheduler that delegates to the a {@link ScheduledExecutorService}.
74
   * <p>
75
   * Note that this implementation will ignore scheduling the task if the executor was shutdown or
76
   * the submission was rejected. Consider implementing your own adapter if different behavior is
77
   * required.
78
   *
79
   * @param scheduledExecutorService the executor to schedule on
80
   * @return a scheduler that delegates to the a {@link ScheduledExecutorService}
81
   */
82
  static Scheduler forScheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
83
    return new ExecutorServiceScheduler(scheduledExecutorService);
×
84
  }
85

86
  /**
87
   * Returns a scheduler that suppresses and logs any exception thrown by the delegate
88
   * {@code scheduler}.
89
   *
90
   * @param scheduler the scheduler to delegate to
91
   * @return a scheduler that suppresses and logs any exception thrown by the delegate
92
   */
93
  static Scheduler guardedScheduler(Scheduler scheduler) {
94
    return (scheduler instanceof GuardedScheduler) ? scheduler : new GuardedScheduler(scheduler);
×
95
  }
96
}
97

98
enum SystemScheduler implements Scheduler {
×
99
  INSTANCE;
×
100

101
  @Override
102
  public Future<?> schedule(Executor executor, Runnable command, long delay, TimeUnit unit) {
103
    Executor delayedExecutor = CompletableFuture.delayedExecutor(delay, unit, executor);
×
104
    return CompletableFuture.runAsync(command, delayedExecutor);
×
105
  }
106
}
107

108
final class ExecutorServiceScheduler implements Scheduler, Serializable {
109
  private static final Logger logger = System.getLogger(ExecutorServiceScheduler.class.getName());
×
110
  private static final long serialVersionUID = 1;
111

112
  @SuppressWarnings("serial")
113
  final ScheduledExecutorService scheduledExecutorService;
114

115
  ExecutorServiceScheduler(ScheduledExecutorService scheduledExecutorService) {
×
116
    this.scheduledExecutorService = requireNonNull(scheduledExecutorService);
×
117
  }
×
118

119
  @Override
120
  public Future<? extends @Nullable Object> schedule(
121
      Executor executor, Runnable command, long delay, TimeUnit unit) {
122
    requireNonNull(executor);
×
123
    requireNonNull(command);
×
124
    requireNonNull(unit);
×
125

126
    if (scheduledExecutorService.isShutdown()) {
×
127
      return DisabledFuture.instance();
×
128
    }
129
    return scheduledExecutorService.schedule(() -> {
×
130
      try {
131
        executor.execute(command);
×
132
      } catch (Throwable t) {
×
133
        logger.log(Level.WARNING, "Exception thrown when submitting scheduled task", t);
×
134
        throw t;
×
135
      }
×
136
    }, delay, unit);
×
137
  }
138
}
139

140
final class GuardedScheduler implements Scheduler, Serializable {
141
  private static final Logger logger = System.getLogger(GuardedScheduler.class.getName());
×
142
  private static final long serialVersionUID = 1;
143

144
  @SuppressWarnings("serial")
145
  final Scheduler delegate;
146

147
  GuardedScheduler(Scheduler delegate) {
×
148
    this.delegate = requireNonNull(delegate);
×
149
  }
×
150

151
  @Override
152
  public Future<? extends @Nullable Object> schedule(
153
      Executor executor, Runnable command, long delay, TimeUnit unit) {
154
    try {
155
      var future = delegate.schedule(executor, command, delay, unit);
×
156
      return (future == null) ? DisabledFuture.instance() : future;
×
157
    } catch (Throwable t) {
×
158
      logger.log(Level.WARNING, "Exception thrown by scheduler; discarded task", t);
×
159
      return DisabledFuture.instance();
×
160
    }
161
  }
162
}
163

164
enum DisabledScheduler implements Scheduler {
×
165
  INSTANCE;
×
166

167
  @Override
168
  public Future<? extends @Nullable Object> schedule(
169
      Executor executor, Runnable command, long delay, TimeUnit unit) {
170
    requireNonNull(executor);
×
171
    requireNonNull(command);
×
172
    requireNonNull(unit);
×
173
    return DisabledFuture.instance();
×
174
  }
175
}
176

177
@SuppressWarnings("CheckedExceptionNotThrown")
×
178
enum DisabledFuture implements Future<@Nullable Void> {
179
  INSTANCE;
×
180

181
  static Future<? extends @Nullable Object> instance() {
182
    return INSTANCE;
×
183
  }
184

185
  @Override public boolean isDone() {
186
    return true;
×
187
  }
188
  @Override public boolean isCancelled() {
189
    return false;
×
190
  }
191
  @Override public boolean cancel(boolean mayInterruptIfRunning) {
192
    return false;
×
193
  }
194
  @Override public @Nullable Void get(long timeout, TimeUnit unit) {
195
    requireNonNull(unit);
×
196
    return null;
×
197
  }
198
  @Override public @Nullable Void get() {
199
    return null;
×
200
  }
201
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc