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

TAKETODAY / today-infrastructure / 18154768944

01 Oct 2025 07:26AM UTC coverage: 81.882% (-0.005%) from 81.887%
18154768944

push

github

web-flow
Merge pull request #290 from TAKETODAY/dev/jspecify

jspecify

59788 of 78013 branches covered (76.64%)

Branch coverage included in aggregate %.

141239 of 167496 relevant lines covered (84.32%)

3.6 hits per line

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

95.31
today-context/src/main/java/infra/scheduling/support/SimpleAsyncTaskSchedulerBuilder.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.scheduling.support;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.time.Duration;
23
import java.util.Arrays;
24
import java.util.Collections;
25
import java.util.LinkedHashSet;
26
import java.util.Set;
27

28
import infra.core.task.TaskDecorator;
29
import infra.lang.Assert;
30
import infra.scheduling.concurrent.SimpleAsyncTaskScheduler;
31
import infra.util.CollectionUtils;
32

33
/**
34
 * Builder that can be used to configure and create a {@link SimpleAsyncTaskScheduler}.
35
 * Provides convenience methods to set common {@link SimpleAsyncTaskScheduler} settings.
36
 * For advanced configuration, consider using {@link SimpleAsyncTaskSchedulerCustomizer}.
37
 * <p>
38
 * In a typical auto-configured Infra application this builder is available as a
39
 * bean and can be injected whenever a {@link SimpleAsyncTaskScheduler} is needed.
40
 *
41
 * @author Stephane Nicoll
42
 * @author Moritz Halbritter
43
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
44
 * @since 4.0
45
 */
46
public class SimpleAsyncTaskSchedulerBuilder {
47

48
  @Nullable
49
  private final String threadNamePrefix;
50

51
  @Nullable
52
  private final Integer concurrencyLimit;
53

54
  @Nullable
55
  private final Boolean virtualThreads;
56

57
  @Nullable
58
  private final Set<SimpleAsyncTaskSchedulerCustomizer> customizers;
59

60
  @Nullable
61
  private final Duration taskTerminationTimeout;
62

63
  @Nullable
64
  private final TaskDecorator taskDecorator;
65

66
  public SimpleAsyncTaskSchedulerBuilder() {
67
    this(null, null, null,
8✔
68
            null, null, null);
69
  }
1✔
70

71
  private SimpleAsyncTaskSchedulerBuilder(@Nullable String threadNamePrefix,
72
          @Nullable Integer concurrencyLimit, @Nullable Boolean virtualThreads,
73
          @Nullable Set<SimpleAsyncTaskSchedulerCustomizer> taskSchedulerCustomizers,
74
          @Nullable Duration taskTerminationTimeout, @Nullable TaskDecorator taskDecorator) {
2✔
75
    this.threadNamePrefix = threadNamePrefix;
3✔
76
    this.concurrencyLimit = concurrencyLimit;
3✔
77
    this.virtualThreads = virtualThreads;
3✔
78
    this.customizers = taskSchedulerCustomizers;
3✔
79
    this.taskTerminationTimeout = taskTerminationTimeout;
3✔
80
    this.taskDecorator = taskDecorator;
3✔
81
  }
1✔
82

83
  /**
84
   * Set the prefix to use for the names of newly created threads.
85
   *
86
   * @param threadNamePrefix the thread name prefix to set
87
   * @return a new builder instance
88
   */
89
  public SimpleAsyncTaskSchedulerBuilder threadNamePrefix(String threadNamePrefix) {
90
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, this.virtualThreads,
15✔
91
            customizers, taskTerminationTimeout, taskDecorator);
92
  }
93

94
  /**
95
   * Set the concurrency limit.
96
   *
97
   * @param concurrencyLimit the concurrency limit
98
   * @return a new builder instance
99
   */
100
  public SimpleAsyncTaskSchedulerBuilder concurrencyLimit(@Nullable Integer concurrencyLimit) {
101
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, virtualThreads,
15✔
102
            customizers, taskTerminationTimeout, taskDecorator);
103
  }
104

105
  /**
106
   * Set whether to use virtual threads.
107
   *
108
   * @param virtualThreads whether to use virtual threads
109
   * @return a new builder instance
110
   */
111
  public SimpleAsyncTaskSchedulerBuilder virtualThreads(Boolean virtualThreads) {
112
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, virtualThreads,
×
113
            customizers, taskTerminationTimeout, taskDecorator);
114
  }
115

116
  /**
117
   * Set the task termination timeout.
118
   *
119
   * @param taskTerminationTimeout the task termination timeout
120
   * @return a new builder instance
121
   */
122
  public SimpleAsyncTaskSchedulerBuilder taskTerminationTimeout(@Nullable Duration taskTerminationTimeout) {
123
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, virtualThreads,
15✔
124
            customizers, taskTerminationTimeout, taskDecorator);
125
  }
126

127
  /**
128
   * Set the task decorator to be used by the {@link SimpleAsyncTaskScheduler}.
129
   *
130
   * @param taskDecorator the task decorator to set
131
   * @return a new builder instance
132
   * @since 5.0
133
   */
134
  public SimpleAsyncTaskSchedulerBuilder taskDecorator(@Nullable TaskDecorator taskDecorator) {
135
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, virtualThreads,
15✔
136
            customizers, taskTerminationTimeout, taskDecorator);
137
  }
138

