Closed rocketraman closed 1 year ago
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?
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())
}
}
}
The problem appears to be with concurrent initalization.
If memory serves me correctly, JRuby is not thread-safe when loading gems, but once everything is loaded, AsciidoctorJ is thread-safe.
The problem appears to be with concurrent initalization.
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.
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. I think I have a clear idea what is going wrong.
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: