Skip to content

[WIP] Fix timezone round-trip bug in BackfillWorkflowExecutorDelegate#3

Closed
Copilot wants to merge 1 commit intoDSIP-95from
copilot/fix-timezone-round-trip-bug
Closed

[WIP] Fix timezone round-trip bug in BackfillWorkflowExecutorDelegate#3
Copilot wants to merge 1 commit intoDSIP-95from
copilot/fix-timezone-round-trip-bug

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 26, 2026

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

Background

PR apache#18003 (apache/dolphinscheduler) implements downstream-dependent backfill triggering in BackfillWorkflowExecutorDelegate. There are two remaining issues that must be fixed without introducing any new problems:


Issue 1 — Timezone round-trip bug (functional bug, highest priority)

File: dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/workflow/BackfillWorkflowExecutorDelegate.java

Root cause: doBackfillDependentWorkflow currently accepts List<String> backfillTimeList (date strings), then converts them back to ZonedDateTime via DateUtils.stringToZoneDateTime. This creates a string→ZonedDateTime round-trip. Because stringToZoneDateTime parses using ZoneId.systemDefault(), the timezone can shift when the request timezone differs from the JVM default, causing downstream workflows to be backfilled for wrong business dates.

Fix:

  • Change the signature of doBackfillDependentWorkflow to accept List<ZonedDateTime> backfillDateList instead of List<String> backfillTimeList
  • Pass the ZonedDateTime list directly to the downstream BackfillParamsDTO.backfillDateList, eliminating the string→ZonedDateTime conversion entirely
  • Update all call sites: in doBackfillWorkflow, instead of passing backfillTimeList (strings), pass the original ZonedDateTime list. The ZonedDateTime list is available from backfillWorkflowDTO.getBackfillParams().getBackfillDateList() — but note that in the serial path the list has already been sorted (in doSerialBackfillWorkflow), and in the parallel path each chunk is a sub-list of ZonedDateTime. So the correct approach is to pass the ZonedDateTime chunk/list into doBackfillWorkflow, and then pass it along to doBackfillDependentWorkflow.

Concretely:

  1. Change doBackfillWorkflow to also accept List<ZonedDateTime> backfillDateList alongside List<String> backfillTimeList — OR store the ZonedDateTime list on the DTO so it is available in doBackfillWorkflow. The cleanest approach: change doBackfillWorkflow to receive both List<ZonedDateTime> backfillDateList and List<String> backfillTimeList (the string list is still needed for the trigger request to master), and pass backfillDateList through to doBackfillDependentWorkflow.
  2. In doSerialBackfillWorkflow: pass backfillTimeList (the sorted ZonedDateTime list) plus the string conversion to doBackfillWorkflow.
  3. In doParallelBackfillWorkflow: pass stringDate (the ZonedDateTime chunk) plus the string conversion to doBackfillWorkflow.
  4. In doBackfillDependentWorkflow: remove the DateUtils.stringToZoneDateTime conversion; use the passed-in ZonedDateTime list directly as backfillDateList in dependentParams.
  5. Remove the now-unused DateUtils import if it is no longer needed (check — DateUtils::dateToString is still used, so keep the import).

Issue 2 — Reflection-based test access (brittle tests)

File: dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/workflow/BackfillWorkflowExecutorDelegateTest.java

Root cause: All tests that exercise doBackfillDependentWorkflow use getDeclaredMethod + setAccessible(true) to call the private method. This is brittle: any rename or signature change silently breaks tests.

Fix:

  • Change doBackfillDependentWorkflow in the production class from private to package-private (no modifier) — it is in the same package as the test
  • Remove ALL reflection usage from the test: replace every getDeclaredMethod / setAccessible / method.invoke(...) block with a direct call to backfillWorkflowExecutorDelegate.doBackfillDependentWorkflow(...)
  • Remove the import java.lang.reflect.Method; import from the test file since it will no longer be needed

The method signature after the timezone fix (Issue 1) will be:

void doBackfillDependentWorkflow(BackfillWorkflowDTO backfillWorkflowDTO,
                                  List<ZonedDateTime> backfillDateList,
                                  Set<Long> visitedCodes)

Tests must be updated to pass List<ZonedDateTime> instead of List<String> when calling doBackfillDependentWorkflow.


Issue 3 — PR description not updated

File: PR body (not a source file — skip this, it is handled separately)


Constraints

  • Do NOT change the public API surface (execute, executeWithVisitedCodes, triggerBackfillWorkflow)
  • Do NOT change existing test logic/assertions — only change how the private method is accessed (direct call vs reflection) and update the argument type from List<String> to List<ZonedDateTime>
  • Do NOT introduce any new bugs
  • Keep the processService and commandDao fields as-is (they exist in the class, don't remove them)
  • The DateUtils import must remain (still used for DateUtils::dateToString)
  • LinkedHashSet import may still be needed (used in doBackfillDependentWorkflow for downstreamCodes)
  • Ensure the test...

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

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.

2 participants