Conversation
ramafasa
requested changes
Mar 31, 2026
okapi-mysql/src/main/resources/com/softwaremill/okapi/db/mysql/003__add_claim_index.sql
Outdated
Show resolved
Hide resolved
okapi-postgres/src/main/resources/com/softwaremill/okapi/db/004__add_claim_index.sql
Outdated
Show resolved
Hide resolved
Shared ConcurrentClaimTests extension function with two tests: - Deterministic: verifies disjoint claim sets when one processor holds locks while another claims concurrently - Realistic: 5 virtual threads process 50 entries with no delivery amplification Also adds (status, created_at) index migration for Postgres to improve claimPending query performance.
Adds MysqlConcurrentClaimTest reusing the shared test suite. Fixes MySQL claimPending to use FORCE INDEX on (status, created_at) so that FOR UPDATE SKIP LOCKED only row-locks the rows returned by LIMIT. Without the index hint, InnoDB locks all rows matching the WHERE clause during a full table scan, preventing concurrent processors from claiming disjoint sets. Changes: - Add (status, created_at) index to OutboxTable and Liquibase migration - Add FORCE INDEX hint to MysqlOutboxStore.claimPending()
Migrated to okapi-integration-tests module: - OutboxEndToEndTest (Postgres+HTTP) → HttpEndToEndTest - MysqlOutboxEndToEndTest (MySQL+HTTP) → MysqlHttpEndToEndTest Removed Testcontainers/WireMock/Liquibase test deps from okapi-spring-boot and okapi-mysql modules.
…e(SKIP_LOCKED) Replace raw SQL string + manual ResultSet mapping with type-safe Exposed DSL query and ForUpdateOption.PostgreSQL.SKIP_LOCKED. Eliminates mapFromResultSet() in favor of ResultRow.toOutboxEntry(). MySQL keeps raw SQL because InnoDB requires FORCE INDEX hint for correct SKIP LOCKED behavior, which Exposed DSL cannot express.
- Add missing `eq` import in PostgresOutboxStore (lost during merge) - Update removeDeliveredBefore call to match new signature (time, limit)
Changeset IDs were not updated when migration files were renumbered during rebase (003→004 for Postgres, 002→003 for MySQL).
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
okapi-integration-testsmodule (non-published) with comprehensive test suitePostgresOutboxStore.claimPending()from raw SQL to type-safe Exposed DSL withForUpdateOption.SKIP_LOCKEDFORCE INDEXhint to fix InnoDB locking behavior withSKIP LOCKEDWhat's included
Test support infrastructure
PostgresTestSupport,MysqlTestSupport,KafkaTestSupport— Testcontainers wrappersRecordingMessageDeliverer— thread-safe test spy withassertNoAmplification()Store contract tests (16 tests)
Shared via FunSpec extension function, run on both Postgres and MySQL:
Concurrency tests (4 tests)
Kafka transport integration (5 tests)
E2E tests (11 tests)
HttpEndToEndTest(Postgres + HTTP): 6 tests including transaction rollback and retry exhaustion (new scenarios)MysqlHttpEndToEndTest(MySQL + HTTP): 4 testsKafkaEndToEndTest(Postgres + Kafka): full pipelineCleanup
OutboxEndToEndTestandMysqlOutboxEndToEndTest(BehaviorSpec, fragile isolation)okapi-spring-bootandokapi-mysqlKey discovery: MySQL FORCE INDEX
Concurrency tests revealed that without
FORCE INDEX(idx_outbox_status_created_at), InnoDB locks ALL examined rows duringSELECT ... FOR UPDATE SKIP LOCKED(full table scan), not just the LIMIT'd ones. Added composite index migration + FORCE INDEX hint.Test plan
./gradlew test -x :okapi-integration-tests:test— unit tests pass./gradlew :okapi-integration-tests:test— all 36 integration tests pass (requires Docker)./gradlew ktlintCheck— formatting clean