Skip to content

Parallel item creation for test-data creators - #39

Open
SirCotare wants to merge 3 commits into
mainfrom
parallel-test-data-creation
Open

Parallel item creation for test-data creators#39
SirCotare wants to merge 3 commits into
mainfrom
parallel-test-data-creation

Conversation

@SirCotare

Copy link
Copy Markdown
Member

Why

In finstral-composer-api, DB-backed test setups spend most of their time in sequential given.many(n) loops. Measured against the real Oracle testcontainer there, parallelizing the per-item loop gives:

Case (composer) sequential many(n) many(n).parallel()
light creator, n=10 ~222 ms ~84 ms (~2.6×)
plain article, n=5 ~294 ms ~93 ms (~3.2×)
fully-valid article, n=5 ~673 ms ~260 ms (~2.6×)

What

  • TestDataCreator.parallel() / .sequential(): opt-in/out per call site; the it.aboutbits.testing.testdata.parallel-by-default system property flips the default for a whole suite (intended for a release-candidate experiment run in composer CI).
  • TestDataDependency<T>: one holder for a creator dependency in its three modes (fixed / shared / per item), replacing the hand-rolled field + sameXyz flag check-then-act memoization that races under parallel creation. Shared values resolve exactly once; per-item resolution stays unsynchronized.

Review notes

  • The result list keeps index order under parallelism; DB side effects (sequence-assigned ids) interleave — documented on parallel().
  • ModifiableTestDataCreator's mutator bookkeeping stays correct under parallelism: writes happen-before the Future.get() joins.
  • parallel()/sequential() are @CanIgnoreReturnValue (not @CheckReturnValue) deliberately: a subclass may pin a mode in its constructor without chaining.

Unit tests cover index order, real concurrency, failure propagation, the property flip, and exactly-once shared resolution under 8 threads. Not run: any downstream project suite — composer runs its own CI experiment against a release candidate.

🤖 Generated with Claude Code

Opt-in per call site via parallel(), opt-out via sequential(). The
it.aboutbits.testing.testdata.parallel-by-default system property flips
the default, so a whole suite can run parallel without touching call
sites. The result list keeps index order; worker failures are rethrown
unwrapped.
Replaces the hand-rolled field-plus-sameXyz-flag memoization in
creators: fixed, shared, and per-item modes in one holder. resolve() is
safe under parallel item creation - a shared value is created exactly
once, per-item creation stays unsynchronized.
@SirCotare SirCotare self-assigned this Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants