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

temporalio / sdk-java / #192

02 Oct 2023 11:52PM UTC coverage: 77.37% (-0.05%) from 77.421%
#192

push

github-actions

web-flow
Fix caching in WorkflowLocal/WorkflowThreadLocal (#1876) (#1878)

Reverted caching changes made to WorkflowLocal/WorkflowThreadLocal,
which broke backwards compatibility and accidentally shared values
between Workflows/Threads. Re-implemented caching as an optional
feature, and deprecated the factory methods that created non-caching
instances.

28 of 28 new or added lines in 5 files covered. (100.0%)

18684 of 24149 relevant lines covered (77.37%)

0.77 hits per line

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

69.23
/temporal-sdk/src/main/java/io/temporal/workflow/WorkflowLocal.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.workflow;
22

23
import io.temporal.internal.sync.RunnerLocalInternal;
24
import java.util.Objects;
25
import java.util.function.Supplier;
26

27
/**
28
 * A value that is local to a single workflow execution. So it can act as a <i>global</i> variable
29
 * for the workflow code. For example the {@code Workflow.isSignaled()} static method returns the
30
 * correct value even if there are multiple workflows executing on the same machine simultaneously.
31
 * It would be invalid if the {@code signaled} was a {@code static boolean} variable.
32
 *
33
 * <pre>{@code
34
 * public class Workflow {
35
 *
36
 *   private static final WorkflowLocal<Boolean> signaled = WorkflowLocal.withCachedInitial(() -> false);
37
 *
38
 *   public static boolean isSignaled() {
39
 *     return signaled.get();
40
 *   }
41
 *
42
 *   public void signal() {
43
 *     signaled.set(true);
44
 *   }
45
 * }
46
 * }</pre>
47
 *
48
 * @see WorkflowThreadLocal for thread local that can be used inside workflow code.
49
 */
50
public final class WorkflowLocal<T> {
51

52
  private final RunnerLocalInternal<T> impl;
53
  private final Supplier<? extends T> supplier;
54

55
  private WorkflowLocal(Supplier<? extends T> supplier, boolean useCaching) {
1✔
56
    this.supplier = Objects.requireNonNull(supplier);
1✔
57
    this.impl = new RunnerLocalInternal<>(useCaching);
1✔
58
  }
1✔
59

60
  public WorkflowLocal() {
×
61
    this.supplier = () -> null;
×
62
    this.impl = new RunnerLocalInternal<>(false);
×
63
  }
×
64

65
  /**
66
   * Create an instance that returns the value returned by the given {@code Supplier} when {@link
67
   * #set(S)} has not yet been called in the Workflow. Note that the value returned by the {@code
68
   * Supplier} is not stored in the {@code WorkflowLocal} implicitly; repeatedly calling {@link
69
   * #get()} will always re-execute the {@code Supplier} until you call {@link #set(S)} for the
70
   * first time. If you want the value returned by the {@code Supplier} to be stored in the {@code
71
   * WorkflowLocal}, use {@link #withCachedInitial(Supplier)} instead.
72
   *
73
   * @param supplier Callback that will be executed whenever {@link #get()} is called, until {@link
74
   *     #set(S)} is called for the first time.
75
   * @return A {@code WorkflowLocal} instance.
76
   * @param <S> The type stored in the {@code WorkflowLocal}.
77
   * @deprecated Because the non-caching behavior of this API is typically not desirable, it's
78
   *     recommend to use {@link #withCachedInitial(Supplier)} instead.
79
   */
80
  @Deprecated
81
  public static <S> WorkflowLocal<S> withInitial(Supplier<? extends S> supplier) {
82
    return new WorkflowLocal<>(supplier, false);
1✔
83
  }
84

85
  /**
86
   * Create an instance that returns the value returned by the given {@code Supplier} when {@link
87
   * #set(S)} has not yet been called in the Workflow, and then stores the returned value inside the
88
   * {@code WorkflowLocal}.
89
   *
90
   * @param supplier Callback that will be executed when {@link #get()} is called for the first
91
   *     time, if {@link #set(S)} has not already been called.
92
   * @return A {@code WorkflowLocal} instance.
93
   * @param <S> The type stored in the {@code WorkflowLocal}.
94
   */
95
  public static <S> WorkflowLocal<S> withCachedInitial(Supplier<? extends S> supplier) {
96
    return new WorkflowLocal<>(supplier, true);
1✔
97
  }
98

99
  public T get() {
100
    return impl.get(supplier);
1✔
101
  }
102

103
  public void set(T value) {
104
    impl.set(value);
1✔
105
  }
1✔
106
}
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

© 2025 Coveralls, Inc