Skip to content

feat(trace): add cadenceIsCron tag in the start workflow span#1071

Open
shijiesheng wants to merge 1 commit into
cadence-workflow:masterfrom
shijiesheng:add-is-cron
Open

feat(trace): add cadenceIsCron tag in the start workflow span#1071
shijiesheng wants to merge 1 commit into
cadence-workflow:masterfrom
shijiesheng:add-is-cron

Conversation

@shijiesheng

Copy link
Copy Markdown
Member

What changed?

Add cadenceIsCron tag on execute workflow span. (In Go, we add it in start workflow span)

Why?
cadence-workflow/cadence-go-client#1518

How did you test it?

Unit Test / Integration Test

Potential risks

Release notes

Documentation Changes

Signed-off-by: Shijie Sheng <liouvetren@gmail.com>
@gitar-bot

gitar-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Adds the cadenceIsCron tag to the workflow execution span, resolving a string comparison logic error. Integration and unit tests confirm the tag is correctly applied to scheduled workflows.

✅ 1 resolved
Bug: String comparison with != produces wrong cadenceIsCron value

📄 src/main/java/com/uber/cadence/internal/tracing/TracingPropagator.java:74 📄 src/test/java/com/uber/cadence/internal/tracing/TracingPropagatorTest.java:79-85 📄 src/test/java/com/uber/cadence/internal/tracing/TracingPropagatorTest.java:87-97
In spanForExecuteWorkflow, the cron detection uses reference comparison: attributes.getCronSchedule() != "". In Java, != on Strings compares object identity, not value.

At runtime the cron schedule string is produced by Thrift/gRPC deserialization, so it is a freshly-allocated String instance that is NOT interned. Therefore even when the value is an empty string "", getCronSchedule() != "" evaluates to true, so the cadenceIsCron tag will be incorrectly set to true for non-cron workflows in production. Additionally, if getCronSchedule() returns null, null != "" is also true, again yielding an incorrect true.

The new unit test (testSpanForExecuteWorkflow_withoutCronSchedule_setsIsCronTagFalse) passes only because it builds attributes with the compile-time literal "", which is interned and happens to be the same reference as the literal in TracingPropagator. This masks the bug and does not reflect the deserialized-string path used in production.

Use value-based comparison with a null guard instead.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

.withTag(TAG_WORKFLOW_TYPE, context.getWorkflowType().getName())
.withTag(TAG_WORKFLOW_ID, context.getWorkflowId())
.withTag(TAG_WORKFLOW_RUN_ID, context.getRunId())
.withTag(TAG_IS_CRON, attributes.getCronSchedule() != "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.withTag(TAG_IS_CRON, attributes.getCronSchedule() != "")
.withTag(TAG_IS_CRON, attributes.getCronSchedule() != null && !attributes.getCronSchedule().isEmpty())

!= on strings compares object references

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants