-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrent use of AsciidoctorJ Asciidoctor
interface results in ConcurrentModificationException
#1158
Comments
This should probably be moved to the asciidoctorj repository, I apologize for putting it in the wrong place. |
Do you get this issue as well if you first convert a document once, and after that start your concurrent threads? |
Nope, I am unable to replicate the issue after doing a single conversion, and there are no warning messages printed either. The problem appears to be with concurrent initalization. An effective workaround (in Kotlin) appears to be to run an extremely simple conversion at initialization time: private val asciidoctor: Asciidoctor by lazy {
Asciidoctor.Factory.create().apply {
// do a one-time conversion to initialize it, as initialization doesn't appear to be thread-safe
// see https://github.com/asciidoctor/asciidoctorj/issues/1158
ByteArrayOutputStream().use {
convert("= Hello", Options.builder().backend("pdf").safe(SafeMode.UNSAFE).toStream(it).build())
}
}
} |
If memory serves me correctly, JRuby is not thread-safe when loading gems, but once everything is loaded, AsciidoctorJ is thread-safe. |
In that case, it sounds like the gems should be loaded eagerly when the factory is created rather than waiting until the first conversion? Or alternatively, load them lazily but wrapped such that only one thread can load the gems (as in my workaround snippet above). |
I agree that if the claim is correct, action may be warranted. But let's prove it first before making any decisions based on it. As I said, it was only based on my memory of past experiences. Let's sure up the facts first. |
Fair enough. Let me know if I can help with testing or whatever. I'm not super-familiar with Ruby/JRuby. |
I can provide a fix for that. |
…er class when converting to stream.
…er class when converting to stream.
…er class when converting to stream.
…er class when converting to stream.
…er class when converting to stream.
(v2.5.x) Fixes #1158. Avoid concurrent initialization of Ruby wrapper class wh…
I'm testing using the
Asciidoctor
interface in concurrent code. I am able to reproduce this error reasonably consistently (though not every time) simply by starting 100 concurrent threads that all convert asciidoc to PDF. My conversion code looks like this:The exception is:
I also see the following warnings:
The text was updated successfully, but these errors were encountered: