You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stormcrawler.apache.org by Richard Zowalla <rz...@apache.org> on 2026/06/02 10:55:25 UTC
[DISCUSS] Java 25 baseline when moving to Storm 3
Hi all,
Storm 3.0 (currently in development upstream) raises its Java baseline
to 21 [1]. Once we move StormCrawler onto Storm 3, we will have to lift
our own baseline (currently Java 17) anyway, so I'd like to discuss
where we should land.
My proposal: go directly to Java 25 (the current LTS) instead of
stopping at Java 21.
Why not just 21?
The main technical argument is virtual threads. Our fetch path is a
textbook use case for them: FetcherBolt today maintains a fixed pool of
platform threads (fetcher.threads.number), each spending most of its
life blocked on DNS / TLS / slow servers / timeouts. With virtual
threads we could move to a thread-per-fetch model where concurrency is
bounded by politeness rules and connection pools rather than by thread
count. For broad multi-host crawls this lifts the per-worker
concurrency ceiling from a few hundred to many thousands of in-flight
fetches, and removes fetcher.threads.number as the tuning knob that
users most often get wrong. (Single-host crawls see no difference -
politeness remains the cap there.)
The catch with Java 21: virtual threads pin their carrier thread inside
synchronized blocks. Adopting them on a 21 baseline would mean
refactoring synchronized usage across the fetch path (FetchItemQueues,
ProtocolFactory, several external modules) to ReentrantLock. JEP 491
(JDK 24) removed this limitation, so on a Java 25 baseline most of that
refactoring simply isn't needed - we could adopt virtual threads in
FetcherBolt with a much smaller and safer change.
Beyond that, 25 is an LTS like 21, with a longer support window.
Practical considerations:
- Users moving to Storm 3 have to upgrade their JVM to 21+ anyway; the
additional step to 25 should be small for most, but it would exclude
anyone whose organisation pins them to 21. Input welcome on whether
this is a real concern for our user base.
- Storm 3 itself is built against 21; running it on a 25 JRE should be
fine, but we'd want to validate this in our CI matrix.
- Dependency ecosystem on 25 needs a quick audit (I don't expect
issues).
What this would enable as follow-up work (separate threads/issues):
- FetcherBolt: virtual-thread-per-fetch, deprecating
fetcher.threads.number in favour of a (much higher) max-in-flight cap
- Dropping the per-fetcher-thread timeout ExecutorServices
- Decoupling HTTP connection pool sizing from thread count
- Pluggable async-capable DNS resolution (JEP 418 SPI)
None of this would affect the current 3.x line - it would target the
release in which we adopt Storm 3.
Looking forward to your thoughts.
Gruß
Richard
Re: [DISCUSS] Java 25 baseline when moving to Storm 3
Posted by Davide Polato <dp...@apache.org>.
+1 on Java 25. The JEP 491 argument is convincing on its own — skipping the
ReentrantLock refactoring across FetchItemQueues is already worth it.
The OkHttp pool concern is real but I think orthogonal. We already document
that it does not scale past ~1000 total connections and point to
protocol.instances.num as the way to spread load. Virtual threads would
stress that limit more, but that is a problem to solve separately
regardless of which Java baseline we pick.
Same goes for the timeout executors. They are there because platform
threads can get stuck in native I/O and interrupt is not always reliable —
with virtual threads that improves, and we already have OkHttp call
timeouts and socket timeouts underneath. I think the pattern could be
simplified, though I would keep some bolt-level safety net either way.
One small thing: beingFetched in FetcherBolt is a String[] sized to
threadCount, indexed by threadNum, only used for debug logging. Minor, but
a good example of the kind of thing that would need updating in the bolt
when the model changes.
Il giorno mer 3 giu 2026 alle ore 09:18 Julien Nioche <
julien@digitalpebble.com> ha scritto:
> Thanks Richard for the suggestion and thorough explanation.
> Two things come to my mind:
>
> - Need to check that it works with OKHttp's connection cache: IIRC
> having too many connections made things slower because of the
> implementation of their cache. If virtual threads means more
> parallelism,
> wouldn't that be a bottleneck?
> - *"Dropping the per-fetcher-thread timeout ExecutorServices" - *this
> was added recently to avoid threads getting blocked forever by the
> protocol, which we did see in practice. Wouldn't we need a similar
> mechanism with virtual threads?
>
> What do you think?
>
> Julien
>
> On Tue, 2 Jun 2026 at 11:55, Richard Zowalla <rz...@apache.org> wrote:
>
> > Hi all,
> >
> > Storm 3.0 (currently in development upstream) raises its Java baseline
> > to 21 [1]. Once we move StormCrawler onto Storm 3, we will have to lift
> > our own baseline (currently Java 17) anyway, so I'd like to discuss
> > where we should land.
> >
> > My proposal: go directly to Java 25 (the current LTS) instead of
> > stopping at Java 21.
> >
> > Why not just 21?
> >
> > The main technical argument is virtual threads. Our fetch path is a
> > textbook use case for them: FetcherBolt today maintains a fixed pool of
> > platform threads (fetcher.threads.number), each spending most of its
> > life blocked on DNS / TLS / slow servers / timeouts. With virtual
> > threads we could move to a thread-per-fetch model where concurrency is
> > bounded by politeness rules and connection pools rather than by thread
> > count. For broad multi-host crawls this lifts the per-worker
> > concurrency ceiling from a few hundred to many thousands of in-flight
> > fetches, and removes fetcher.threads.number as the tuning knob that
> > users most often get wrong. (Single-host crawls see no difference -
> > politeness remains the cap there.)
> >
> > The catch with Java 21: virtual threads pin their carrier thread inside
> > synchronized blocks. Adopting them on a 21 baseline would mean
> > refactoring synchronized usage across the fetch path (FetchItemQueues,
> > ProtocolFactory, several external modules) to ReentrantLock. JEP 491
> > (JDK 24) removed this limitation, so on a Java 25 baseline most of that
> > refactoring simply isn't needed - we could adopt virtual threads in
> > FetcherBolt with a much smaller and safer change.
> >
> > Beyond that, 25 is an LTS like 21, with a longer support window.
> >
> > Practical considerations:
> >
> > - Users moving to Storm 3 have to upgrade their JVM to 21+ anyway;
> the
> > additional step to 25 should be small for most, but it would exclude
> > anyone whose organisation pins them to 21. Input welcome on whether
> > this is a real concern for our user base.
> > - Storm 3 itself is built against 21; running it on a 25 JRE should be
> > fine, but we'd want to validate this in our CI matrix.
> > - Dependency ecosystem on 25 needs a quick audit (I don't expect
> > issues).
> >
> > What this would enable as follow-up work (separate threads/issues):
> >
> > - FetcherBolt: virtual-thread-per-fetch, deprecating
> > fetcher.threads.number in favour of a (much higher) max-in-flight cap
> > - Dropping the per-fetcher-thread timeout ExecutorServices
> > - Decoupling HTTP connection pool sizing from thread count
> > - Pluggable async-capable DNS resolution (JEP 418 SPI)
> >
> > None of this would affect the current 3.x line - it would target the
> > release in which we adopt Storm 3.
> >
> > Looking forward to your thoughts.
> >
> > Gruß
> > Richard
> >
> >
>
Re: [DISCUSS] Java 25 baseline when moving to Storm 3
Posted by Julien Nioche <ju...@digitalpebble.com>.
Thanks Richard for the suggestion and thorough explanation.
Two things come to my mind:
- Need to check that it works with OKHttp's connection cache: IIRC
having too many connections made things slower because of the
implementation of their cache. If virtual threads means more parallelism,
wouldn't that be a bottleneck?
- *"Dropping the per-fetcher-thread timeout ExecutorServices" - *this
was added recently to avoid threads getting blocked forever by the
protocol, which we did see in practice. Wouldn't we need a similar
mechanism with virtual threads?
What do you think?
Julien
On Tue, 2 Jun 2026 at 11:55, Richard Zowalla <rz...@apache.org> wrote:
> Hi all,
>
> Storm 3.0 (currently in development upstream) raises its Java baseline
> to 21 [1]. Once we move StormCrawler onto Storm 3, we will have to lift
> our own baseline (currently Java 17) anyway, so I'd like to discuss
> where we should land.
>
> My proposal: go directly to Java 25 (the current LTS) instead of
> stopping at Java 21.
>
> Why not just 21?
>
> The main technical argument is virtual threads. Our fetch path is a
> textbook use case for them: FetcherBolt today maintains a fixed pool of
> platform threads (fetcher.threads.number), each spending most of its
> life blocked on DNS / TLS / slow servers / timeouts. With virtual
> threads we could move to a thread-per-fetch model where concurrency is
> bounded by politeness rules and connection pools rather than by thread
> count. For broad multi-host crawls this lifts the per-worker
> concurrency ceiling from a few hundred to many thousands of in-flight
> fetches, and removes fetcher.threads.number as the tuning knob that
> users most often get wrong. (Single-host crawls see no difference -
> politeness remains the cap there.)
>
> The catch with Java 21: virtual threads pin their carrier thread inside
> synchronized blocks. Adopting them on a 21 baseline would mean
> refactoring synchronized usage across the fetch path (FetchItemQueues,
> ProtocolFactory, several external modules) to ReentrantLock. JEP 491
> (JDK 24) removed this limitation, so on a Java 25 baseline most of that
> refactoring simply isn't needed - we could adopt virtual threads in
> FetcherBolt with a much smaller and safer change.
>
> Beyond that, 25 is an LTS like 21, with a longer support window.
>
> Practical considerations:
>
> - Users moving to Storm 3 have to upgrade their JVM to 21+ anyway; the
> additional step to 25 should be small for most, but it would exclude
> anyone whose organisation pins them to 21. Input welcome on whether
> this is a real concern for our user base.
> - Storm 3 itself is built against 21; running it on a 25 JRE should be
> fine, but we'd want to validate this in our CI matrix.
> - Dependency ecosystem on 25 needs a quick audit (I don't expect
> issues).
>
> What this would enable as follow-up work (separate threads/issues):
>
> - FetcherBolt: virtual-thread-per-fetch, deprecating
> fetcher.threads.number in favour of a (much higher) max-in-flight cap
> - Dropping the per-fetcher-thread timeout ExecutorServices
> - Decoupling HTTP connection pool sizing from thread count
> - Pluggable async-capable DNS resolution (JEP 418 SPI)
>
> None of this would affect the current 3.x line - it would target the
> release in which we adopt Storm 3.
>
> Looking forward to your thoughts.
>
> Gruß
> Richard
>
>