Skip to content

[CELEBORN-2536] Support pluggable worker self-decommission driven by an external signal - #3939

Draft
venkata91 wants to merge 9 commits into
apache:mainfrom
venkata91:vsowrira/implement-pluggable-mechanism-celeborn-s
Draft

venkata91 wants to merge 9 commits into
apache:mainfrom
venkata91:vsowrira/implement-pluggable-mechanism-celeborn-s

Conversation

@venkata91

@venkata91 venkata91 commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Adds a pluggable checker that lets a worker decommission itself when something outside Celeborn says the node is going away.

  • New DecommissionSignalChecker interface in the worker module. Implementations take a CelebornConf constructor. The worker loads the class set in celeborn.worker.decommission.signal.checker and fails at startup if it can't.
  • The worker polls the checker every celeborn.worker.decommission.signal.checkInterval (30s by default). When it returns true, the worker calls the existing exit("DECOMMISSION"), same as the REST API. It fires at most once, and checker errors are logged and treated as a no.
  • The default checker is a no-op and doesn't start a polling thread. FileDecommissionSignalChecker is included as a simple option: it decommissions the worker once a configured file exists.
  • Docs: new section in docs/decommissioning.md, and docs/configuration/worker.md is regenerated.

Why are the changes needed?

https://issues.apache.org/jira/browse/CELEBORN-2536

Today decommission has to come from outside, through the worker or master REST API. But in cloud and autoscaled setups, the first heads-up usually reaches the node itself, like a spot preemption notice or a node drain. So every deployment ends up writing a sidecar that watches for it and calls the API. This lets the worker act on it directly.

Related: #3698 (decommission on SIGTERM). I think the two are complementary. That one handles the worker already being killed, this one acts before that.

Does this PR resolve a correctness bug?

  • Yes

Does this PR introduce any user-facing change?

  • Yes

Three new worker configs (celeborn.worker.decommission.signal.checker, .checkInterval, .file.path) and the public DecommissionSignalChecker interface. Nothing changes unless a checker is configured.

How was this patch tested?

New DecommissionSignalMonitorSuite and FileDecommissionSignalCheckerSuite, plus WorkerSuite cases for loading the checker, failing on a bad class, and reaching InDecommission through the real exit path.

Ran locally on JDK 17, all passed:

  • build/mvn -pl common,worker spotless:check
  • build/mvn clean test -pl common -am -Dtest=none -DwildcardSuites=org.apache.celeborn.ConfigurationSuite
  • build/mvn test -pl worker -am '-Dtest=org.apache.celeborn.service.deploy.worker.**' -DwildcardSuites=org.apache.celeborn.service.deploy.worker (Scala 2.12)
  • build/mvn test -Pspark-4.0 -pl worker -am -Dtest=none -DwildcardSuites=org.apache.celeborn.service.deploy.worker.decommission,org.apache.celeborn.service.deploy.worker.WorkerStatusManagerSuite,org.apache.celeborn.service.deploy.worker.WorkerSuite (Scala 2.13)
  • build/mvn apache-rat:check -pl common,worker

On my arm64 Mac I also had to pass -Dgrpc.version=1.44.0-local-arm64-stub, which isn't part of this change.

Drafted with help from GitHub Copilot CLI.

venkata91 and others added 8 commits October 31, 2026 23:29
Introduce the worker-side SPI that lets an external signal ask a worker to
decommission itself, the default no-op checker, a built-in checker that
signals once a marker file exists, and the three
celeborn.worker.decommission.signal.* configs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
Move the delayed System.exit thread into an overridable
scheduleSystemExit() and expose inExitStatus() within the worker package,
so tests can drive real Decommission transitions without exiting the JVM.
No behaviour change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
The monitor loads the configured checker (failing fast with the config key
and class name on any error), polls it on a dedicated daemon thread, skips
polling while the worker is already exiting, treats checker exceptions as
no signal, and triggers decommission at most once.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
The worker creates the configured checker before allocating any other
resource, starts polling once initialised, stops the monitor on stop, and
triggers decommission through the same exit("DECOMMISSION") path as the
REST API.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
…r init

Extract the exception-swallowing checker poll into pollChecker() to flatten
checkOnce(), and use getOrElse(throw ...) for the required signal file path.
No behavior change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
Treat LinkageError from a checker as recoverable so polling keeps
running and a failing checker class still fails startup with the
config key. Log at ERROR if a fatal error stops polling, if the
trigger itself fails (not retried), and skip triggering when the
monitor is stopped while a poll is in flight.

Add a Worker test seam for WorkerStatusManager and a WorkerSuite test
that runs the production DECOMMISSION exit path from the monitor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
…utdown

Use this.conf in the WorkerSuite anonymous Worker subclass so the test
compiles under Scala 2.13 with -Xfatal-warnings. Handle interruption of
an in-flight poll during stop() quietly instead of logging a fatal error,
stop the unstarted monitor in the trigger-failure test, and document why
the DECOMMISSION test leaves the shutdown hook timeout updated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8
@venkata91 venkata91 changed the title [CELEBORN-XXXX] Support pluggable worker self-decommission driven by an external signal [CELEBORN-2536] Support pluggable worker self-decommission driven by an external signal Nov 1, 2026
Rename the configs to celeborn.worker.decommission.signal.checker and
celeborn.worker.decommission.signal.checkInterval. Instantiate checkers
through Utils.instantiateClassWithCelebornConf with a CelebornConf
constructor and drop init(). Create the monitor at the start of
initialize() so a failing constructor never leaks the checker. Keep the
trigger when getReason throws a LinkageError, and wait briefly for an
in-flight check before closing the checker. Replace the overridable test
seams with an injectable exit action on WorkerStatusManager. Fix the
Kubernetes preStop example in the docs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1816769b-cdd1-4c85-be0b-d11a935c03d8

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant