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

temporalio / sdk-java / #244

10 Apr 2024 08:19PM UTC coverage: 77.465% (-0.08%) from 77.549%
#244

push

github

web-flow
Slot supplier interface & fixed-size implementation (#2014)

https://github.com/temporalio/proposals/blob/master/all-sdk/autotuning.md

286 of 388 new or added lines in 25 files covered. (73.71%)

3 existing lines in 3 files now uncovered.

19116 of 24677 relevant lines covered (77.46%)

0.77 hits per line

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

80.29
/temporal-sdk/src/main/java/io/temporal/worker/WorkerOptions.java
1
/*
2
 * Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3
 *
4
 * Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
 *
6
 * Modifications copyright (C) 2017 Uber Technologies, Inc.
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this material except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *   http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20

21
package io.temporal.worker;
22

23
import static java.lang.Double.compare;
24

25
import com.google.common.base.Preconditions;
26
import io.temporal.common.Experimental;
27
import io.temporal.serviceclient.WorkflowServiceStubsOptions;
28
import io.temporal.worker.tuning.*;
29
import java.time.Duration;
30
import java.util.Objects;
31
import javax.annotation.Nonnull;
32
import javax.annotation.Nullable;
33

34
public final class WorkerOptions {
35

36
  public static Builder newBuilder() {
37
    return new Builder();
1✔
38
  }
39

40
  public static Builder newBuilder(WorkerOptions options) {
41
    return new Builder(options);
1✔
42
  }
43

44
  public static WorkerOptions getDefaultInstance() {
45
    return DEFAULT_INSTANCE;
1✔
46
  }
47

48
  static final Duration DEFAULT_STICKY_SCHEDULE_TO_START_TIMEOUT = Duration.ofSeconds(5);
1✔
49

50
  static final Duration DEFAULT_STICKY_TASK_QUEUE_DRAIN_TIMEOUT = Duration.ofSeconds(0);
1✔
51

52
  private static final WorkerOptions DEFAULT_INSTANCE;
53

54
  static {
55
    DEFAULT_INSTANCE = WorkerOptions.newBuilder().validateAndBuildWithDefaults();
1✔
56
  }
1✔
57

58
  public static final class Builder {
59

60
    private static final int DEFAULT_MAX_CONCURRENT_WORKFLOW_TASK_POLLERS = 5;
61
    private static final int DEFAULT_MAX_CONCURRENT_ACTIVITY_TASK_POLLERS = 5;
62
    private static final int DEFAULT_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTION_SIZE = 200;
63
    private static final int DEFAULT_MAX_CONCURRENT_ACTIVITY_EXECUTION_SIZE = 200;
64
    private static final int DEFAULT_MAX_CONCURRENT_LOCAL_ACTIVITY_EXECUTION_SIZE = 200;
65
    private static final long DEFAULT_DEADLOCK_DETECTION_TIMEOUT = 1000;
66
    private static final Duration DEFAULT_MAX_HEARTBEAT_THROTTLE_INTERVAL = Duration.ofSeconds(60);
1✔
67
    private static final Duration DEFAULT_DEFAULT_HEARTBEAT_THROTTLE_INTERVAL =
1✔
68
        Duration.ofSeconds(30);
1✔
69

70
    private double maxWorkerActivitiesPerSecond;
71
    private int maxConcurrentActivityExecutionSize;
72
    private int maxConcurrentWorkflowTaskExecutionSize;
73
    private int maxConcurrentLocalActivityExecutionSize;
74
    private double maxTaskQueueActivitiesPerSecond;
75
    private int maxConcurrentWorkflowTaskPollers;
76
    private int maxConcurrentActivityTaskPollers;
77
    private boolean localActivityWorkerOnly;
78
    private long defaultDeadlockDetectionTimeout;
79
    private Duration maxHeartbeatThrottleInterval;
80
    private Duration defaultHeartbeatThrottleInterval;
81
    private Duration stickyQueueScheduleToStartTimeout;
82
    private boolean disableEagerExecution;
83
    private String buildId;
84
    private boolean useBuildIdForVersioning;
85
    private Duration stickyTaskQueueDrainTimeout;
86
    private SlotSupplier<WorkflowSlotInfo> workflowSlotSupplier;
87
    private SlotSupplier<ActivitySlotInfo> activitySlotSupplier;
88
    private SlotSupplier<LocalActivitySlotInfo> localActivitySlotSupplier;
89

90
    private Builder() {}
91

92
    private Builder(WorkerOptions o) {
1✔
93
      if (o == null) {
1✔
94
        return;
1✔
95
      }
96
      this.maxWorkerActivitiesPerSecond = o.maxWorkerActivitiesPerSecond;
1✔
97
      this.maxConcurrentActivityExecutionSize = o.maxConcurrentActivityExecutionSize;
1✔
98
      this.maxConcurrentWorkflowTaskExecutionSize = o.maxConcurrentWorkflowTaskExecutionSize;
1✔
99
      this.maxConcurrentLocalActivityExecutionSize = o.maxConcurrentLocalActivityExecutionSize;
1✔
100
      this.workflowSlotSupplier = o.workflowSlotSupplier;
1✔
101
      this.activitySlotSupplier = o.activitySlotSupplier;
1✔
102
      this.localActivitySlotSupplier = o.localActivitySlotSupplier;
1✔
103
      this.maxTaskQueueActivitiesPerSecond = o.maxTaskQueueActivitiesPerSecond;
1✔
104
      this.maxConcurrentWorkflowTaskPollers = o.maxConcurrentWorkflowTaskPollers;
1✔
105
      this.maxConcurrentActivityTaskPollers = o.maxConcurrentActivityTaskPollers;
1✔
106
      this.localActivityWorkerOnly = o.localActivityWorkerOnly;
1✔
107
      this.defaultDeadlockDetectionTimeout = o.defaultDeadlockDetectionTimeout;
1✔
108
      this.maxHeartbeatThrottleInterval = o.maxHeartbeatThrottleInterval;
1✔
109
      this.defaultHeartbeatThrottleInterval = o.defaultHeartbeatThrottleInterval;
1✔
110
      this.stickyQueueScheduleToStartTimeout = o.stickyQueueScheduleToStartTimeout;
1✔
111
      this.disableEagerExecution = o.disableEagerExecution;
1✔
112
      this.useBuildIdForVersioning = o.useBuildIdForVersioning;
1✔
113
      this.buildId = o.buildId;
1✔
114
      this.stickyTaskQueueDrainTimeout = o.stickyTaskQueueDrainTimeout;
1✔
115
    }
1✔
116

117
    /**
118
     * @param maxWorkerActivitiesPerSecond Maximum number of activities started per second by this
119
     *     worker. Default is 0 which means unlimited.
120
     * @return {@code this}
121
     *     <p>If worker is not fully loaded while tasks are backing up on the service consider
122
     *     increasing {@link #setMaxConcurrentActivityTaskPollers(int)}.
123
     *     <p>Note that this is a per worker limit. Use {@link
124
     *     #setMaxTaskQueueActivitiesPerSecond(double)} to set per task queue limit across multiple
125
     *     workers.
126
     */
127
    public Builder setMaxWorkerActivitiesPerSecond(double maxWorkerActivitiesPerSecond) {
128
      if (maxWorkerActivitiesPerSecond < 0) {
1✔
129
        throw new IllegalArgumentException(
×
130
            "Negative maxWorkerActivitiesPerSecond value: " + maxWorkerActivitiesPerSecond);
131
      }
132
      this.maxWorkerActivitiesPerSecond = maxWorkerActivitiesPerSecond;
1✔
133
      return this;
1✔
134
    }
135

136
    /**
137
     * @param maxConcurrentActivityExecutionSize Maximum number of activities executed in parallel.
138
     *     Default is 200, which is chosen if set to zero.
139
     * @return {@code this}
140
     *     <p>Note setting is mutually exclusive with {@link
141
     *     #setActivitySlotSupplier(SlotSupplier)}.
142
     */
143
    public Builder setMaxConcurrentActivityExecutionSize(int maxConcurrentActivityExecutionSize) {
144
      if (maxConcurrentActivityExecutionSize < 0) {
1✔
145
        throw new IllegalArgumentException(
×
146
            "Negative maxConcurrentActivityExecutionSize value: "
147
                + maxConcurrentActivityExecutionSize);
148
      }
149
      this.maxConcurrentActivityExecutionSize = maxConcurrentActivityExecutionSize;
1✔
150
      return this;
1✔
151
    }
152

153
    /**
154
     * @param maxConcurrentWorkflowTaskExecutionSize Maximum number of simultaneously executed
155
     *     workflow tasks. Default is 200, which is chosen if set to zero.
156
     * @return {@code this}
157
     *     <p>Note that this is not related to the total number of open workflows which do not need
158
     *     to be loaded in a worker when they are not making state transitions.
159
     *     <p>Note setting is mutually exclusive with {@link #setWorkflowSlotSupplier(SlotSupplier)}
160
     */
161
    public Builder setMaxConcurrentWorkflowTaskExecutionSize(
162
        int maxConcurrentWorkflowTaskExecutionSize) {
163
      if (maxConcurrentWorkflowTaskExecutionSize < 0) {
1✔
164
        throw new IllegalArgumentException(
×
165
            "Negative maxConcurrentWorkflowTaskExecutionSize value: "
166
                + maxConcurrentWorkflowTaskExecutionSize);
167
      }
168
      this.maxConcurrentWorkflowTaskExecutionSize = maxConcurrentWorkflowTaskExecutionSize;
1✔
169
      return this;
1✔
170
    }
171

172
    /**
173
     * @param maxConcurrentLocalActivityExecutionSize Maximum number of local activities executed in
174
     *     parallel. Default is 200, which is chosen if set to zero.
175
     * @return {@code this}
176
     *     <p>Note setting is mutually exclusive with {@link
177
     *     #setLocalActivitySlotSupplier(SlotSupplier)}
178
     */
179
    public Builder setMaxConcurrentLocalActivityExecutionSize(
180
        int maxConcurrentLocalActivityExecutionSize) {
181
      if (maxConcurrentLocalActivityExecutionSize < 0) {
1✔
182
        throw new IllegalArgumentException(
×
183
            "Negative maxConcurrentLocalActivityExecutionSize value: "
184
                + maxConcurrentLocalActivityExecutionSize);
185
      }
186
      this.maxConcurrentLocalActivityExecutionSize = maxConcurrentLocalActivityExecutionSize;
1✔
187
      return this;
1✔
188
    }
189

190
    /**
191
     * Optional: Sets the rate limiting on number of activities that can be executed per second.
192
     * This is managed by the server and controls activities per second for the entire task queue
193
     * across all the workers. Notice that the number is represented in double, so that you can set
194
     * it to less than 1 if needed. For example, set the number to 0.1 means you want your activity
195
     * to be executed once every 10 seconds. This can be used to protect down stream services from
196
     * flooding. The zero value of this uses the default value. Default is unlimited.
197
     */
198
    public Builder setMaxTaskQueueActivitiesPerSecond(double maxTaskQueueActivitiesPerSecond) {
199
      this.maxTaskQueueActivitiesPerSecond = maxTaskQueueActivitiesPerSecond;
1✔
200
      return this;
1✔
201
    }
202

203
    /**
204
     * Sets the maximum number of simultaneous long poll requests to the Temporal Server to retrieve
205
     * workflow tasks. Changing this value will affect the rate at which the worker is able to
206
     * consume tasks from a task queue.
207
     *
208
     * <p>Due to internal logic where pollers alternate between sticky and non-sticky queues, this
209
     * value cannot be 1 and will be adjusted to 2 if set to that value.
210
     *
211
     * <p>Default is 5, which is chosen if set to zero.
212
     */
213
    public Builder setMaxConcurrentWorkflowTaskPollers(int maxConcurrentWorkflowTaskPollers) {
214
      this.maxConcurrentWorkflowTaskPollers = maxConcurrentWorkflowTaskPollers;
1✔
215
      return this;
1✔
216
    }
217

218
    /**
219
     * Number of simultaneous poll requests on workflow task queue. Note that the majority of the
220
     * workflow tasks will be using host local task queue due to caching. So try incrementing {@link
221
     * WorkerFactoryOptions.Builder#setWorkflowHostLocalPollThreadCount(int)} before this one.
222
     *
223
     * <p>Default is 5, which is chosen if set to zero.
224
     *
225
     * @deprecated Use {@link #setMaxConcurrentWorkflowTaskPollers}
226
     */
227
    @Deprecated
228
    public Builder setWorkflowPollThreadCount(int workflowPollThreadCount) {
229
      return setMaxConcurrentWorkflowTaskPollers(workflowPollThreadCount);
×
230
    }
231

232
    /**
233
     * Number of simultaneous poll requests on activity task queue. Consider incrementing if the
234
     * worker is not throttled due to `MaxActivitiesPerSecond` or
235
     * `MaxConcurrentActivityExecutionSize` options and still cannot keep up with the request rate.
236
     *
237
     * <p>Default is 5, which is chosen if set to zero.
238
     */
239
    public Builder setMaxConcurrentActivityTaskPollers(int maxConcurrentActivityTaskPollers) {
240
      this.maxConcurrentActivityTaskPollers = maxConcurrentActivityTaskPollers;
1✔
241
      return this;
1✔
242
    }
243

244
    /**
245
     * Number of simultaneous poll requests on activity task queue. Consider incrementing if the
246
     * worker is not throttled due to `MaxActivitiesPerSecond` or
247
     * `MaxConcurrentActivityExecutionSize` options and still cannot keep up with the request rate.
248
     *
249
     * <p>Default is 5, which is chosen if set to zero.
250
     *
251
     * @deprecated Use {@link #setMaxConcurrentActivityTaskPollers}
252
     */
253
    @Deprecated
254
    public Builder setActivityPollThreadCount(int activityPollThreadCount) {
255
      return setMaxConcurrentActivityTaskPollers(activityPollThreadCount);
×
256
    }
257

258
    /**
259
     * If set to true worker would only handle workflow tasks and local activities. Non-local
260
     * activities will not be executed by this worker.
261
     *
262
     * <p>Default is false.
263
     */
264
    public Builder setLocalActivityWorkerOnly(boolean localActivityWorkerOnly) {
265
      this.localActivityWorkerOnly = localActivityWorkerOnly;
1✔
266
      return this;
1✔
267
    }
268

269
    /**
270
     * @param defaultDeadlockDetectionTimeoutMs time period in ms that will be used to detect
271
     *     workflows deadlock. Default is 1000ms, which is chosen if set to zero.
272
     *     <p>Specifies an amount of time in milliseconds that workflow tasks are allowed to execute
273
     *     without interruption. If workflow task runs longer than specified interval without
274
     *     yielding (like calling an Activity), it will fail automatically.
275
     * @return {@code this}
276
     * @see io.temporal.internal.sync.PotentialDeadlockException
277
     */
278
    public Builder setDefaultDeadlockDetectionTimeout(long defaultDeadlockDetectionTimeoutMs) {
279
      if (defaultDeadlockDetectionTimeoutMs < 0) {
1✔
280
        throw new IllegalArgumentException(
×
281
            "Negative defaultDeadlockDetectionTimeout value: " + defaultDeadlockDetectionTimeoutMs);
282
      }
283
      this.defaultDeadlockDetectionTimeout = defaultDeadlockDetectionTimeoutMs;
1✔
284
      return this;
1✔
285
    }
286

287
    /**
288
     * @param interval the maximum amount of time between sending each pending heartbeat to the
289
     *     server. Regardless of heartbeat timeout, no pending heartbeat will wait longer than this
290
     *     amount of time to send. Default is 60s, which is chosen if set to null or 0.
291
     * @return {@code this}
292
     */
293
    public Builder setMaxHeartbeatThrottleInterval(@Nullable Duration interval) {
294
      Preconditions.checkArgument(
×
295
          interval == null || !interval.isNegative(),
×
296
          "Negative maxHeartbeatThrottleInterval value: %s",
297
          interval);
298
      this.maxHeartbeatThrottleInterval = interval;
×
299
      return this;
×
300
    }
301

302
    /**
303
     * @param interval the default amount of time between sending each pending heartbeat to the
304
     *     server. This is used if the ActivityOptions do not provide a HeartbeatTimeout. Otherwise,
305
     *     the interval becomes a value a bit smaller than the given HeartbeatTimeout. Default is
306
     *     30s, which is chosen if set to null or 0.
307
     * @return {@code this}
308
     */
309
    public Builder setDefaultHeartbeatThrottleInterval(@Nullable Duration interval) {
310
      Preconditions.checkArgument(
×
311
          interval == null || !interval.isNegative(),
×
312
          "Negative defaultHeartbeatThrottleInterval value: %s",
313
          interval);
314
      this.defaultHeartbeatThrottleInterval = interval;
×
315
      return this;
×
316
    }
317

318
    /**
319
     * Timeout for a workflow task routed to the "sticky worker" - host that has the workflow
320
     * instance cached in memory. Once it times out, then it can be picked up by any worker.
321
     *
322
     * <p>Default value is 5 seconds.
323
     */
324
    public Builder setStickyQueueScheduleToStartTimeout(Duration timeout) {
325
      this.stickyQueueScheduleToStartTimeout = timeout;
1✔
326
      return this;
1✔
327
    }
328

329
    /**
330
     * Disable eager activities. If set to true, eager execution will not be requested for
331
     * activities requested from workflows bound to this Worker.
332
     *
333
     * <p>Eager activity execution means the server returns requested eager activities directly from
334
     * the workflow task back to this worker which is faster than non-eager which may be dispatched
335
     * to a separate worker.
336
     *
337
     * <p>Defaults to false, meaning that eager activity execution is permitted
338
     */
339
    public Builder setDisableEagerExecution(boolean disableEagerExecution) {
340
      this.disableEagerExecution = disableEagerExecution;
×
341
      return this;
×
342
    }
343

344
    /**
345
     * Opts the worker in to the Build-ID-based versioning feature. This ensures that the worker
346
     * will only receive tasks which it is compatible with. For more information see: TODO: Doc link
347
     *
348
     * <p>Defaults to false
349
     */
350
    @Experimental
351
    public Builder setUseBuildIdForVersioning(boolean useBuildIdForVersioning) {
352
      this.useBuildIdForVersioning = useBuildIdForVersioning;
1✔
353
      return this;
1✔
354
    }
355

356
    /**
357
     * Set a unique identifier for this worker. The identifier should be stable with respect to the
358
     * code the worker uses for workflows, activities, and interceptors. For more information see:
359
     * TODO: Doc link
360
     *
361
     * <p>A Build Id must be set if {@link #setUseBuildIdForVersioning(boolean)} is set true.
362
     */
363
    @Experimental
364
    public Builder setBuildId(String buildId) {
365
      this.buildId = buildId;
1✔
366
      return this;
1✔
367
    }
368

369
    /**
370
     * During graceful shutdown, as when calling {@link WorkerFactory#shutdown()}, if the workflow
371
     * cache is enabled, this timeout controls how long to wait for the sticky task queue to drain
372
     * before shutting down the worker. If set the worker will stop making new poll requests on the
373
     * normal task queue, but will continue to poll the sticky task queue until the timeout is
374
     * reached. This value should always be greater than clients rpc long poll timeout, which can be
375
     * set via {@link WorkflowServiceStubsOptions.Builder#setRpcLongPollTimeout(Duration)}.
376
     *
377
     * <p>Default is not to wait.
378
     */
379
    @Experimental
380
    public Builder setStickyTaskQueueDrainTimeout(Duration stickyTaskQueueDrainTimeout) {
381
      this.stickyTaskQueueDrainTimeout = stickyTaskQueueDrainTimeout;
1✔
382
      return this;
1✔
383
    }
384

385
    /**
386
     * Set the {@link SlotSupplier} for workflow tasks.
387
     *
388
     * <p>Note that this setting is mutually exclusive with {@link
389
     * #setMaxConcurrentWorkflowTaskExecutionSize(int)}.
390
     */
391
    @Experimental
392
    public void setWorkflowSlotSupplier(SlotSupplier<WorkflowSlotInfo> workflowSlotSupplier) {
NEW
393
      this.workflowSlotSupplier = workflowSlotSupplier;
×
NEW
394
    }
×
395

396
    /**
397
     * Set the {@link SlotSupplier} for activity tasks.
398
     *
399
     * <p>Note that this setting is mutually exclusive with {@link
400
     * #setMaxConcurrentActivityExecutionSize(int)}.
401
     */
402
    @Experimental
403
    public void setActivitySlotSupplier(SlotSupplier<ActivitySlotInfo> activitySlotSupplier) {
NEW
404
      this.activitySlotSupplier = activitySlotSupplier;
×
NEW
405
    }
×
406

407
    /**
408
     * Set the {@link SlotSupplier} for local activity tasks.
409
     *
410
     * <p>Note that this setting is mutually exclusive with {@link
411
     * #setMaxConcurrentLocalActivityExecutionSize(int)}.
412
     */
413
    @Experimental
414
    public void setLocalActivitySlotSupplier(
415
        SlotSupplier<LocalActivitySlotInfo> localActivitySlotSupplier) {
NEW
416
      this.localActivitySlotSupplier = localActivitySlotSupplier;
×
NEW
417
    }
×
418

419
    public WorkerOptions build() {
420
      return new WorkerOptions(
1✔
421
          maxWorkerActivitiesPerSecond,
422
          maxConcurrentActivityExecutionSize,
423
          maxConcurrentWorkflowTaskExecutionSize,
424
          maxConcurrentLocalActivityExecutionSize,
425
          workflowSlotSupplier,
426
          activitySlotSupplier,
427
          localActivitySlotSupplier,
428
          maxTaskQueueActivitiesPerSecond,
429
          maxConcurrentWorkflowTaskPollers,
430
          maxConcurrentActivityTaskPollers,
431
          localActivityWorkerOnly,
432
          defaultDeadlockDetectionTimeout,
433
          maxHeartbeatThrottleInterval,
434
          defaultHeartbeatThrottleInterval,
435
          stickyQueueScheduleToStartTimeout,
436
          disableEagerExecution,
437
          useBuildIdForVersioning,
438
          buildId,
439
          stickyTaskQueueDrainTimeout);
440
    }
441

442
    public WorkerOptions validateAndBuildWithDefaults() {
443
      Preconditions.checkState(
1✔
444
          maxWorkerActivitiesPerSecond >= 0, "negative maxActivitiesPerSecond");
445
      Preconditions.checkState(
1✔
446
          maxConcurrentActivityExecutionSize >= 0, "negative maxConcurrentActivityExecutionSize");
447
      Preconditions.checkState(
1✔
448
          maxConcurrentWorkflowTaskExecutionSize >= 0,
449
          "negative maxConcurrentWorkflowTaskExecutionSize");
450
      Preconditions.checkState(
1✔
451
          maxConcurrentLocalActivityExecutionSize >= 0,
452
          "negative maxConcurrentLocalActivityExecutionSize");
453
      if (activitySlotSupplier != null) {
1✔
NEW
454
        Preconditions.checkState(
×
455
            maxConcurrentActivityExecutionSize == 0,
456
            "maxConcurrentActivityExecutionSize must not be set if activitySlotSupplier is set");
457
      }
458
      if (workflowSlotSupplier != null) {
1✔
NEW
459
        Preconditions.checkState(
×
460
            maxConcurrentWorkflowTaskExecutionSize == 0,
461
            "maxConcurrentWorkflowTaskExecutionSize must not be set if workflowSlotSupplier is set");
462
      }
463
      if (localActivitySlotSupplier != null) {
1✔
NEW
464
        Preconditions.checkState(
×
465
            maxConcurrentLocalActivityExecutionSize == 0,
466
            "maxConcurrentLocalActivityExecutionSize must not be set if localActivitySlotSupplier is set");
467
      }
468
      Preconditions.checkState(
1✔
469
          maxTaskQueueActivitiesPerSecond >= 0, "negative taskQueueActivitiesPerSecond");
470
      Preconditions.checkState(
1✔
471
          maxConcurrentWorkflowTaskPollers >= 0, "negative maxConcurrentWorkflowTaskPollers");
472
      Preconditions.checkState(
1✔
473
          maxConcurrentActivityTaskPollers >= 0, "negative maxConcurrentActivityTaskPollers");
474
      Preconditions.checkState(
1✔
475
          defaultDeadlockDetectionTimeout >= 0, "negative defaultDeadlockDetectionTimeout");
476
      Preconditions.checkState(
1✔
477
          stickyQueueScheduleToStartTimeout == null
478
              || !stickyQueueScheduleToStartTimeout.isNegative(),
1✔
479
          "negative stickyQueueScheduleToStartTimeout");
480
      if (useBuildIdForVersioning) {
1✔
481
        Preconditions.checkState(
1✔
482
            buildId != null && !buildId.isEmpty(),
1✔
483
            "buildId must be set non-empty if useBuildIdForVersioning is set true");
484
      }
485
      Preconditions.checkState(
1✔
486
          stickyTaskQueueDrainTimeout == null || !stickyTaskQueueDrainTimeout.isNegative(),
1✔
487
          "negative stickyTaskQueueDrainTimeout");
488

489
      return new WorkerOptions(
1✔
490
          maxWorkerActivitiesPerSecond,
491
          maxConcurrentActivityExecutionSize == 0
1✔
492
              ? DEFAULT_MAX_CONCURRENT_ACTIVITY_EXECUTION_SIZE
1✔
493
              : maxConcurrentActivityExecutionSize,
1✔
494
          maxConcurrentWorkflowTaskExecutionSize == 0
1✔
495
              ? DEFAULT_MAX_CONCURRENT_WORKFLOW_TASK_EXECUTION_SIZE
1✔
496
              : maxConcurrentWorkflowTaskExecutionSize,
1✔
497
          maxConcurrentLocalActivityExecutionSize == 0
1✔
498
              ? DEFAULT_MAX_CONCURRENT_LOCAL_ACTIVITY_EXECUTION_SIZE
1✔
499
              : maxConcurrentLocalActivityExecutionSize,
1✔
500
          workflowSlotSupplier,
501
          activitySlotSupplier,
502
          localActivitySlotSupplier,
503
          maxTaskQueueActivitiesPerSecond,
504
          maxConcurrentWorkflowTaskPollers == 0
1✔
505
              ? DEFAULT_MAX_CONCURRENT_WORKFLOW_TASK_POLLERS
1✔
506
              : maxConcurrentWorkflowTaskPollers,
1✔
507
          maxConcurrentActivityTaskPollers == 0
1✔
508
              ? DEFAULT_MAX_CONCURRENT_ACTIVITY_TASK_POLLERS
1✔
509
              : maxConcurrentActivityTaskPollers,
1✔
510
          localActivityWorkerOnly,
511
          defaultDeadlockDetectionTimeout == 0
1✔
512
              ? DEFAULT_DEADLOCK_DETECTION_TIMEOUT
1✔
513
              : defaultDeadlockDetectionTimeout,
1✔
514
          maxHeartbeatThrottleInterval == null || maxHeartbeatThrottleInterval.isZero()
1✔
515
              ? DEFAULT_MAX_HEARTBEAT_THROTTLE_INTERVAL
1✔
516
              : maxHeartbeatThrottleInterval,
1✔
517
          defaultHeartbeatThrottleInterval == null || defaultHeartbeatThrottleInterval.isZero()
1✔
518
              ? DEFAULT_DEFAULT_HEARTBEAT_THROTTLE_INTERVAL
1✔
519
              : defaultHeartbeatThrottleInterval,
1✔
520
          stickyQueueScheduleToStartTimeout == null
1✔
521
              ? DEFAULT_STICKY_SCHEDULE_TO_START_TIMEOUT
1✔
522
              : stickyQueueScheduleToStartTimeout,
1✔
523
          disableEagerExecution,
524
          useBuildIdForVersioning,
525
          buildId,
526
          stickyTaskQueueDrainTimeout == null
1✔
527
              ? DEFAULT_STICKY_TASK_QUEUE_DRAIN_TIMEOUT
1✔
528
              : stickyTaskQueueDrainTimeout);
1✔
529
    }
530
  }
531

532
  private final double maxWorkerActivitiesPerSecond;
533
  private final int maxConcurrentActivityExecutionSize;
534
  private final int maxConcurrentWorkflowTaskExecutionSize;
535
  private final int maxConcurrentLocalActivityExecutionSize;
536
  private final SlotSupplier<WorkflowSlotInfo> workflowSlotSupplier;
537
  private final SlotSupplier<ActivitySlotInfo> activitySlotSupplier;
538
  private final SlotSupplier<LocalActivitySlotInfo> localActivitySlotSupplier;
539
  private final double maxTaskQueueActivitiesPerSecond;
540
  private final int maxConcurrentWorkflowTaskPollers;
541
  private final int maxConcurrentActivityTaskPollers;
542
  private final boolean localActivityWorkerOnly;
543
  private final long defaultDeadlockDetectionTimeout;
544
  private final Duration maxHeartbeatThrottleInterval;
545
  private final Duration defaultHeartbeatThrottleInterval;
546
  private final @Nonnull Duration stickyQueueScheduleToStartTimeout;
547
  private final boolean disableEagerExecution;
548
  private final boolean useBuildIdForVersioning;
549
  private final String buildId;
550
  private final Duration stickyTaskQueueDrainTimeout;
551

552
  private WorkerOptions(
553
      double maxWorkerActivitiesPerSecond,
554
      int maxConcurrentActivityExecutionSize,
555
      int maxConcurrentWorkflowTaskExecutionSize,
556
      int maxConcurrentLocalActivityExecutionSize,
557
      SlotSupplier<WorkflowSlotInfo> workflowSlotSupplier,
558
      SlotSupplier<ActivitySlotInfo> activitySlotSupplier,
559
      SlotSupplier<LocalActivitySlotInfo> localActivitySlotSupplier,
560
      double maxTaskQueueActivitiesPerSecond,
561
      int workflowPollThreadCount,
562
      int activityPollThreadCount,
563
      boolean localActivityWorkerOnly,
564
      long defaultDeadlockDetectionTimeout,
565
      Duration maxHeartbeatThrottleInterval,
566
      Duration defaultHeartbeatThrottleInterval,
567
      @Nonnull Duration stickyQueueScheduleToStartTimeout,
568
      boolean disableEagerExecution,
569
      boolean useBuildIdForVersioning,
570
      String buildId,
571
      Duration stickyTaskQueueDrainTimeout) {
1✔
572
    this.maxWorkerActivitiesPerSecond = maxWorkerActivitiesPerSecond;
1✔
573
    this.maxConcurrentActivityExecutionSize = maxConcurrentActivityExecutionSize;
1✔
574
    this.maxConcurrentWorkflowTaskExecutionSize = maxConcurrentWorkflowTaskExecutionSize;
1✔
575
    this.maxConcurrentLocalActivityExecutionSize = maxConcurrentLocalActivityExecutionSize;
1✔
576
    this.workflowSlotSupplier = workflowSlotSupplier;
1✔
577
    this.activitySlotSupplier = activitySlotSupplier;
1✔
578
    this.localActivitySlotSupplier = localActivitySlotSupplier;
1✔
579
    this.maxTaskQueueActivitiesPerSecond = maxTaskQueueActivitiesPerSecond;
1✔
580
    this.maxConcurrentWorkflowTaskPollers = workflowPollThreadCount;
1✔
581
    this.maxConcurrentActivityTaskPollers = activityPollThreadCount;
1✔
582
    this.localActivityWorkerOnly = localActivityWorkerOnly;
1✔
583
    this.defaultDeadlockDetectionTimeout = defaultDeadlockDetectionTimeout;
1✔
584
    this.maxHeartbeatThrottleInterval = maxHeartbeatThrottleInterval;
1✔
585
    this.defaultHeartbeatThrottleInterval = defaultHeartbeatThrottleInterval;
1✔
586
    this.stickyQueueScheduleToStartTimeout = stickyQueueScheduleToStartTimeout;
1✔
587
    this.disableEagerExecution = disableEagerExecution;
1✔
588
    this.useBuildIdForVersioning = useBuildIdForVersioning;
1✔
589
    this.buildId = buildId;
1✔
590
    this.stickyTaskQueueDrainTimeout = stickyTaskQueueDrainTimeout;
1✔
591
  }
1✔
592

593
  public double getMaxWorkerActivitiesPerSecond() {
594
    return maxWorkerActivitiesPerSecond;
1✔
595
  }
596

597
  public int getMaxConcurrentActivityExecutionSize() {
598
    return maxConcurrentActivityExecutionSize;
1✔
599
  }
600

601
  public int getMaxConcurrentWorkflowTaskExecutionSize() {
602
    return maxConcurrentWorkflowTaskExecutionSize;
1✔
603
  }
604

605
  public int getMaxConcurrentLocalActivityExecutionSize() {
606
    return maxConcurrentLocalActivityExecutionSize;
1✔
607
  }
608

609
  public double getMaxTaskQueueActivitiesPerSecond() {
610
    return maxTaskQueueActivitiesPerSecond;
1✔
611
  }
612

613
  /**
614
   * @deprecated use {@link #getMaxConcurrentWorkflowTaskPollers}
615
   */
616
  @Deprecated
617
  public int getWorkflowPollThreadCount() {
618
    return getMaxConcurrentWorkflowTaskPollers();
×
619
  }
620

621
  public int getMaxConcurrentWorkflowTaskPollers() {
622
    return maxConcurrentWorkflowTaskPollers;
1✔
623
  }
624

625
  /**
626
   * @deprecated use {@link #getMaxConcurrentActivityTaskPollers}
627
   */
628
  @Deprecated
629
  public int getActivityPollThreadCount() {
630
    return getMaxConcurrentActivityTaskPollers();
×
631
  }
632

633
  public int getMaxConcurrentActivityTaskPollers() {
634
    return maxConcurrentActivityTaskPollers;
1✔
635
  }
636

637
  public long getDefaultDeadlockDetectionTimeout() {
638
    return defaultDeadlockDetectionTimeout;
1✔
639
  }
640

641
  public boolean isLocalActivityWorkerOnly() {
642
    return localActivityWorkerOnly;
1✔
643
  }
644

645
  public Duration getMaxHeartbeatThrottleInterval() {
646
    return maxHeartbeatThrottleInterval;
1✔
647
  }
648

649
  public Duration getDefaultHeartbeatThrottleInterval() {
650
    return defaultHeartbeatThrottleInterval;
1✔
651
  }
652

653
  @Nonnull
654
  public Duration getStickyQueueScheduleToStartTimeout() {
655
    return stickyQueueScheduleToStartTimeout;
1✔
656
  }
657

658
  public boolean isEagerExecutionDisabled() {
659
    return disableEagerExecution;
1✔
660
  }
661

662
  public boolean isUsingBuildIdForVersioning() {
663
    return useBuildIdForVersioning;
1✔
664
  }
665

666
  public String getBuildId() {
667
    return buildId;
1✔
668
  }
669

670
  public Duration getStickyTaskQueueDrainTimeout() {
671
    return stickyTaskQueueDrainTimeout;
1✔
672
  }
673

674
  public SlotSupplier<WorkflowSlotInfo> getWorkflowSlotSupplier() {
675
    return workflowSlotSupplier;
1✔
676
  }
677

678
  public SlotSupplier<ActivitySlotInfo> getActivitySlotSupplier() {
679
    return activitySlotSupplier;
1✔
680
  }
681

682
  public SlotSupplier<LocalActivitySlotInfo> getLocalActivitySlotSupplier() {
683
    return localActivitySlotSupplier;
1✔
684
  }
685

686
  @Override
687
  public boolean equals(Object o) {
688
    if (this == o) return true;
1✔
689
    if (o == null || getClass() != o.getClass()) return false;
1✔
690
    WorkerOptions that = (WorkerOptions) o;
1✔
691
    return compare(maxWorkerActivitiesPerSecond, that.maxWorkerActivitiesPerSecond) == 0
1✔
692
        && maxConcurrentActivityExecutionSize == that.maxConcurrentActivityExecutionSize
693
        && maxConcurrentWorkflowTaskExecutionSize == that.maxConcurrentWorkflowTaskExecutionSize
694
        && maxConcurrentLocalActivityExecutionSize == that.maxConcurrentLocalActivityExecutionSize
695
        && compare(maxTaskQueueActivitiesPerSecond, that.maxTaskQueueActivitiesPerSecond) == 0
1✔
696
        && maxConcurrentWorkflowTaskPollers == that.maxConcurrentWorkflowTaskPollers
697
        && maxConcurrentActivityTaskPollers == that.maxConcurrentActivityTaskPollers
698
        && localActivityWorkerOnly == that.localActivityWorkerOnly
699
        && defaultDeadlockDetectionTimeout == that.defaultDeadlockDetectionTimeout
700
        && disableEagerExecution == that.disableEagerExecution
701
        && useBuildIdForVersioning == that.useBuildIdForVersioning
702
        && Objects.equals(workflowSlotSupplier, that.workflowSlotSupplier)
1✔
703
        && Objects.equals(activitySlotSupplier, that.activitySlotSupplier)
1✔
704
        && Objects.equals(localActivitySlotSupplier, that.localActivitySlotSupplier)
1✔
705
        && Objects.equals(maxHeartbeatThrottleInterval, that.maxHeartbeatThrottleInterval)
1✔
706
        && Objects.equals(defaultHeartbeatThrottleInterval, that.defaultHeartbeatThrottleInterval)
1✔
707
        && Objects.equals(stickyQueueScheduleToStartTimeout, that.stickyQueueScheduleToStartTimeout)
1✔
708
        && Objects.equals(buildId, that.buildId)
1✔
709
        && Objects.equals(stickyTaskQueueDrainTimeout, that.stickyTaskQueueDrainTimeout);
1✔
710
  }
711

712
  @Override
713
  public int hashCode() {
714
    return Objects.hash(
×
715
        maxWorkerActivitiesPerSecond,
×
716
        maxConcurrentActivityExecutionSize,
×
717
        maxConcurrentWorkflowTaskExecutionSize,
×
718
        maxConcurrentLocalActivityExecutionSize,
×
719
        workflowSlotSupplier,
720
        activitySlotSupplier,
721
        localActivitySlotSupplier,
722
        maxTaskQueueActivitiesPerSecond,
×
723
        maxConcurrentWorkflowTaskPollers,
×
724
        maxConcurrentActivityTaskPollers,
×
725
        localActivityWorkerOnly,
×
726
        defaultDeadlockDetectionTimeout,
×
727
        maxHeartbeatThrottleInterval,
728
        defaultHeartbeatThrottleInterval,
729
        stickyQueueScheduleToStartTimeout,
730
        disableEagerExecution,
×
731
        useBuildIdForVersioning,
×
732
        buildId,
733
        stickyTaskQueueDrainTimeout);
734
  }
735

736
  @Override
737
  public String toString() {
738
    return "WorkerOptions{"
×
739
        + "maxWorkerActivitiesPerSecond="
740
        + maxWorkerActivitiesPerSecond
741
        + ", maxConcurrentActivityExecutionSize="
742
        + maxConcurrentActivityExecutionSize
743
        + ", maxConcurrentWorkflowTaskExecutionSize="
744
        + maxConcurrentWorkflowTaskExecutionSize
745
        + ", maxConcurrentLocalActivityExecutionSize="
746
        + maxConcurrentLocalActivityExecutionSize
747
        + ", workflowSlotSupplier="
748
        + workflowSlotSupplier
749
        + ", activitySlotSupplier="
750
        + activitySlotSupplier
751
        + ", localActivitySlotSupplier="
752
        + localActivitySlotSupplier
753
        + ", maxTaskQueueActivitiesPerSecond="
754
        + maxTaskQueueActivitiesPerSecond
755
        + ", maxConcurrentWorkflowTaskPollers="
756
        + maxConcurrentWorkflowTaskPollers
757
        + ", maxConcurrentActivityTaskPollers="
758
        + maxConcurrentActivityTaskPollers
759
        + ", localActivityWorkerOnly="
760
        + localActivityWorkerOnly
761
        + ", defaultDeadlockDetectionTimeout="
762
        + defaultDeadlockDetectionTimeout
763
        + ", maxHeartbeatThrottleInterval="
764
        + maxHeartbeatThrottleInterval
765
        + ", defaultHeartbeatThrottleInterval="
766
        + defaultHeartbeatThrottleInterval
767
        + ", stickyQueueScheduleToStartTimeout="
768
        + stickyQueueScheduleToStartTimeout
769
        + ", disableEagerExecution="
770
        + disableEagerExecution
771
        + ", useBuildIdForVersioning="
772
        + useBuildIdForVersioning
773
        + ", buildId='"
774
        + buildId
775
        + '\''
776
        + ", stickyTaskQueueDrainTimeout="
777
        + stickyTaskQueueDrainTimeout
778
        + '}';
779
  }
780
}
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