-
Notifications
You must be signed in to change notification settings - Fork 78
feat(optimizer): [4/N] Scheduler app #534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
294 commits
Select commit
Hold shift + click to select a range
8054586
refactor(optimizer-analyzer): delete unused AnalyzerConfig
mkuchenbecker a9104ae
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 5af5f14
refactor(optimizer-analyzer): remove circuit breaker, defer with TODO
mkuchenbecker cbddc5d
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 62f426a
feat(optimizer): add findLatestPerTable to history repo
mkuchenbecker e13a31b
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 442f1e4
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker c4f194a
perf(optimizer-analyzer): use findLatestPerTable for history lookup
mkuchenbecker 790994e
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 6da624a
refactor(optimizer-analyzer): typed OperationType/Status, polish cade…
mkuchenbecker 9913b77
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 52ba858
refactor(optimizer-analyzer): rename OrphanFilesDeletionAnalyzer → Ca…
mkuchenbecker beedad8
fix(optimizer-analyzer): update class name inside renamed files
mkuchenbecker f63a952
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 3483b25
perf(optimizer): index table_operations_history for findLatestPerTable
mkuchenbecker 9748548
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker e4a1ad1
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker f663537
docs(optimizer-analyzer): add scale roadmap as block comment
mkuchenbecker 8ad9cac
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker d7e3a65
docs(optimizer-analyzer): move scale roadmap to BDP-102182
mkuchenbecker 0069b92
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 0293009
feat(optimizer): add findDistinctDatabaseNames to TableStatsRepository
mkuchenbecker 0efab45
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 6fa885d
refactor(optimizer): Optional<T> for optional filter params in servic…
mkuchenbecker a5585f4
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker dd4faf2
refactor(optimizer-analyzer): address PR review — required op, per-db…
mkuchenbecker 0668486
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 91ba362
style(optimizer-analyzer): tighten AnalyzerRunner.analyze body
mkuchenbecker b315c11
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker eba1392
feat(optimizer): promote internal model types to shared apps/optimizer
mkuchenbecker 10ed1bb
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 35bcd38
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 0dbe3d9
refactor(optimizer-analyzer): import shared model + explanatory comment
mkuchenbecker e80f9ce
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker ded97d0
refactor(optimizer-scheduler): per-op BinPacker interface, TableOpera…
mkuchenbecker e576593
refactor(optimizer): rename apps/optimizer entities + repos to plural…
mkuchenbecker 9f88a4a
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 6f98e1a
refactor(optimizer): consolidate entities/repos into apps/optimizer; …
mkuchenbecker d44783f
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker ef78c17
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker d90c26f
refactor(optimizer): move apps/optimizer module into services/optimizer
mkuchenbecker 62f33b7
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 17e280f
refactor(optimizer): drop apps/optimizer-data dep; simplify history API
mkuchenbecker a5df7e4
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker b0898e3
refactor(optimizer-analyzer): depend on :services:optimizer
mkuchenbecker 7a0d6d2
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 8142af3
refactor(optimizer-scheduler): depend on :services:optimizer; drop de…
mkuchenbecker 9a129a8
refactor(optimizer): align data model — rename HistoryStatus; String …
mkuchenbecker a8978a0
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker dfb9102
refactor(optimizer): realign entity shapes with optimizer-0
mkuchenbecker e3bf9e1
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker fb71bd9
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 681407e
feat(optimizer): add internal model layer
mkuchenbecker 2005bca
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker b689969
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 7ea8868
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker d7767e8
fix(optimizer-analyzer): rewrite AnalyzerRunnerTest to use entity bui…
mkuchenbecker 3ec0b0a
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker e3fb777
perf(optimizer): index table_operations_history for findLatestPerTable
mkuchenbecker f89889d
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker beaaf88
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 4a8796c
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 949e814
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker d3e1726
refactor(optimizer): enforce layer boundaries in api/ + model/
mkuchenbecker db9513a
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 1d469a7
refactor(optimizer): remove db-layer types from optimizer-0
mkuchenbecker eee8eca
refactor(optimizer): remove DB schema + schema-init properties
mkuchenbecker 0567753
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 328e5b9
refactor(optimizer): scrub MySQL / JPA / datasource references
mkuchenbecker f7a5d20
refactor(optimizer): drop UpsertTableOperationsRequest
mkuchenbecker 2a532b5
refactor(optimizer): drop JobResult from the wire and internal model
mkuchenbecker 2e3a231
feat(optimizer): add debug echo fields to CompleteOperationRequest
mkuchenbecker db5eb29
refactor(optimizer): move application.properties out of optimizer-0
mkuchenbecker bbcf84a
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker ac3abc0
feat(optimizer): introduce db/ layer with per-layer types
mkuchenbecker e79eec7
refactor(optimizer): split TableStats envelope into snapshot + delta …
mkuchenbecker f955ded
fix(optimizer): drop CommitDeltaMetrics from TableStatsRow
mkuchenbecker 13987c1
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 969949d
refactor(optimizer): rewire service layer onto api/model/db mappers
mkuchenbecker 861b584
feat(optimizer): extend model layer for service-only types
mkuchenbecker 41d4c6d
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 69d9e8f
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker b60a3bf
feat(optimizer): extend ModelDbMapper for service-only types
mkuchenbecker eb6e3be
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker b80b2e5
refactor(optimizer): service layer returns only model/ types
mkuchenbecker ef453ca
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker ad11533
refactor(optimizer-analyzer): consume model/ types and ModelDbMapper
mkuchenbecker 0c36ff2
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 25d98aa
feat(optimizer): restore batch CAS methods on TableOperationsRepository
mkuchenbecker 31fac5b
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 51dab67
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 3a4f0a8
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 3fee7ab
refactor(optimizer-scheduler): consume model/ types and ModelDbMapper
mkuchenbecker 188713d
docs(optimizer): comment every field on opt-0 api/ and model/ types
mkuchenbecker f060b5e
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 1119699
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 619df83
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker a04cad6
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 8d64273
refactor(optimizer): remove clusterId from SnapshotMetrics
mkuchenbecker ee7bcab
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker c1ad246
refactor(optimizer): comment every db/ field; drop clusterId and version
mkuchenbecker 72b431c
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 0b30130
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker e183906
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker b2fd321
fix(optimizer-scheduler): drop .version(0L) from SchedulerRunnerTest
mkuchenbecker c72aae8
refactor(optimizer): move api↔model conversion onto api types; delete…
mkuchenbecker 1fca287
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 8ae8777
refactor(optimizer): move model↔db conversion onto model types; delet…
mkuchenbecker b3aacff
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker bb8aa4d
refactor(optimizer): service + controllers use type to/from methods
mkuchenbecker 6a23755
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 95456be
refactor(optimizer-analyzer): use type to/from methods; drop ModelDbM…
mkuchenbecker b9620e3
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker de9b0e1
refactor(optimizer-scheduler): use type to/from methods; drop ModelDb…
mkuchenbecker af23d5e
fix(optimizer): make TableStats self-describing; route DTO conversion…
mkuchenbecker 3864e42
chore(optimizer): cascade self-describing TableStats from opt-0 to opt-1
mkuchenbecker 0a1125b
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker a6045b5
feat(optimizer): add TableStats↔TableStatsRow conversion on model
mkuchenbecker 4427de0
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker db5921e
refactor(optimizer): service stats methods take/return TableStats, no…
mkuchenbecker d82c17f
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker f74c6f9
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 3aebf64
chore(optimizer): enable toBuilder on model.Table and model.TableOper…
mkuchenbecker bf30f86
chore(optimizer): cascade toBuilder annotations from opt-0 to opt-1
mkuchenbecker faba6d7
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 1d56fa6
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker d0ec73e
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker b6c7f42
refactor(optimizer): drop fileCount enrichment from model.TableOperation
mkuchenbecker 177af95
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 487ac56
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 6ffc703
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 7f51360
chore(analyzer): add TODOs for scale tests and query-builder migration
mkuchenbecker 2903e0b
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 9ad8861
refactor(scheduler): TableStats at BinPacker interface; Bin owns its …
mkuchenbecker a325684
refactor(scheduler): BinPacker takes List<SchedulingCandidate> pairs
mkuchenbecker 9e5fbae
style(scheduler): convert FileCountBinPacker for-loops to functional …
mkuchenbecker 7dd1e97
refactor(scheduler): final resultsEndpoint, throw on missing packer, …
mkuchenbecker 2b06c92
feat(repo): add findClaimedIds for transactional batch-claim verifica…
mkuchenbecker 5b5aae2
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker c862777
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 7935f43
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker c73d8cb
fix(scheduler): only launch + mark SCHEDULED the ops actually claimed
mkuchenbecker ad1bf4c
feat(scheduler): add SingletonBinPacker; register for SNAPSHOT_EXPIRA…
mkuchenbecker d9ffe48
docs(scheduler): strip editorial commentary from SingletonBinPacker j…
mkuchenbecker ad88893
Revert "docs(scheduler): strip editorial commentary from SingletonBin…
mkuchenbecker ac7f84d
Revert "feat(scheduler): add SingletonBinPacker; register for SNAPSHO…
mkuchenbecker 437a0ed
refactor(optimizer): add Dto suffix to all api/model classes (PR #527…
mkuchenbecker aabb51c
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker 928d537
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker eedf6d0
refactor(optimizer): update controllers for renamed api/model Dto types
mkuchenbecker 1166efb
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker e492f7c
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 4f98c22
refactor(optimizer): rename api.model package to api.spec (PR #527 re…
mkuchenbecker 2c26872
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker b849b7d
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 231efde
refactor(optimizer): update controller imports for api.model -> api.s…
mkuchenbecker a2580b1
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 9a0ab09
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker f1c500b
refactor(optimizer): hard-fail in AnalyzerRunner if no analyzer is re…
mkuchenbecker d315227
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker f788ab6
fix(analyzer): point @EntityScan at the actual db package
mkuchenbecker bb52e7a
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 0b87381
fix(scheduler): point @EntityScan at the actual db package
mkuchenbecker b31decf
refactor(optimizer): move Dto suffix from api/spec to model
mkuchenbecker caf3294
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker c6a64bf
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 91e89ef
refactor(optimizer): update controller + service refs after Dto suffi…
mkuchenbecker 8a4251d
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker c305aa9
refactor(analyzer): update model refs after Dto suffix swap
mkuchenbecker 428cb17
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker f6c4674
refactor(scheduler): update model refs after Dto suffix swap
mkuchenbecker 4e86569
feat(optimizer): propagate jobId through model + api conversions
mkuchenbecker cc8aa80
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker efcceea
feat(optimizer): propagate jobId through model ↔ db conversions
mkuchenbecker f85edd5
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker c00f201
chore(optimizer): rename OPTIMIZER_DB_USERNAME → OPTIMIZER_DB_USER
mkuchenbecker 6998a0f
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 5cbdbcb
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker a89a600
fix(scheduler): four runtime gaps surfaced by docker e2e
mkuchenbecker 1fe71f0
refactor(optimizer): rename CompleteOperationRequest → UpdateOperatio…
mkuchenbecker fb5e726
Merge branch 'mkuchenb/optimizer-0' into mkuchenb/optimizer-1
mkuchenbecker ad0c0f1
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 947bedf
refactor(optimizer): rename completeOperation → updateOperation
mkuchenbecker ce5745b
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker c99bc3a
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker b96c388
Merge remote-tracking branch 'linkedin/main' into mkuchenb/optimizer-1
mkuchenbecker d65b511
refactor(optimizer-repo): unify find/updateBatch with Optional params
mkuchenbecker 78de390
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 49e43bc
refactor(optimizer-service): use Optional repo API + configurable limit
mkuchenbecker 210d5f0
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 040046e
refactor(analyzer): switch to Optional repo API + configurable limit
mkuchenbecker 6dd07bd
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 66aa3e7
refactor(scheduler): switch to Optional repo API + dedup per cycle
mkuchenbecker b69e09a
test(optimizer-repo): truncate Instant to micros for CI precision
mkuchenbecker a028a98
Merge branch 'mkuchenb/optimizer-1' into mkuchenb/optimizer-2
mkuchenbecker 2b6f67c
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 231320c
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 6eb6a1e
Merge remote-tracking branch 'linkedin/main' into mkuchenb/optimizer-2
mkuchenbecker de39a78
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 3309983
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker a89e037
feat(optimizer): require limit on list-API endpoints
mkuchenbecker 1e361af
feat(optimizer): basic error-code handling across controllers
mkuchenbecker a37169d
refactor(optimizer): simplify error handling per PR review
mkuchenbecker 6416c9d
refactor(optimizer): drop GlobalExceptionHandler + ApiError; use Spri…
mkuchenbecker bbef386
refactor(optimizer): revert UpdateOperationRequest doc edits
mkuchenbecker 02bbc5c
(wip) feat(optimizer): basic error-code handling across controllers (…
mkuchenbecker 266e2a7
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker e8d2c7a
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 144da72
Merge remote-tracking branch 'linkedin/mkuchenb/optimizer-2' into mku…
mkuchenbecker c74ad5f
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 1866033
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 6ef7964
docs(optimizer): add @ApiResponses to controllers for OpenAPI spec
mkuchenbecker 357d5c2
Merge branch 'mkuchenb/optimizer-2' into mkuchenb/optimizer-3
mkuchenbecker 020e94a
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 08bebcb
Merge commit '78ba0abd' into mkuchenb/optimizer-3
mkuchenbecker d7dead0
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker 9abde3b
refactor(optimizer): inline analyzer.getOperationType().toDb() per re…
mkuchenbecker e7321d0
refactor(optimizer-analyzer): audit fixes per review
mkuchenbecker eae3a4a
refactor(optimizer-analyzer): nest under apps/optimizer/analyzer
mkuchenbecker 3ef5eaf
Merge mkuchenb/optimizer-3 + nest scheduler under apps/optimizer/sche…
mkuchenbecker a638541
style: spotless format on SchedulerRunner after package rename
mkuchenbecker 2477530
refactor(optimizer-analyzer): move from apps/ to services/optimizer/a…
mkuchenbecker f529a5c
refactor(optimizer-analyzer): rename property to analyzer.max-tables-…
mkuchenbecker 8e5e97c
style: spotless format on AnalyzerRunner
mkuchenbecker 87b9a75
fix(optimizer-analyzer): paginate per-DB scan to process all tables
mkuchenbecker 4b05cb2
style: spotless format on AnalyzerRunner
mkuchenbecker 21dbf34
Update services/optimizer/analyzer/src/main/java/com/linkedin/openhou…
mkuchenbecker adbff95
(wip) refactor(optimizer-analyzer): split AnalyzerApplication into ap…
mkuchenbecker eccd2bc
Merge mkuchenb/optimizer-3 into mkuchenb/optimizer-4
mkuchenbecker b183f9c
refactor(optimizer-scheduler): split into services/optimizer/schedule…
mkuchenbecker 663564c
docs(optimizer-analyzer): strip BDP ticket references from javadoc
mkuchenbecker cfe5509
Merge branch 'mkuchenb/optimizer-3' into mkuchenb/optimizer-4
mkuchenbecker f3fe80a
docs(optimizer-scheduler): strip BDP ticket reference from javadoc
mkuchenbecker 8cb1a37
Merge remote-tracking branch 'linkedin/main' into mkuchenb/optimizer-4
mkuchenbecker 9630e57
test(scheduler): use canonical optimizer-schema.sql; drop duplicate
mkuchenbecker 84a3532
Update services/optimizer/scheduler/src/main/java/com/linkedin/openho…
mkuchenbecker 2cb7c54
refactor(scheduler): prefix all scheduler config properties with opti…
mkuchenbecker 3f1173b
refactor(scheduler): exit JVM with Spring exit code for clean shutdown
mkuchenbecker 10a5dda
refactor(scheduler): adopt full ExitCodeGenerator pattern from review
mkuchenbecker 055e482
refactor(scheduler): make bin packing a generic utility per #534 review
mkuchenbecker f02cd0e
refactor(scheduler): inline single-use helpers; affirmative dedup split
mkuchenbecker 564cbe9
style(scheduler): inline getter aliases in scheduleBin
mkuchenbecker 5637156
docs(scheduler): drop overclaimed unpaged-correctness comment
mkuchenbecker 26c525f
refactor(scheduler): cancel handles empty; collapse toCancel + uuidsT…
mkuchenbecker 09de807
refactor(scheduler): drop intermediate locals + log lines in schedule()
mkuchenbecker 6ae576f
refactor(scheduler): cancelIfNonEmpty lambda; revert repo guard
mkuchenbecker c16c0d2
refactor(scheduler): cancel as collectingAndThen finisher
mkuchenbecker 354b909
refactor(scheduler): extract claim(); ifPresentOrElse for launch outcome
mkuchenbecker 093755e
Apply suggestion from @mkuchenbecker
mkuchenbecker 6583384
refactor(optimizer): extract bin packing to :libs:optimizer:binpack
mkuchenbecker File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| plugins { | ||
| id 'openhouse.springboot-ext-conventions' | ||
| id 'openhouse.maven-publish' | ||
| id 'org.springframework.boot' version '2.7.8' | ||
| } | ||
|
|
||
| // Deployable Spring Boot wrapper around the scheduler library. Holds SchedulerApplication (the | ||
| // @SpringBootApplication entry point) and application.properties; the scheduling logic lives in | ||
| // :services:optimizer:scheduler. | ||
| dependencies { | ||
| implementation project(':services:optimizer:scheduler') | ||
| implementation 'org.springframework.boot:spring-boot-starter:2.7.8' | ||
| implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.7.8' | ||
| runtimeOnly 'mysql:mysql-connector-java:8.0.33' | ||
| } | ||
59 changes: 59 additions & 0 deletions
59
...lerapp/src/main/java/com/linkedin/openhouse/optimizer/scheduler/SchedulerApplication.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package com.linkedin.openhouse.optimizer.scheduler; | ||
|
|
||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.boot.CommandLineRunner; | ||
| import org.springframework.boot.ExitCodeGenerator; | ||
| import org.springframework.boot.SpringApplication; | ||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| import org.springframework.boot.autoconfigure.domain.EntityScan; | ||
| import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | ||
|
|
||
| /** | ||
| * Entry point for the Optimizer Scheduler application. | ||
| * | ||
| * <p>Spring Batch–style: implements {@link CommandLineRunner} so the work runs after context | ||
| * startup, and {@link ExitCodeGenerator} so the JVM exit code reflects batch outcome. {@code | ||
| * SpringApplication.exit(...)} closes the context (triggers {@code @PreDestroy} hooks, drains the | ||
| * JPA pool, etc.) so the k8s CronJob pod terminates cleanly with a status reflecting reality. | ||
| */ | ||
| @Slf4j | ||
| @SpringBootApplication | ||
| @EntityScan(basePackages = "com.linkedin.openhouse.optimizer.db") | ||
| @EnableJpaRepositories(basePackages = "com.linkedin.openhouse.optimizer.repository") | ||
| public class SchedulerApplication implements CommandLineRunner, ExitCodeGenerator { | ||
|
|
||
| private final SchedulerRunner runner; | ||
| private int exitCode = 0; | ||
|
|
||
| @Autowired | ||
| public SchedulerApplication(SchedulerRunner runner) { | ||
| this.runner = runner; | ||
| } | ||
|
|
||
| public static void main(String[] args) { | ||
| System.exit(SpringApplication.exit(SpringApplication.run(SchedulerApplication.class, args))); | ||
| } | ||
|
|
||
| /** | ||
| * Runs the scheduler once per registered operation type per process invocation. Any thrown | ||
| * exception is logged and surfaces as a non-zero exit code via {@link #getExitCode()} after the | ||
| * context is shut down cleanly. | ||
| */ | ||
| @Override | ||
| public void run(String... args) { | ||
| try { | ||
| log.info("Scheduler starting; operation types: {}", runner.getRegisteredOperationTypes()); | ||
| runner.getRegisteredOperationTypes().forEach(runner::schedule); | ||
| log.info("Scheduler completed successfully"); | ||
| } catch (Exception e) { | ||
| log.error("Scheduler failed", e); | ||
| exitCode = 1; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public int getExitCode() { | ||
| return exitCode; | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions
14
apps/optimizer/schedulerapp/src/main/resources/application.properties
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| spring.application.name=openhouse-optimizer-scheduler | ||
| spring.main.web-application-type=none | ||
| spring.main.banner-mode=off | ||
| spring.datasource.url=${OPTIMIZER_DB_URL:jdbc:h2:mem:schedulerdb;DB_CLOSE_DELAY=-1;MODE=MySQL} | ||
| spring.datasource.username=${OPTIMIZER_DB_USER:sa} | ||
| spring.datasource.password=${OPTIMIZER_DB_PASSWORD:} | ||
| spring.jpa.hibernate.ddl-auto=none | ||
| optimizer.scheduler.jobs.base-uri=${JOBS_BASE_URI:http://localhost:8002} | ||
| # Per-bin caps for ORPHAN_FILES_DELETION; 0 disables a dimension. File count is the OFD cost | ||
| # driver — per-file list, manifest joins, and delete calls dominate, independent of file size. | ||
| optimizer.scheduler.ofd.max-files-per-bin=${SCHEDULER_OFD_MAX_FILES_PER_BIN:1000000} | ||
| optimizer.scheduler.ofd.max-tables-per-bin=${SCHEDULER_OFD_MAX_TABLES_PER_BIN:50} | ||
| optimizer.scheduler.results-endpoint=${SCHEDULER_RESULTS_ENDPOINT:http://openhouse-optimizer:8080/v1/optimizer/operations} | ||
| optimizer.scheduler.cluster-id=${SCHEDULER_CLUSTER_ID:LocalHadoopCluster} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| plugins { | ||
| id 'openhouse.java-conventions' | ||
| id 'openhouse.maven-publish' | ||
| } | ||
|
|
||
| dependencies { | ||
| // api: bin-packing types reference TableOperationDto / TableStatsDto, which consumers need on | ||
| // their compile classpath. | ||
| api project(':services:optimizer') | ||
| api 'org.slf4j:slf4j-api:1.7.36' | ||
| } | ||
|
|
||
| test { | ||
| useJUnitPlatform() | ||
| } |
20 changes: 20 additions & 0 deletions
20
libs/optimizer/binpack/src/main/java/com/linkedin/openhouse/optimizer/binpack/Bin.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.linkedin.openhouse.optimizer.binpack; | ||
|
|
||
| import com.linkedin.openhouse.optimizer.model.OperationTypeDto; | ||
| import java.util.List; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
| import lombok.ToString; | ||
|
|
||
| /** | ||
| * One scheduling unit: the operation type the bin will run as, and the items the scheduler will | ||
| * claim, narrow to claimed, and launch a single Spark job for. Pure data — the scheduler reads from | ||
| * a bin to do the work; the bin does no IO itself. | ||
| */ | ||
| @AllArgsConstructor | ||
| @Getter | ||
| @ToString | ||
| public class Bin { | ||
|
abhisheknath2011 marked this conversation as resolved.
|
||
| private final OperationTypeDto operationType; | ||
| private final List<BinItem> items; | ||
| } | ||
24 changes: 24 additions & 0 deletions
24
libs/optimizer/binpack/src/main/java/com/linkedin/openhouse/optimizer/binpack/BinItem.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.linkedin.openhouse.optimizer.binpack; | ||
|
|
||
| import com.linkedin.openhouse.optimizer.model.TableOperationDto; | ||
| import com.linkedin.openhouse.optimizer.model.TableStatsDto; | ||
|
|
||
| /** | ||
| * One packable unit. Exposes the weight a packer keys on, plus the identity the scheduler reads | ||
| * when it launches a Spark job (fully-qualified table name, operation id). | ||
| * | ||
| * <p>Implementations have a public no-arg constructor — instantiated transiently inside {@link | ||
| * FirstFitBinPacker#pack} via a {@code Supplier<T extends BinItem>} (typically a {@code | ||
| * MyItem::new} method reference) — on which {@link #fromOpAndStats} is called to return the | ||
| * populated item. Getters on the empty instance are not meaningful; it exists for the lifetime of a | ||
| * single projection call. | ||
| */ | ||
| public interface BinItem { | ||
| long getWeight(); | ||
|
|
||
| String getFullyQualifiedTableName(); | ||
|
|
||
| String getOperationId(); | ||
|
|
||
| BinItem fromOpAndStats(TableOperationDto op, TableStatsDto stats); | ||
| } |
18 changes: 18 additions & 0 deletions
18
libs/optimizer/binpack/src/main/java/com/linkedin/openhouse/optimizer/binpack/BinPacker.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package com.linkedin.openhouse.optimizer.binpack; | ||
|
|
||
| import com.linkedin.openhouse.optimizer.model.TableOperationDto; | ||
| import com.linkedin.openhouse.optimizer.model.TableStatsDto; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Per-operation-type strategy. Given a flat list of operations and the corresponding stats, returns | ||
| * one grouping per batch the scheduler should submit. The scheduler wraps each grouping into a | ||
| * {@link Bin} with the registered operation type. Implementations do no IO and hold no mutable | ||
| * state; the projection from {@code (op, stats)} to {@link BinItem} and the bucketing strategy both | ||
| * live in the implementation. | ||
| */ | ||
| public interface BinPacker { | ||
| List<List<BinItem>> pack( | ||
| List<TableOperationDto> operations, Map<String, TableStatsDto> statsByTableUuid); | ||
| } |
92 changes: 92 additions & 0 deletions
92
...zer/binpack/src/main/java/com/linkedin/openhouse/optimizer/binpack/FirstFitBinPacker.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| package com.linkedin.openhouse.optimizer.binpack; | ||
|
|
||
| import com.linkedin.openhouse.optimizer.model.TableOperationDto; | ||
| import com.linkedin.openhouse.optimizer.model.TableStatsDto; | ||
| import java.util.ArrayList; | ||
| import java.util.Comparator; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.function.Supplier; | ||
| import java.util.stream.Collectors; | ||
| import lombok.extern.slf4j.Slf4j; | ||
|
|
||
| /** | ||
| * First-fit-decreasing packing, generic over the concrete {@link BinItem} subtype {@code T}. | ||
| * Construction takes a {@code Supplier<T>} — typically a {@code MyItem::new} method reference — | ||
| * which the packer invokes per operation to get an empty instance, then calls {@link | ||
| * BinItem#fromOpAndStats} on it to project the (operation, stats) pair into a populated item. | ||
| * | ||
| * <p>Sorts items by weight descending, then places each into the first group whose totals stay at | ||
| * or below {@code maxWeightPerBin} and {@code maxItemsPerBin}. An item whose weight exceeds the cap | ||
| * on its own goes into a group by itself. Operations whose {@code tableUuid} has no entry in {@code | ||
| * statsByTableUuid} are dropped. | ||
| * | ||
| * <p>Stateless: the constructor takes only the BinItem supplier and the cap configuration; {@link | ||
| * #pack} is a pure function over its arguments. The packer is operation-agnostic — the scheduler | ||
| * wraps each grouping into a {@link Bin} with the registered operation type. | ||
| */ | ||
| @Slf4j | ||
| public class FirstFitBinPacker<T extends BinItem> implements BinPacker { | ||
|
|
||
| private final Supplier<T> binItemSupplier; | ||
| private final long maxWeightPerBin; | ||
| private final int maxItemsPerBin; | ||
|
|
||
| public FirstFitBinPacker(Supplier<T> binItemSupplier, long maxWeightPerBin, int maxItemsPerBin) { | ||
| this.binItemSupplier = binItemSupplier; | ||
| this.maxWeightPerBin = maxWeightPerBin; | ||
| this.maxItemsPerBin = maxItemsPerBin; | ||
| } | ||
|
|
||
| @Override | ||
| public List<List<BinItem>> pack( | ||
|
abhisheknath2011 marked this conversation as resolved.
|
||
| List<TableOperationDto> operations, Map<String, TableStatsDto> statsByTableUuid) { | ||
|
abhisheknath2011 marked this conversation as resolved.
|
||
| List<BinItem> items = | ||
| operations.stream() | ||
| .filter(op -> statsByTableUuid.containsKey(op.getTableUuid())) | ||
| .map( | ||
| op -> | ||
| binItemSupplier | ||
| .get() | ||
| .fromOpAndStats(op, statsByTableUuid.get(op.getTableUuid()))) | ||
| .collect(Collectors.toList()); | ||
| List<PackingBin> packingBins = | ||
| items.stream() | ||
| .sorted(Comparator.comparingLong(BinItem::getWeight).reversed()) | ||
| .collect(ArrayList::new, this::placeItem, List::addAll); | ||
| log.info( | ||
| "Packed {} operations ({} items after projection) into {} groupings", | ||
| operations.size(), | ||
| items.size(), | ||
| packingBins.size()); | ||
| return packingBins.stream().map(pb -> pb.items).collect(Collectors.toList()); | ||
| } | ||
|
|
||
| private void placeItem(List<PackingBin> bins, BinItem item) { | ||
| bins.stream() | ||
| .filter(b -> b.fits(item, maxWeightPerBin, maxItemsPerBin)) | ||
| .findFirst() | ||
| .ifPresentOrElse( | ||
| b -> b.add(item), | ||
| () -> { | ||
| PackingBin fresh = new PackingBin(); | ||
| fresh.add(item); | ||
| bins.add(fresh); | ||
| }); | ||
| } | ||
|
|
||
| /** Running-totals helper used during the fold. */ | ||
| private static class PackingBin { | ||
| final List<BinItem> items = new ArrayList<>(); | ||
| long totalWeight; | ||
|
|
||
| boolean fits(BinItem item, long maxWeight, int maxItems) { | ||
| return items.size() < maxItems && totalWeight + item.getWeight() <= maxWeight; | ||
| } | ||
|
|
||
| void add(BinItem item) { | ||
| items.add(item); | ||
| totalWeight += item.getWeight(); | ||
| } | ||
| } | ||
| } | ||
49 changes: 49 additions & 0 deletions
49
...zer/binpack/src/main/java/com/linkedin/openhouse/optimizer/binpack/TotalFilesBinItem.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| package com.linkedin.openhouse.optimizer.binpack; | ||
|
|
||
| import com.linkedin.openhouse.optimizer.model.TableOperationDto; | ||
| import com.linkedin.openhouse.optimizer.model.TableStatsDto; | ||
| import java.util.Optional; | ||
| import lombok.Getter; | ||
| import lombok.ToString; | ||
|
|
||
| /** | ||
| * {@link BinItem} that weights by the table's current file count. Suitable for any operation whose | ||
| * Spark cost scales with file count — orphan files deletion, stats collection, etc. The | ||
| * implementation knows nothing about which operation type it is wired up to. | ||
| * | ||
| * <p>Construction: callers pass {@code TotalFilesBinItem::new} as the {@code Supplier<T>} to {@link | ||
| * FirstFitBinPacker}; the packer calls the supplier per operation to get an empty instance, then | ||
| * {@link #fromOpAndStats} on it to get a populated copy. | ||
| */ | ||
| @Getter | ||
| @ToString | ||
| public class TotalFilesBinItem implements BinItem { | ||
|
|
||
| private final String fullyQualifiedTableName; | ||
| private final String operationId; | ||
| private final long weight; | ||
|
|
||
| /** Empty constructor: call {@link #fromOpAndStats} on the result to get a populated instance. */ | ||
| public TotalFilesBinItem() { | ||
| this("", "", 0L); | ||
| } | ||
|
|
||
| private TotalFilesBinItem(String fullyQualifiedTableName, String operationId, long weight) { | ||
| this.fullyQualifiedTableName = fullyQualifiedTableName; | ||
| this.operationId = operationId; | ||
| this.weight = weight; | ||
| } | ||
|
|
||
| @Override | ||
| public BinItem fromOpAndStats(TableOperationDto op, TableStatsDto stats) { | ||
| return new TotalFilesBinItem( | ||
| op.getDatabaseName() + "." + op.getTableName(), op.getId(), currentFileCount(stats)); | ||
| } | ||
|
|
||
| private static long currentFileCount(TableStatsDto stats) { | ||
| return Optional.ofNullable(stats) | ||
| .map(TableStatsDto::getSnapshot) | ||
| .map(TableStatsDto.SnapshotMetrics::getNumCurrentFiles) | ||
| .orElse(0L); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.