139
  /**
140
   * Set the {@link SimpleAsyncTaskSchedulerCustomizer customizers} that should be
141
   * applied to the {@link SimpleAsyncTaskScheduler}. Customizers are applied in the
142
   * order that they were added after builder configuration has been applied. Setting
143
   * this value will replace any previously configured customizers.
144
   *
145
   * @param customizers the customizers to set
146
   * @return a new builder instance
147
   * @see #additionalCustomizers(SimpleAsyncTaskSchedulerCustomizer...)
148
   */
149
  public SimpleAsyncTaskSchedulerBuilder customizers(SimpleAsyncTaskSchedulerCustomizer... customizers) {
150
    Assert.notNull(customizers, "Customizers is required");
3✔
151
    return customizers(Arrays.asList(customizers));
5✔
152
  }
153

154
  /**
155
   * Set the {@link SimpleAsyncTaskSchedulerCustomizer customizers} that should be
156
   * applied to the {@link SimpleAsyncTaskScheduler}. Customizers are applied in the
157
   * order that they were added after builder configuration has been applied. Setting
158
   * this value will replace any previously configured customizers.
159
   *
160
   * @param customizers the customizers to set
161
   * @return a new builder instance
162
   * @see #additionalCustomizers(Iterable)
163
   */
164
  public SimpleAsyncTaskSchedulerBuilder customizers(Iterable<? extends SimpleAsyncTaskSchedulerCustomizer> customizers) {
165
    Assert.notNull(customizers, "Customizers is required");
3✔
166
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, virtualThreads,
12✔
167
            append(null, customizers), taskTerminationTimeout, taskDecorator);
6✔
168
  }
169

170
  /**
171
   * Add {@link SimpleAsyncTaskSchedulerCustomizer customizers} that should be applied
172
   * to the {@link SimpleAsyncTaskScheduler}. Customizers are applied in the order that
173
   * they were added after builder configuration has been applied.
174
   *
175
   * @param customizers the customizers to add
176
   * @return a new builder instance
177
   * @see #customizers(SimpleAsyncTaskSchedulerCustomizer...)
178
   */
179
  public SimpleAsyncTaskSchedulerBuilder additionalCustomizers(SimpleAsyncTaskSchedulerCustomizer... customizers) {
180
    Assert.notNull(customizers, "Customizers is required");
3✔
181
    return additionalCustomizers(Arrays.asList(customizers));
5✔
182
  }
183

184
  /**
185
   * Add {@link SimpleAsyncTaskSchedulerCustomizer customizers} that should be applied
186
   * to the {@link SimpleAsyncTaskScheduler}. Customizers are applied in the order that
187
   * they were added after builder configuration has been applied.
188
   *
189
   * @param customizers the customizers to add
190
   * @return a new builder instance
191
   * @see #customizers(Iterable)
192
   */
193
  public SimpleAsyncTaskSchedulerBuilder additionalCustomizers(Iterable<? extends SimpleAsyncTaskSchedulerCustomizer> customizers) {
194
    Assert.notNull(customizers, "Customizers is required");
3✔
195
    return new SimpleAsyncTaskSchedulerBuilder(threadNamePrefix, concurrencyLimit, virtualThreads,
13✔
196
            append(this.customizers, customizers), taskTerminationTimeout, taskDecorator);
6✔
197
  }
198

199
  /**
200
   * Build a new {@link SimpleAsyncTaskScheduler} instance and configure it using this
201
   * builder.
202
   *
203
   * @return a configured {@link SimpleAsyncTaskScheduler} instance.
204
   * @see #configure(SimpleAsyncTaskScheduler)
205
   */
206
  public SimpleAsyncTaskScheduler build() {
207
    return configure(new SimpleAsyncTaskScheduler());
6✔
208
  }
209

210
  /**
211
   * Configure the provided {@link SimpleAsyncTaskScheduler} instance using this
212
   * builder.
213
   *
214
   * @param <T> the type of task scheduler
215
   * @param taskScheduler the {@link SimpleAsyncTaskScheduler} to configure
216
   * @return the task scheduler instance
217
   * @see #build()
218
   */
219
  public <T extends SimpleAsyncTaskScheduler> T configure(T taskScheduler) {
220
    if (threadNamePrefix != null) {
3✔
221
      taskScheduler.setThreadNamePrefix(threadNamePrefix);
4✔
222
    }
223
    if (concurrencyLimit != null) {
3✔
224
      taskScheduler.setConcurrencyLimit(concurrencyLimit);
5✔
225
    }
226

227
    if (virtualThreads != null) {
3!
228
      taskScheduler.setVirtualThreads(virtualThreads);
×
229
    }
230
    if (taskTerminationTimeout != null) {
3✔
231
      taskScheduler.setTaskTerminationTimeout(taskTerminationTimeout.toMillis());
5✔
232
    }
233

234
    if (CollectionUtils.isNotEmpty(this.customizers)) {
4✔
235
      for (SimpleAsyncTaskSchedulerCustomizer customizer : customizers) {
11✔
236
        customizer.customize(taskScheduler);
3✔
237
      }
1✔
238
    }
239

240
    if (taskDecorator != null) {
3✔
241
      taskScheduler.setTaskDecorator(taskDecorator);
4✔
242
    }
243

244
    return taskScheduler;
2✔
245
  }
246

247
  private <T> Set<T> append(@Nullable Set<T> set, Iterable<? extends T> additions) {
248
    LinkedHashSet<T> result = new LinkedHashSet<>((set != null) ? set : Collections.emptySet());
9✔
249
    for (T addition : additions) {
9✔
250
      result.add(addition);
4✔
251
    }
1✔
252
    return Collections.unmodifiableSet(result);
3✔
253
  }
254

255
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc