From 070052089ae01b09b6de3207d8e38af3b5472e7c Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 12 May 2025 12:13:34 -0700 Subject: [PATCH 01/10] Add some agent files --- AGENTS.md | 31 +++++++++++++++++++ temporal-sdk/AGENTS.md | 4 +++ .../main/java/io/temporal/internal/AGENTS.md | 1 + 3 files changed, 36 insertions(+) create mode 100644 AGENTS.md create mode 100644 temporal-sdk/AGENTS.md create mode 100644 temporal-sdk/src/main/java/io/temporal/internal/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..d8f650b1cb --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,31 @@ +# Layout + +The main directory of the repository contains the following folders: +- `temporal-sdk`: This folder contains the SDK code. +- `temporal-testing`: This folder contains the code for helping users test their workflows and activities. +- `temporal-test-server`: This folder contains the code for the time skipping test server. This is an alternate implementation of the Temporal server that supports time skipping for fast testing. +- `temporal-shaded`: This folder contains the code for the shaded Temporal SDK. This is a version of the SDK that is shaded to avoid dependency conflicts with other libraries. +- `temporal-serviceclient`: This folder contains the code for the Temporal service client. This is a client that can be used to communicate with the Temporal server. +- `temporal-sprintg-boot-autoconfigure`: This folder contains the code for the Spring Boot autoconfiguration. This is a library that can be used to automatically configure the Temporal SDK in a Spring Boot application. + +# Guide + +Generally we should not make any change to the signature of the public API. Classes or interfaces that in an `internal` folder are not considered public API. + +# Language + +The SDK should be written in Java using Java 8. + +# Testing + +To format code run: + +```bash +./gradlew spotlessApply +``` + +To test the SDK run: + +```bash +./gradlew temporal-sdk:test +``` \ No newline at end of file diff --git a/temporal-sdk/AGENTS.md b/temporal-sdk/AGENTS.md new file mode 100644 index 0000000000..ab28668002 --- /dev/null +++ b/temporal-sdk/AGENTS.md @@ -0,0 +1,4 @@ +This directory contains the core Temporal SDK code, which is used to build Temporal applications. The SDK provides a set of APIs and libraries that allow developers to create, manage, and execute workflows and activities in a distributed environment. The SDK is designed to be easy to use and provides a high-level abstraction over the underlying Temporal service. + +The SDK is written in Java and is designed to be used with the Temporal service. It provides a set of APIs for defining workflows and activities, as well as for managing the execution of those workflows and activities. + diff --git a/temporal-sdk/src/main/java/io/temporal/internal/AGENTS.md b/temporal-sdk/src/main/java/io/temporal/internal/AGENTS.md new file mode 100644 index 0000000000..fdfb881879 --- /dev/null +++ b/temporal-sdk/src/main/java/io/temporal/internal/AGENTS.md @@ -0,0 +1 @@ +All files in this directory and subdirectory are intended to be internal to the SDK and should not be used by external users. They do not have the same backwards compatibility guarantees as our other APIS \ No newline at end of file From b6f81f8df92575147be584a0c75d28aa1f197179 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 12 May 2025 12:51:19 -0700 Subject: [PATCH 02/10] Add more agent files --- AGENTS.md | 4 +++- temporal-sdk/AGENTS.md | 5 +++++ temporal-sdk/src/test/java/io/temporal/workflow/AGENTS.md | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 temporal-sdk/src/test/java/io/temporal/workflow/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md index d8f650b1cb..34363e41eb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,4 +28,6 @@ To test the SDK run: ```bash ./gradlew temporal-sdk:test -``` \ No newline at end of file +``` + +running all tests can take a long time \ No newline at end of file diff --git a/temporal-sdk/AGENTS.md b/temporal-sdk/AGENTS.md index ab28668002..d250db3596 100644 --- a/temporal-sdk/AGENTS.md +++ b/temporal-sdk/AGENTS.md @@ -2,3 +2,8 @@ This directory contains the core Temporal SDK code, which is used to build Tempo The SDK is written in Java and is designed to be used with the Temporal service. It provides a set of APIs for defining workflows and activities, as well as for managing the execution of those workflows and activities. +# Testing + +All tests are written using JUnit4. + +All tests for this package are located in `temporal-sdk/src/test/java/io/temporal` \ No newline at end of file diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/AGENTS.md b/temporal-sdk/src/test/java/io/temporal/workflow/AGENTS.md new file mode 100644 index 0000000000..fecae42e04 --- /dev/null +++ b/temporal-sdk/src/test/java/io/temporal/workflow/AGENTS.md @@ -0,0 +1,7 @@ +# Summary + +This directory and sub directory contain tests for workflow APIs. + +# Testing + +Tests should use the `SDKTestWorkflowRule` to create a worker, register workflows, activities and nexus services. \ No newline at end of file From 2e7d2a43e04ccb550b129c4a1b67f32035703172 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 12 May 2025 15:43:40 -0700 Subject: [PATCH 03/10] update agent instructions --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 34363e41eb..ef8820dc47 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,7 +27,7 @@ To format code run: To test the SDK run: ```bash -./gradlew temporal-sdk:test +./gradlew --offline temporal-sdk:test ``` running all tests can take a long time \ No newline at end of file From a4ce3dafd2e2eef3372fbe7565969bcc0d5da0da Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 12 May 2025 22:16:47 -0700 Subject: [PATCH 04/10] Add more testing instructions --- AGENTS.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ef8820dc47..1161fcfb2f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,13 +21,21 @@ The SDK should be written in Java using Java 8. To format code run: ```bash -./gradlew spotlessApply +./gradlew --offline spotlessApply ``` To test the SDK run: ```bash -./gradlew --offline temporal-sdk:test +./gradlew :temporal-sdk:test --offline --tests "io.temporal.workflow.*" ``` -running all tests can take a long time \ No newline at end of file +running all tests can take a long time + +To test a new test you added run + +```bash +./gradlew :temporal-sdk:test --offline --tests "$TEST" +``` + +where $TEST is the name of the test including the package. \ No newline at end of file From a94c3bcd1f014f648d1b8adbe963eaec80f79396 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 12 May 2025 22:36:30 -0700 Subject: [PATCH 05/10] Skip some flaky tests --- .../test/java/io/temporal/workflow/updateTest/UpdateTest.java | 1 + .../io/temporal/workflow/updateTest/UpdateWithStartTest.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java index 8adad01bde..80632c9399 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java @@ -36,6 +36,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@Ignore public class UpdateTest { private static final Logger log = LoggerFactory.getLogger(UpdateTest.class); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java index ceaa18dce1..e0d02a71b7 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java @@ -33,9 +33,12 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; import java.util.function.Function; + +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; +@Ignore public class UpdateWithStartTest { @Rule From fd33162e1c6c4902d511b6cbd54cf9c3addb4544 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Mon, 12 May 2025 22:41:09 -0700 Subject: [PATCH 06/10] fix compile --- .../test/java/io/temporal/workflow/updateTest/UpdateTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java index 80632c9399..1528d87636 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java @@ -31,6 +31,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.slf4j.Logger; From f8d8d2f38c85cc8449f49cf8eca2d8473d8dff09 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Tue, 13 May 2025 13:53:48 -0700 Subject: [PATCH 07/10] Update agents.md --- AGENTS.md | 100 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 41 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1161fcfb2f..330c537e40 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,41 +1,59 @@ -# Layout - -The main directory of the repository contains the following folders: -- `temporal-sdk`: This folder contains the SDK code. -- `temporal-testing`: This folder contains the code for helping users test their workflows and activities. -- `temporal-test-server`: This folder contains the code for the time skipping test server. This is an alternate implementation of the Temporal server that supports time skipping for fast testing. -- `temporal-shaded`: This folder contains the code for the shaded Temporal SDK. This is a version of the SDK that is shaded to avoid dependency conflicts with other libraries. -- `temporal-serviceclient`: This folder contains the code for the Temporal service client. This is a client that can be used to communicate with the Temporal server. -- `temporal-sprintg-boot-autoconfigure`: This folder contains the code for the Spring Boot autoconfiguration. This is a library that can be used to automatically configure the Temporal SDK in a Spring Boot application. - -# Guide - -Generally we should not make any change to the signature of the public API. Classes or interfaces that in an `internal` folder are not considered public API. - -# Language - -The SDK should be written in Java using Java 8. - -# Testing - -To format code run: - -```bash -./gradlew --offline spotlessApply -``` - -To test the SDK run: - -```bash -./gradlew :temporal-sdk:test --offline --tests "io.temporal.workflow.*" -``` - -running all tests can take a long time - -To test a new test you added run - -```bash -./gradlew :temporal-sdk:test --offline --tests "$TEST" -``` - -where $TEST is the name of the test including the package. \ No newline at end of file +# Contributor Quickstart Guide + +## Repository Layout +- `temporal-sdk`: core SDK implementation. +- `temporal-testing`: utilities to help write workflow and activity tests. +- `temporal-test-server`: in-memory Temporal server for fast tests. +- `temporal-serviceclient`: gRPC client for communicating with the service. +- `temporal-shaded`: prepackaged version of the SDK with shaded dependencies. +- `temporal-spring-boot-autoconfigure`: Spring Boot auto configuration. +- `temporal-kotlin`: Kotlin DSL for the SDK. +- `temporal-opentracing`: OpenTracing interceptor integration. +- +## General Guidance +- Avoid changing public API signatures. Anything under an `internal` directory + is not part of the public API and may change freely. +- The SDK code is written for Java 8. + +## Building and Testing +1. Format the code before committing: + ```bash + ./gradlew --offline spotlessApply + ``` +2. Run the tests. A full build requires a local Temporal Server instance. + ```bash + ./gradlew test + ``` + To run only the core SDK tests or a single test: + ```bash + ./gradlew :temporal-sdk:test --offline --tests "io.temporal.workflow.*" + ./gradlew :temporal-sdk:test --offline --tests "" + ``` +3. Build the project: + ```bash + ./gradlew clean build + ``` + +## Tests +- Tests use JUnit4 and are located under + `temporal-sdk/src/test/java/io/temporal`. +- Workflow API tests should rely on `SDKTestWorkflowRule` to create a worker and + register workflows, activities, and nexus services. + +## Commit Messages and Pull Requests +- Follow the [Chris Beams](http://chris.beams.io/posts/git-commit/) style for + commit messages. +- Every pull request should answer: + - **What changed?** + - **Why?** + - **Breaking changes?** + - **Server PR** (if the change requires a coordinated server update) +- Comments should be complete sentences and end with a period. + +## Review Checklist +- `./gradlew spotlessCheck` must pass. +- All tests from `./gradlew test` must succeed. +- Add new tests for any new feature or bug fix. +- Update documentation for user facing changes. + +For more details see `CONTRIBUTING.md` in the repository root. From a316508d0538ee1ac5e7863f4d0c3bcd44f8a2af Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Wed, 14 May 2025 19:06:55 -0700 Subject: [PATCH 08/10] Update some AGENTS.md --- AGENTS.md | 7 +++---- temporal-kotlin/AGENTS.md | 1 + temporal-sdk/AGENTS.md | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) create mode 100644 temporal-kotlin/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md index 330c537e40..8bde8253ac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,7 @@ - `temporal-spring-boot-autoconfigure`: Spring Boot auto configuration. - `temporal-kotlin`: Kotlin DSL for the SDK. - `temporal-opentracing`: OpenTracing interceptor integration. -- + ## General Guidance - Avoid changing public API signatures. Anything under an `internal` directory is not part of the public API and may change freely. @@ -20,7 +20,7 @@ ```bash ./gradlew --offline spotlessApply ``` -2. Run the tests. A full build requires a local Temporal Server instance. +2. Run the tests. This can take a long time so you may prefer to run individual tests. ```bash ./gradlew test ``` @@ -35,8 +35,7 @@ ``` ## Tests -- Tests use JUnit4 and are located under - `temporal-sdk/src/test/java/io/temporal`. +- All tests for this each package is located in `$PACKAGE_NAME/src/test/java/io/temporal`, where `$PACKAGE_NAME` is the name of the package - Workflow API tests should rely on `SDKTestWorkflowRule` to create a worker and register workflows, activities, and nexus services. diff --git a/temporal-kotlin/AGENTS.md b/temporal-kotlin/AGENTS.md new file mode 100644 index 0000000000..23312afd00 --- /dev/null +++ b/temporal-kotlin/AGENTS.md @@ -0,0 +1 @@ +Unlike the rest of this repository, this directory is for the Kotlin SDK so most of the code here is written in Kotlin, not Java. diff --git a/temporal-sdk/AGENTS.md b/temporal-sdk/AGENTS.md index d250db3596..4ebe0e163e 100644 --- a/temporal-sdk/AGENTS.md +++ b/temporal-sdk/AGENTS.md @@ -5,5 +5,3 @@ The SDK is written in Java and is designed to be used with the Temporal service. # Testing All tests are written using JUnit4. - -All tests for this package are located in `temporal-sdk/src/test/java/io/temporal` \ No newline at end of file From 781c7f2df1b39707473a1a747702df942f1e29c6 Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Thu, 15 May 2025 13:53:50 -0700 Subject: [PATCH 09/10] Fix tests --- .../test/java/io/temporal/workflow/updateTest/UpdateTest.java | 3 --- .../io/temporal/workflow/updateTest/UpdateWithStartTest.java | 3 --- 2 files changed, 6 deletions(-) diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java index 1528d87636..8adad01bde 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateTest.java @@ -31,14 +31,11 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; - -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Ignore public class UpdateTest { private static final Logger log = LoggerFactory.getLogger(UpdateTest.class); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java index e0d02a71b7..ceaa18dce1 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/updateTest/UpdateWithStartTest.java @@ -33,12 +33,9 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; import java.util.function.Function; - -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; -@Ignore public class UpdateWithStartTest { @Rule From c80eeaaea7d2df136d37a2ab9a6edca8c1a6476a Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Tue, 3 Jun 2025 15:17:28 -0700 Subject: [PATCH 10/10] Clear MDC after each task --- .../internal/worker/PollTaskExecutor.java | 3 +- .../worker/MdcClearedBetweenTasksTest.java | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 temporal-sdk/src/test/java/io/temporal/worker/MdcClearedBetweenTasksTest.java diff --git a/temporal-sdk/src/main/java/io/temporal/internal/worker/PollTaskExecutor.java b/temporal-sdk/src/main/java/io/temporal/internal/worker/PollTaskExecutor.java index 27c07fd040..5928b585f2 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/worker/PollTaskExecutor.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/worker/PollTaskExecutor.java @@ -81,8 +81,7 @@ public void process(@Nonnull T task) { .uncaughtException(Thread.currentThread(), handler.wrapFailure(task, e)); } } finally { - MDC.remove(LoggerTag.NAMESPACE); - MDC.remove(LoggerTag.TASK_QUEUE); + MDC.clear(); } }); } diff --git a/temporal-sdk/src/test/java/io/temporal/worker/MdcClearedBetweenTasksTest.java b/temporal-sdk/src/test/java/io/temporal/worker/MdcClearedBetweenTasksTest.java new file mode 100644 index 0000000000..49be6224d7 --- /dev/null +++ b/temporal-sdk/src/test/java/io/temporal/worker/MdcClearedBetweenTasksTest.java @@ -0,0 +1,71 @@ +package io.temporal.worker; + +import static org.junit.Assert.assertNull; + +import io.temporal.activity.ActivityInterface; +import io.temporal.activity.ActivityMethod; +import io.temporal.testing.internal.SDKTestOptions; +import io.temporal.testing.internal.SDKTestWorkflowRule; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.shared.TestWorkflows; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.MDC; + +public class MdcClearedBetweenTasksTest { + @Rule + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() + .setWorkflowTypes(TestWorkflowImpl.class) + .setActivityImplementations(new SetMdcActivityImpl(), new GetMdcActivityImpl()) + .build(); + + @Test + public void testMdcClearedBetweenActivities() { + TestWorkflows.TestWorkflowReturnString workflow = + testWorkflowRule.newWorkflowStub(TestWorkflows.TestWorkflowReturnString.class); + String result = workflow.execute(); + assertNull(result); + } + + public static class TestWorkflowImpl implements TestWorkflows.TestWorkflowReturnString { + private final SetMdcActivity setMdcActivity = + Workflow.newActivityStub( + SetMdcActivity.class, SDKTestOptions.newActivityOptions20sScheduleToClose()); + private final GetMdcActivity getMdcActivity = + Workflow.newActivityStub( + GetMdcActivity.class, SDKTestOptions.newActivityOptions20sScheduleToClose()); + + @Override + public String execute() { + setMdcActivity.execute(); + return getMdcActivity.execute(); + } + } + + @ActivityInterface + public interface SetMdcActivity { + @ActivityMethod(name = "setMdc") + void execute(); + } + + public static class SetMdcActivityImpl implements SetMdcActivity { + @Override + public void execute() { + MDC.put("mdcTest", "value"); + } + } + + @ActivityInterface + public interface GetMdcActivity { + @ActivityMethod(name = "getMdc") + String execute(); + } + + public static class GetMdcActivityImpl implements GetMdcActivity { + @Override + public String execute() { + return MDC.get("mdcTest"); + } + } +}