vlsi opened a new pull request, #6727: URL: https://github.com/apache/jmeter/pull/6727
## Why Open Model Thread Group creates a new `JMeterThread` and a fresh test-plan clone for every arrival, with no upper bound. When the server responds slower than arrivals are scheduled, threads pile up until JMeter runs out of memory — several users report thousands to tens of thousands of threads for a load a handful of threads could serve (#5966). A second, deliberate use case is modeling a system with a hard concurrency limit, such as a fixed-size connection pool. ## What Add a positional `concurrency(N)` schedule step, alongside `rate(...)`, that caps the number of threads running at the same time. Like `rate`, it is positional and may vary over time: ``` concurrency(100) rate(10/sec) random_arrivals(10 min) concurrency(200) random_arrivals(10 min) ``` caps the load at 100 threads for the first ten minutes and 200 for the next. - `ConcurrencyLimit` reads the cap by the time elapsed since the schedule start, not by the arrivals-generator position, so the cap still rises while the producer is blocked waiting for a free thread. - `ConcurrencyGate` reserves a slot **before** cloning the test plan, so a capped arrival waits for a free thread instead of allocating a clone. This bounds memory by the limit rather than by the arrival rate. - When the limit is saturated, OMTG no longer follows the open model: the achieved rate drops below the target rate, which the reports show as fewer samples. An arrival that still has no free thread when the schedule ends is dropped rather than stretching the test past its nominal end. A summary is logged at the end. - `openmodel.max_concurrency` is an installation-wide safety net for schedules that set no `concurrency(...)` of their own. It defaults to unlimited to preserve existing behavior. The design leaves room for the `thread_lifetime` / thread-reuse ideas discussed in the issue: `concurrency` counts active threads, so a future clone pool can sit under the gate without changing the meaning of existing schedules. ## How to verify New tests in `src/core/.../threads/openmodel/`: - `ConcurrencyLimitTest` — the cap changes on the arrival boundary regardless of generator position. - `ConcurrencyGateTest` — blocking, deadline drop, release-unblocks-waiter, and interruptibility of a blocked producer. - `ConcurrencyParseErrorTest` — `concurrency(0)`, non-integer, and malformed input are rejected. - `ConcurrencyLimitBehaviorTest` — end-to-end: at most N threads run at once and delayed arrivals are counted. - `ThreadScheduleTest` — parser cases for `concurrency(...)`. ``` ./gradlew :src:core:test --tests "org.apache.jmeter.threads.openmodel.*" ``` ## Open question `openmodel.max_concurrency` defaults to unlimited, so an unconfigured plan can still hit OOM — the graceful-by-default behavior asked for in the issue would need a non-zero default (e.g. 10000), which changes behavior for existing plans. Left as unlimited here; happy to switch the default if that is preferred. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
