Skip to content

Conversation

lorban
Copy link
Contributor

@lorban lorban commented Aug 22, 2025

Prototype QueuedThreadPool alternative that stripes execution requests.

@lorban lorban requested a review from gregw August 22, 2025 07:52
@lorban lorban self-assigned this Aug 22, 2025
@ManagedObject("A striped thread pool")
public class StripedQueuedThreadPool extends ContainerLifeCycle implements ThreadFactory, SizedThreadPool, Dumpable, TryExecutor, VirtualThreads.Configurable
{
private static final int STRIPES = 16;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be configurable, perhaps default to the number of cores.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to reduce striping for small pools. If max threads is 100, then slicing 16 ways is too much.

}

@Override
public void setMaxThreads(int threads)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a check that threads should be an exact multiple of STRIPES?

}

@Override
public void setMinThreads(int threads)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a check that threads should be an exact multiple of STRIPES?

Also, threads should be divided by STRIPES.

@Override
public int getMinThreads()
{
return queuedThreadPools[0].getMinThreads();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stripe this.

throw new IllegalArgumentException("max threads (" + maxThreads + ") less than min threads (" + minThreads + ")");
for (int i = 0; i < queuedThreadPools.length; i++)
{
queuedThreadPools[i] = new QueuedThreadPool();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be added as beans.

Comment on lines +131 to +149
@Override
protected void doStart() throws Exception
{
super.doStart();
for (QueuedThreadPool queuedThreadPool : queuedThreadPools)
{
queuedThreadPool.start();
}
}

@Override
protected void doStop() throws Exception
{
super.doStop();
for (QueuedThreadPool queuedThreadPool : queuedThreadPools)
{
queuedThreadPool.stop();
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this if the striped QTP are added as beans, which is also better for dump purposes.

setIdleTimeout(60000);
setStopTimeout(5000);
setReservedThreads(-1);
// setThreadPoolBudget(new ThreadPoolBudget(this));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole ThreadPoolBudget implementation needs to be reworked, we should first confirm we want to go with this solution.

@lorban lorban force-pushed the experiment/jetty-12.1.x/AES-perf-investigations branch from 8a5ccb6 to 4d517ca Compare August 25, 2025 14:55
Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to stripe the whole QTP? Can't we just stripe the queue itself (and make it not maintain a strict ordering). AI thinks it can be done and has written a version... but I'm also thinking that a ConcurrentPool might be usable?

@ManagedObject("A striped thread pool")
public class StripedQueuedThreadPool extends ContainerLifeCycle implements ThreadFactory, SizedThreadPool, Dumpable, TryExecutor, VirtualThreads.Configurable
{
private static final int STRIPES = 16;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to reduce striping for small pools. If max threads is 100, then slicing 16 ways is too much.

@lorban
Copy link
Contributor Author

lorban commented Aug 26, 2025

Do we really need to stripe the whole QTP? Can't we just stripe the queue itself (and make it not maintain a strict ordering). AI thinks it can be done and has written a version... but I'm also thinking that a ConcurrentPool might be usable?

Striping the queue would have my preference, and the fact that we don't need a queue that strictly enforces FIFO (despite the fact that it would break the BlockingQueue contract) makes that somewhat easy, except for our use of take() and poll(timeout, unit) blocking calls which are fairly hard to scale, or at least I couldn't think of an easy solution.

Maybe we could give the conversant disruptor or the JCTools MPMC BlockingQueue a try to see how a known performant blocking queue performs before investing time building our own? I'll give that a try.

@lorban
Copy link
Contributor Author

lorban commented Aug 26, 2025

I'm getting a feeling that QTP isn't the right layer where to handle the extra needed concurrency. ThreadPoolBudget would need quite some work and handling reserved threads opens a host of questions.

Despite the shortcomings, a striped QTP is still our best option IMHO.

Signed-off-by: Ludovic Orban <[email protected]>
@lorban lorban force-pushed the experiment/jetty-12.1.x/AES-perf-investigations branch from 4d517ca to 6800c1a Compare August 26, 2025 16:19
@lorban lorban force-pushed the experiment/jetty-12.1.x/AES-perf-investigations branch from 6800c1a to 10cfdcd Compare August 26, 2025 16:20
@gregw
Copy link
Contributor

gregw commented Aug 27, 2025

I tried several variations of the jctools queue in the QTP JMH benchmark and all were slower (30k - 100k ops/s) than BAQ (300k ops/s).

Signed-off-by: Ludovic Orban <[email protected]>
@lorban lorban force-pushed the experiment/jetty-12.1.x/AES-perf-investigations branch from ea58469 to e3c7b04 Compare August 27, 2025 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants