sferik / multi_xml

A generic swappable back-end for XML parsing
MIT License
157 stars 40 forks source link

Switching parser backend is not threadsafe #50

Open tcollier opened 8 years ago

tcollier commented 8 years ago

I've written a gem that is using MultiXml to parse a response from a 3rd party API. Due to some peculiarities of the response XML, this gem is forced to use the Ox backend. The client using this gem also has other dependencies which use MultiXml, though I'm not sure which back-end they prefer. Given that different backends result in different parsing behavior (see https://github.com/sferik/multi_xml/issues/30), I foresee disaster if I force all dependencies to use Ox (or if one of the dependencies forces my gem to use a backend other than Ox).

The naive solution would be to wrap calls to MultiXml.parse in my gem like so

def parse_xml(xml)
  orig_parser = MultiXml.parser
  MultiXml.parser = :ox
  parsed = MultiXml.parse(xml)
  MultiXml.parser = orig_parser
  parsed
end

Unfortunately, this won't work for me, because the client application is running in a multithreaded environment (Rails with Puma) and this approach is not thread-safe.

What I need is a thread safe way to tell my gem to use Ox when parsing without affecting other gems' usage of MultiXml.

One solution would be to add a :parser option to MultiXml.parse, which would override the globally configured parser for that particular case. Usage could look like

MutliXml.parse(xml, parser: :ox)

That is just a suggested solution, I know there are other ways to solve this problem too.