View on GitHub

LibXML-raku

Raku bindings to the libxml2 native library

[Raku LibXML Project] / [LibXML Module] / Threads

Notes on Raku LibXML Threading and Concurrency

Concurrency and Parsing

Parsing, including, validation and the Reader pull-parser can be run concurrently.

my @docs = @files.hyper.map: -> $file { LibXML::Parse: :$file }

However, the Raku LibXML bindings will protect these with a commonly library lock, defeating concurrency, if the libxml library has not been compiled with threading enabled. Threading can be checked using the LibXML::Config threads method.

unless LibXML::Config.threads { ... }

Concurrency and Input Callbacks

Input callbacks may be set globally, without affecting concurrency.

my LibXML::InputCallback $input-callbacks .= new: @callbacks;
LibXML::Config.input-callbacks = $input-callbacks;

They may also be set at the parser level. However, this is not thread safe. The LibXML library requires that you also enable the parser-locking flag, which limits concurrent parsing.

LibXML::Config.parser-locking = True;
my LibXML::InputCallback $input-callbacks .= new: :callbacks{
        :&match, :&read, :&open, :&close
}
LibXML::Config.parser-locking = True;
my LibXML:D $parser .= new: :$input-callbacks;

DOM Concurrency

Parallel Construction

Document fragments and element sub-trees, may be constructed in parallel provided that they remain independent of each other. They then need to be assembled sequentially to create the final document:

my LibXML::Document $doc .= parse: :string("<doc/>");
my @frags = @files.hyper.map: -> $file { LibXML::DocumentFragment.parse: :balanced, :$file}
$doc.addChild($_) for @frags;

DOM Updates and Concurrency

It is not thread-safe to read and modify DOM nodes concurrently.

However, each node has a protect method that can be used to limit concurrency.

$elem.protect: { $elem.appendChild: LibXML::Element.new('foo') }

Be careful with nesting protect calls, to avoid potential deadlocks.