Skip to content

[GOBBLIN-2270] Add retained-state fallback for KILL actions - #4208

Merged
Blazer-007 merged 3 commits into
apache:masterfrom
Siddhi-agg:siagrawa/add-force-kill-handler
Sep 24, 2026
Merged

Blazer-007 merged 3 commits into
apache:masterfrom
Siddhi-agg:siagrawa/add-force-kill-handler

Conversation

@Siddhi-agg

@Siddhi-agg Siddhi-agg commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Dear Gobblin maintainers,

Please accept this PR. I understand that it will not be reviewed until I have checked off all the steps below!

JIRA

Description

  • Here are some details about my PR:

The existing KILL path requires an active DAG to locate the executor and its submission handle. Once the DAG has been removed, KILL reports that the DAG was not found, even if an external execution or launcher is still running.

Retained job status can contain the execution metadata needed to address that remaining execution. However, the existing status retrieval APIs convert stored State objects into JobStatus objects, which do not preserve arbitrary backend-specific metadata.

Changes

  • Add a backend-neutral ForceKillHandler interface for handling existing KILL actions when the active DAG is absent.
  • Allow deployments to supply the handler through gobblin.service.forceKillHandler.class, using an optional singleton Guice binding and service lifecycle hooks.
  • Add raw-state retrieval through JobStatusRetriever and MysqlJobStatusRetriever so the fallback can access retained execution metadata without converting it into JobStatus.
  • Validate the decoded flow group, flow name, execution ID, and optional job scope before passing state copies to the handler. Flow-summary records provide context but cannot trigger stopping on their own.
  • Recheck for an active DAG after reading retained state and supply a callback for backend-side checks before stopping. If the DAG reappears, return to normal cancellation.
  • Distinguish acknowledged, unacknowledged, and active-DAG-present outcomes. The retained-state path does not emit normal cancellation events or rewrite terminal job status.
  • Include the execution-ID separator in the MySQL lookup pattern so an execution such as 1234 does not also match 12340.

Tests

  • My PR adds the following unit tests:

  • KillDagProcForceKillTest: active-DAG compatibility, retained-state scoping, metadata preservation, DAG reappearance, and failure outcomes.

  • DagProcFactoryForceKillTest: optional binding, lazy provider access, and legacy constructor behavior.

  • RawJobStatusRetrieverTest: raw metadata retrieval, execution scoping, and read-error propagation.

  • MysqlJobStatusStateStoreFlowScopeTest: execution-ID delimiter in the MySQL lookup.

  • GobblinServiceForceKillConfigurationTest: optional configuration and singleton binding.

  • GobblinServiceForceKillLifecycleTest: backend cleanup paths.

Commits

  • My commits reference the Jira issue, are appropriately squashed, and follow the project's commit-message guidelines.

Keep active-DAG cancellation unchanged and allow missing-DAG KILL
actions to delegate to an optional backend using retained job states.

Preserve opaque execution metadata, scope it to the requested flow
and job, and recheck for active DAGs during fallback. Add handler
configuration and lifecycle hooks with focused unit coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

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.

Copilot review overview

🟡 Changes recommended

Resolve the two moderate issues involving null state stores and defensive state copying.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds a configurable retained-state fallback for KILL actions when the active DAG is unavailable.

Changes:

  • Introduces ForceKillHandler configuration and lifecycle management.
  • Adds raw retained-state retrieval and execution-scoped MySQL lookups.
  • Adds fallback validation, race handling, and comprehensive tests.
  • Outstanding issues: handle null StateStore instances and defensively copy retained state before invoking handlers.
File Summary
gobblin-service/​src/​test/​java/​org/​apache/​gobblin/​service/​monitoring/​RawJobStatusRetrieverTest.java Tests raw metadata retrieval, scoping, and read failures.
gobblin-service/​src/​test/​java/​org/​apache/​gobblin/​service/​modules/​orchestration/​proc/​KillDagProcForceKillTest.java Tests fallback behavior, scoping, races, and failures.
gobblin-service/​src/​test/​java/​org/​apache/​gobblin/​service/​modules/​orchestration/​DagProcFactoryForceKillTest.java Tests optional handler injection and legacy constructors.
gobblin-service/​src/​test/​java/​org/​apache/​gobblin/​service/​modules/​core/​GobblinServiceForceKillLifecycleTest.java Tests handler lifecycle cleanup.
gobblin-service/​src/​test/​java/​org/​apache/​gobblin/​service/​modules/​core/​GobblinServiceForceKillConfigurationTest.java Tests optional configuration and singleton binding.
gobblin-service/​src/​main/​java/​org/​apache/​gobblin/​service/​monitoring/​MysqlJobStatusRetriever.java Retrieves retained raw state from MySQL.
gobblin-service/​src/​main/​java/​org/​apache/​gobblin/​service/​modules/​orchestration/​proc/​KillDagProc.java Implements retained-state force-kill fallback; state copying requires correction.
gobblin-service/​src/​main/​java/​org/​apache/​gobblin/​service/​modules/​orchestration/​ForceKillHandler.java Defines the backend force-kill contract.
gobblin-service/​src/​main/​java/​org/​apache/​gobblin/​service/​modules/​orchestration/​DagProcFactory.java Injects optional force-kill dependencies.
gobblin-service/​src/​main/​java/​org/​apache/​gobblin/​service/​modules/​core/​GobblinServiceManager.java Manages handler lifecycle.
gobblin-service/​src/​main/​java/​org/​apache/​gobblin/​service/​modules/​core/​GobblinServiceGuiceModule.java Configures optional singleton binding.
gobblin-runtime/​src/​main/​java/​org/​apache/​gobblin/​service/​monitoring/​JobStatusRetriever.java Adds raw-state retrieval; null StateStore handling requires correction.
gobblin-metastore/​src/​test/​java/​org/​apache/​gobblin/​metastore/​MysqlJobStatusStateStoreFlowScopeTest.java Tests execution-ID delimiter lookup.
gobblin-metastore/​src/​main/​java/​org/​apache/​gobblin/​metastore/​MysqlJobStatusStateStore.java Prevents execution-ID prefix collisions.
gobblin-api/​src/​main/​java/​org/​apache/​gobblin/​service/​ServiceConfigKeys.java Adds the force-kill handler configuration key.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@Siddhi-agg
Siddhi-agg marked this pull request as draft September 22, 2026 08:03
Declare the metastore Mockito test dependency so the CI test and
static-check jobs can compile their shared test fixtures.

Reject raw-state reads with an IOException when the retriever has
no state store. Snapshot merged properties before invoking the kill
handler so neither common nor specific properties share mutable maps.
Cover unsupported local-file retrieval and property isolation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Siddhi-agg

Copy link
Copy Markdown
Contributor Author

Pushed 9c72ce8 to address the CI failures and review feedback:

  • Added the missing gobblin-metastore Mockito test dependency. All five previous failed jobs stopped at the same compileTestJava error.
  • Made raw-state retrieval fail explicitly with IOException for retrievers without a StateStore, with a regression using LocalFsJobStatusRetriever. Replied to and resolved the review thread.
  • Replaced the State copy constructor with an independent merged-properties snapshot, covering common-property isolation in both directions and preservation of specific-property overrides.

The new workflow is awaiting maintainer approval before any jobs can run: https://github.com/apache/gobblin/actions/runs/35818045073 . Please approve that run. Local targeted execution is blocked before compilation by a Gradle/Groovy ReflectionCache initialization error; no passing result is claimed.

The previously identified standalone handler-lifetime and truncated-state decoding concerns remain outside this follow-up.

@Siddhi-agg Siddhi-agg changed the title [GOBBLIN-XXXX] Add retained-state fallback for KILL actions [GOBBLIN-2270] Add retained-state fallback for KILL actions Sep 23, 2026
@Siddhi-agg
Siddhi-agg marked this pull request as ready for review September 23, 2026 04:53
@Blazer-007
Blazer-007 merged commit 8b219f1 into apache:master Sep 24, 2026
6 checks passed
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