Skip to content

fix(kubernetes): terminate idle computing units - #6046

Open
yrenat wants to merge 15 commits into
apache:mainfrom
yrenat:fix/idle-kubernetes-cus
Open

fix(kubernetes): terminate idle computing units#6046
yrenat wants to merge 15 commits into
apache:mainfrom
yrenat:fix/idle-kubernetes-cus

Conversation

@yrenat

@yrenat yrenat commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Following discussion #6264, this PR adds backend-side cleanup for idle Kubernetes computing units.

The main change is a scheduled cleanup task in the computing unit managing service that periodically scans active Kubernetes computing units and terminates units that have been inactive longer than a configurable timeout.

The implementation includes the following changes:

  • Added new Kubernetes configuration entries for:
    • computing unit idle timeout
    • computing unit idle check interval
  • Exposed both settings through environment-variable-based configuration so deployment-side overrides can be applied without code changes.
  • Added a scheduled background task in ComputingUnitManagingService that runs the idle cleanup logic at a fixed interval.
  • Added idle Kubernetes computing unit termination logic in ComputingUnitManagingResource:
    • only considers Kubernetes computing units that are not already terminated
    • checks whether the computing unit has any active workflow executions
    • computes the latest execution activity timestamp from existing execution metadata
    • terminates the Kubernetes pod when the computing unit is considered idle past the configured timeout
    • updates the computing unit termination time in the database after cleanup

The timeout and check interval are configurable through environment variables, so the behavior can be tuned for different deployment or testing needs without modifying the code.

Any related issues, documentation, discussions?

Fixes #5362

How was this PR tested?

Tested locally on the Kubernetes deployment flow.

fix-idle-CU-demo.mp4

Was this PR authored or co-authored using generative AI tooling?

Generated-by: OpenAI Codex GPT-5

@github-actions github-actions Bot added fix common platform Non-amber Scala service paths labels Jul 1, 2026
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

👋 Thanks for opening this pull request, @yrenat!

It looks like the pull request description doesn't quite follow our template yet:

  • The What changes were proposed in this PR? section is missing; please keep the template's headings.
  • The How was this PR tested? section is missing; please keep the template's headings.
  • The Was this PR authored or co-authored using generative AI tooling? section is missing; please keep the template's headings.

Filling out the template helps reviewers understand and triage your contribution faster. Please edit the description to complete it. This message will disappear automatically once the template is followed.

You can find the template prompts by editing the description, or see CONTRIBUTING.md for the full contribution flow.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @tanishqgandhi1908, @Neilk1021, @aicam
    You can notify them by mentioning @tanishqgandhi1908, @Neilk1021, @aicam in a comment.

@codecov-commenter

codecov-commenter commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.03%. Comparing base (60300e3) to head (a624db6).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #6046   +/-   ##
=========================================
  Coverage     91.02%   91.03%           
- Complexity     4454     4459    +5     
=========================================
  Files          1174     1174           
  Lines         47146    47127   -19     
  Branches       5287     5283    -4     
=========================================
- Hits          42916    42903   -13     
+ Misses         2550     2549    -1     
+ Partials       1680     1675    -5     
Flag Coverage Δ *Carryforward flag
access-control-service 81.00% <ø> (ø)
agent-service 98.62% <ø> (ø) Carriedforward from e80add4
amber 87.49% <ø> (+0.03%) ⬆️ Carriedforward from e80add4
computing-unit-managing-service 73.34% <ø> (-0.33%) ⬇️ Carriedforward from e80add4
config-service 86.73% <ø> (ø)
file-service 68.90% <ø> (ø)
frontend 92.58% <ø> (-0.01%) ⬇️ Carriedforward from e80add4
notebook-migration-service 83.74% <ø> (ø)
pyamber 97.57% <ø> (ø) Carriedforward from e80add4
workflow-compiling-service 77.19% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 9 worse · ⚪ 6 noise (<±5%) · 0 without baseline

Compared against main 60300e3 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 404 0.247 23,525/34,106/34,106 us 🔴 +14.0% / 🔴 +113.4%
🔴 bs=100 sw=10 sl=64 928 0.567 106,521/131,965/131,965 us 🔴 +6.4% / 🔴 +23.0%
🔴 bs=1000 sw=10 sl=64 1,074 0.656 932,106/1,094,010/1,094,010 us 🔴 +8.9% / 🔴 +7.1%
Baseline details

Latest main 60300e3 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 404 tuples/sec 456 tuples/sec 779.07 tuples/sec -11.4% -48.1%
bs=10 sw=10 sl=64 MB/s 0.247 MB/s 0.278 MB/s 0.476 MB/s -11.2% -48.1%
bs=10 sw=10 sl=64 p50 23,525 us 20,636 us 12,818 us +14.0% +83.5%
bs=10 sw=10 sl=64 p95 34,106 us 30,899 us 15,986 us +10.4% +113.4%
bs=10 sw=10 sl=64 p99 34,106 us 30,899 us 19,339 us +10.4% +76.4%
bs=100 sw=10 sl=64 throughput 928 tuples/sec 962 tuples/sec 1,011 tuples/sec -3.5% -8.2%
bs=100 sw=10 sl=64 MB/s 0.567 MB/s 0.587 MB/s 0.617 MB/s -3.4% -8.1%
bs=100 sw=10 sl=64 p50 106,521 us 103,060 us 100,965 us +3.4% +5.5%
bs=100 sw=10 sl=64 p95 131,965 us 123,995 us 107,295 us +6.4% +23.0%
bs=100 sw=10 sl=64 p99 131,965 us 123,995 us 115,531 us +6.4% +14.2%
bs=1000 sw=10 sl=64 throughput 1,074 tuples/sec 1,057 tuples/sec 1,049 tuples/sec +1.6% +2.4%
bs=1000 sw=10 sl=64 MB/s 0.656 MB/s 0.645 MB/s 0.64 MB/s +1.7% +2.5%
bs=1000 sw=10 sl=64 p50 932,106 us 947,408 us 978,248 us -1.6% -4.7%
bs=1000 sw=10 sl=64 p95 1,094,010 us 1,004,359 us 1,021,881 us +8.9% +7.1%
bs=1000 sw=10 sl=64 p99 1,094,010 us 1,004,359 us 1,050,075 us +8.9% +4.2%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,494.52,200,128000,404,0.247,23524.91,34106.30,34106.30
1,100,10,64,20,2154.06,2000,1280000,928,0.567,106520.72,131965.07,131965.07
2,1000,10,64,20,18615.74,20000,12800000,1074,0.656,932106.07,1094010.36,1094010.36

@yrenat

yrenat commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

/request-review @aicam

@github-actions
github-actions Bot requested a review from aicam July 2, 2026 00:47
@chenlica

chenlica commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

In addition to @aicam , @kunwp1 please review it as well.

@aicam aicam 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.

Please add a new column to workflow_computing_unit which is "termination_reason" and we should have two types of termination (as of this PR):

  • USER_REQUESTED
  • GARBAGE_COLLECTED

@aicam aicam 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.

Please add a new column to workflow_computing_unit which is "termination_reason" and we should have two types of termination (as of this PR):

  • USER_REQUESTED
  • GARBAGE_COLLECTED

@github-actions github-actions Bot added the ddl-change Changes to the TexeraDB DDL label Jul 5, 2026
@yrenat
yrenat force-pushed the fix/idle-kubernetes-cus branch from 136f725 to a11601f Compare July 5, 2026 12:10
@yrenat

yrenat commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

this video shows the new effect:
I create 2 Computing Units, then delete 1 CU, and wait for another one to be auto-deleted. The log shows the output message for each case.

texera-PR6046.mp4

@chenlica

chenlica commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

@aicam @yrenat : we want to follow the practice of having a discussion before raising a PR. Can you create a discussion first?

@yrenat
yrenat requested a review from aicam July 6, 2026 14:35
@Yicong-Huang

Copy link
Copy Markdown
Contributor

@yrenat please also have more tests. the coverage is too low.

@yrenat

yrenat commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@aicam @yrenat : we want to follow the practice of having a discussion before raising a PR. Can you create a discussion first?

discussion added at: #6264

@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Jul 8, 2026
@yrenat

yrenat commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@yrenat please also have more tests. the coverage is too low.

done. The coverage is now 100%

@chenlica

Copy link
Copy Markdown
Contributor

@yrenat Before we continue this PR, can we first finish the discussion #6264 and draw a design conclusion?

@yrenat

yrenat commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

@yrenat Before we continue this PR, can we first finish the discussion #6264 and draw a design conclusion?

Yeah I'm working on that. Sorry for not replying promptly.

@Produces(Array(MediaType.APPLICATION_JSON))
@Path("/computing-unit")
class ComputingUnitManagingResource {
private val logger = LoggerFactory.getLogger(classOf[ComputingUnitManagingService])

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.

With this setup, the log line in terminateComputingUnit will emit under the service's logger name instead of the resource's (which is the class it is created under). I recommend using the resource class instead here:

Suggested change
private val logger = LoggerFactory.getLogger(classOf[ComputingUnitManagingService])
private val logger = LoggerFactory.getLogger(classOf[ComputingUnitManagingResource])

val cutoff = new Timestamp(now.getTime - cleanupConfig.idleTimeoutMinutes * 60 * 1000)
val activeStatuses = Seq(Short.box(0), Short.box(1), Short.box(2))

withTransaction(context) { ctx =>

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.

A single DB transaction appears to handle the full scan and deletion of pods. I recommend deleting pods outside the transaction or committing per unit, so one failure does not undo the whole batch.

@github-actions github-actions Bot added frontend Changes related to the frontend GUI ci changes related to CI and removed dependencies Pull requests that update a dependency file labels Aug 14, 2026
@yrenat
yrenat force-pushed the fix/idle-kubernetes-cus branch from 65c2db2 to e551284 Compare August 15, 2026 09:39
@github-actions github-actions Bot added dependencies Pull requests that update a dependency file and removed frontend Changes related to the frontend GUI ci changes related to CI labels Aug 15, 2026
@chenlica
chenlica requested a review from kunwp1 August 16, 2026 18:32
@chenlica

Copy link
Copy Markdown
Contributor

@yrenat If you think the PR is ready, please ask @aicam to review. Then @kunwp1 can review it.

…-cus

# Conflicts:
#	build.sbt
#	computing-unit-managing-service/src/main/scala/org/apache/texera/service/resource/ComputingUnitManagingResource.scala
#	computing-unit-managing-service/src/test/scala/org/apache/texera/service/ComputingUnitManagingServiceRunSpec.scala
#	computing-unit-managing-service/src/test/scala/org/apache/texera/service/resource/ComputingUnitManagingResourceSpec.scala
#	sql/texera_ddl.sql
#	sql/updates/28.sql
@yrenat
yrenat force-pushed the fix/idle-kubernetes-cus branch from 534bdad to 522a05d Compare August 18, 2026 07:28
@github-actions github-actions Bot removed the dependencies Pull requests that update a dependency file label Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common ddl-change Changes to the TexeraDB DDL fix platform Non-amber Scala service paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automatically terminate idle Computing Units to reclaim cluster resources

6 participants