-
Notifications
You must be signed in to change notification settings - Fork 16
feat(judge): deploy workload-specific worker pools #3723
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
Open
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b847d3c
feat(judge): configure request routing keys
lshtar13 a25470a
docs(judge): describe workload routing
lshtar13 6e6006e
test(judge): satisfy routing test lint rules
lshtar13 0515e3c
Merge branch 'main' into t2852-nest-routing-env
lshtar13 ec45abb
fix(judge): keep split routing keys opt-in
lshtar13 c775f74
feat(judge): deploy workload-specific worker pools
lshtar13 ebfd858
fix(judge): preserve local submission queue priority
lshtar13 bbbc6b7
feat(dev): configure local Iris worker launches
lshtar13 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
Some comments aren't visible on the classic Files Changed page.
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
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
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
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
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,106 @@ | ||
| import type { ConfigService } from '@nestjs/config' | ||
| import type { AmqpConnection } from '@golevelup/nestjs-rabbitmq' | ||
| import { expect } from 'chai' | ||
| import type { TraceService } from 'nestjs-otel' | ||
| import * as sinon from 'sinon' | ||
| import { DEFAULT_SUBMISSION_KEY, EXCHANGE } from '@libs/constants' | ||
| import { JudgeAMQPService } from './amqp.service' | ||
|
|
||
| type RoutingKeyConfig = Partial< | ||
| Record< | ||
| | 'SUBMISSION_KEY' | ||
| | 'TEST_KEY' | ||
| | 'REJUDGE_KEY' | ||
| | 'JUDGE_SUBMISSION_ROUTING_KEY', | ||
| string | ||
| > | ||
| > | ||
|
|
||
| describe('JudgeAMQPService', () => { | ||
| const sandbox = sinon.createSandbox() | ||
| const publish = sandbox.stub().resolves() | ||
| const traceService = { | ||
| startSpan: sandbox.stub().returns({ | ||
| setAttributes: sandbox.stub(), | ||
| end: sandbox.stub() | ||
| }) | ||
| } as unknown as TraceService | ||
|
|
||
| afterEach(() => { | ||
| sandbox.resetHistory() | ||
| }) | ||
|
|
||
| const createService = function (config: RoutingKeyConfig) { | ||
| const configService = { | ||
| get: (key: keyof RoutingKeyConfig) => config[key] | ||
| } as ConfigService | ||
|
|
||
| return new JudgeAMQPService( | ||
| { publish } as unknown as AmqpConnection, | ||
| traceService, | ||
| configService | ||
| ) | ||
| } | ||
|
|
||
| const expectRoutingKey = async function ( | ||
| service: JudgeAMQPService, | ||
| routingKey: string, | ||
| isTest = false, | ||
| isUserTest = false, | ||
| isRejudge = false | ||
| ) { | ||
| await service.publishJudgeRequestMessage( | ||
| { request: routingKey }, | ||
| 42, | ||
| isTest, | ||
| isUserTest, | ||
| isRejudge | ||
| ) | ||
|
|
||
| expect(publish.calledWith(EXCHANGE, routingKey)).to.be.true | ||
| sandbox.resetHistory() | ||
| } | ||
|
|
||
| const createRoutingKeyConfig = function ( | ||
| entries: [keyof RoutingKeyConfig, string][] | ||
| ): RoutingKeyConfig { | ||
| return Object.fromEntries(entries) | ||
| } | ||
|
|
||
| it('uses workload-specific routing keys when configured', async () => { | ||
| const service = createService( | ||
| createRoutingKeyConfig([ | ||
| ['SUBMISSION_KEY', 'submission.key'], | ||
| ['TEST_KEY', 'test.key'], | ||
| ['REJUDGE_KEY', 'rejudge.key'] | ||
| ]) | ||
| ) | ||
|
|
||
| await expectRoutingKey(service, 'submission.key') | ||
| await expectRoutingKey(service, 'test.key', true) | ||
| await expectRoutingKey(service, 'test.key', false, true) | ||
| await expectRoutingKey(service, 'rejudge.key', false, false, true) | ||
| }) | ||
|
|
||
| it('falls back to the legacy submission routing key for every workload', async () => { | ||
| const service = createService( | ||
| createRoutingKeyConfig([ | ||
| ['JUDGE_SUBMISSION_ROUTING_KEY', 'legacy.submission.key'] | ||
| ]) | ||
| ) | ||
|
|
||
| await expectRoutingKey(service, 'legacy.submission.key') | ||
| await expectRoutingKey(service, 'legacy.submission.key', true) | ||
| await expectRoutingKey(service, 'legacy.submission.key', false, true) | ||
| await expectRoutingKey(service, 'legacy.submission.key', false, false, true) | ||
| }) | ||
|
|
||
| it('falls back to the built-in submission key when no routing key is configured', async () => { | ||
| const service = createService({}) | ||
|
|
||
| await expectRoutingKey(service, DEFAULT_SUBMISSION_KEY) | ||
| await expectRoutingKey(service, DEFAULT_SUBMISSION_KEY, true) | ||
| await expectRoutingKey(service, DEFAULT_SUBMISSION_KEY, false, true) | ||
| await expectRoutingKey(service, DEFAULT_SUBMISSION_KEY, false, false, true) | ||
| }) | ||
| }) |
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
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
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
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,55 @@ | ||
| # Iris local judge workers | ||
|
|
||
| Iris is configured as a generic judge request consumer. The queue it consumes | ||
| is selected by `JUDGE_REQUEST_*`; it always publishes results through | ||
| `JUDGE_RESULT_*`. | ||
|
|
||
| ## Split local topology | ||
|
|
||
| After loading the root `.envrc` and starting local RabbitMQ, initialize the | ||
| three request queues and the shared result queue: | ||
|
|
||
| ```sh | ||
| pnpm init:rabbitmq | ||
| ``` | ||
|
|
||
| Start one process for each workload in separate terminals: | ||
|
|
||
| ```sh | ||
| # submission | ||
| go run . | ||
|
|
||
| # test | ||
| JUDGE_REQUEST_CONSUMER_CONNECTION_NAME=iris-test-consumer \ | ||
| JUDGE_REQUEST_QUEUE_NAME="$JUDGE_TEST_QUEUE_NAME" \ | ||
| JUDGE_REQUEST_CONSUMER_TAG=iris-test-consumer-tag \ | ||
| go run . | ||
|
|
||
| # rejudge | ||
| JUDGE_REQUEST_CONSUMER_CONNECTION_NAME=iris-rejudge-consumer \ | ||
| JUDGE_REQUEST_QUEUE_NAME="$JUDGE_REJUDGE_QUEUE_NAME" \ | ||
| JUDGE_REQUEST_CONSUMER_TAG=iris-rejudge-consumer-tag \ | ||
| go run . | ||
| ``` | ||
|
|
||
| Inside the devcontainer, the VS Code launch configurations `Iris Submission`, | ||
| `Iris Test`, and `Iris Rejudge` provide the same three worker processes. Run | ||
| all three configurations to exercise the split topology locally. | ||
|
|
||
| `SUBMISSION_KEY`, `TEST_KEY`, and `REJUDGE_KEY` default to distinct routing | ||
| keys in `.envrc`, so each workload reaches only its corresponding queue. | ||
|
|
||
| ## Legacy single-queue mode | ||
|
|
||
| To reproduce the pre-split local topology, omit the new test and rejudge keys | ||
| or set them equal to `SUBMISSION_KEY` before initializing RabbitMQ, then run | ||
| only the submission worker: | ||
|
|
||
| ```sh | ||
| unset TEST_KEY REJUDGE_KEY | ||
| pnpm init:rabbitmq | ||
| go run . | ||
| ``` | ||
|
|
||
| Nest falls back to `JUDGE_SUBMISSION_ROUTING_KEY`, so submission, test, and | ||
| rejudge requests are all routed to the submission queue. |
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
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
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
REJUDGE_KEYis configured only forclient-api, but rejudge requests are published byadmin-api.REJUDGE_KEYshould also be published toadmin-apior rejudge code invoke logic should be moved into theclient-api.