Thread-safety in Scala

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Thread-safety in Scala

jqno
Hi all,

I'm using parboiled for Scala in one of my projects, and I'm really enjoying working with it.

However, I now need to bring my existing parsers into a multi-threaded environment, and I'm trying to figure out the thread-safety issues. They are quite well documented for Java ( https://github.com/sirthias/parboiled/wiki/Thread-Safety ), but there are a few things that I'm uncertain of in the Scala context.

The ParseRunners and the Rule Tree (once constructed) are, as far as I can tell, the same in Java and Scala, so I'm assuming the documentation applies for both contexts. I.e., ParseRunners are not thread-safe but cheap to create, and Rule Trees are not cheap to create, but thread-safe.

The Parser is implemented differently in Scala, though. Looking at the code of the Parser trait, its purpose seems to be to (help) create a Rule Tree. It even does caching and synchronisation. Does that mean that it is thread-safe, unlike the Parser for parboiled for Java (as long as I wrap my rules consistently inside a rule {} block)?
I.e., can I instantiate a Parser in my main thread, and pass it around to the others? Or even make it an object instead of a class, so it becomes a singleton?

Or if it's not thread-safe, could I simply instantiate a Parser to construct a Rule Tree, store that tree somewhere, and discard the Parser? If my earlier assumption is correct, the Rule Tree is thread-safe, so it should be safe to pass that around to my threads, right? Would I need the Parser object for anything else, once I've constructed the Rule Tree? (Assuming I don't put any other logic in there, of course.)

I appreciate any insight you can give in this.


Thanks!
Jan
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thread-safety in Scala

mythica
I'm also interested in knowing which parts of Parboiled are thread-safe and which parts are not.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thread-safety in Scala

mathias
Administrator
In reply to this post by jqno
Jan,

it's not that easy to make assertions about thread-safety of your parser since, in addition to the parboiled constructs, it heavily depends on what the rules of your parser actually do.
Best practice is to not have any mutable state in your parser, but purely rely on the value stack for everything dynamic.
If you stick to this then your parse will indeed be thread-safe once constructed.

> The ParseRunners and the Rule Tree (once constructed) are, as far as I can tell, the same in Java and Scala, so I'm assuming the documentation applies for both contexts. I.e., ParseRunners are not thread-safe but cheap to create, and Rule Trees are not cheap to create, but thread-safe.

Yes, that's right.

> I.e., can I instantiate a Parser in my main thread, and pass it around to the others? Or even make it an object instead of a class, so it becomes a singleton?

Yes, you can (pass it around or make it an object). The key thing is to not have any mutable members.
For instance, look at the spray-json JsonParser:
https://github.com/spray/spray-json/blob/master/src/main/scala/cc/spray/json/JsonParser.scala

It's implemented as an object with the root rule being a lazy val.
Since this parser has no mutable fields it's completely thread-safe.

> Or if it's not thread-safe, could I simply instantiate a Parser to construct a Rule Tree, store that tree somewhere, and discard the Parser? If my earlier assumption is correct, the Rule Tree is thread-safe, so it should be safe to pass that around to my threads, right? Would I need the Parser object for anything else, once I've constructed the Rule Tree? (Assuming I don't put any other logic in there, of course.)

Actually there is no such thing as a "Parser". There is only a rule tree.
As you said before, the `Parser` trait is just a container for rule construction helpers.
It depends on what your rules whether the resulting construct is thread-safe or not.
If you have a rule that sets a non-local `var` somewhere (be it a class deriving from the `Parser` trait or something else) then thread-safety is gone.
If you follow the best-practice of confining yourself to the value-stack for managing state during a parsing run you are good.

HTH and cheers,
Mathias

---
[hidden email]
http://www.parboiled.org

On 14.03.2012, at 11:13, jqno [via parboiled users] wrote:

> Hi all,
>
> I'm using parboiled for Scala in one of my projects, and I'm really enjoying working with it.
>
> However, I now need to bring my existing parsers into a multi-threaded environment, and I'm trying to figure out the thread-safety issues. They are quite well documented for Java ( https://github.com/sirthias/parboiled/wiki/Thread-Safety ), but there are a few things that I'm uncertain of in the Scala context.
>
> The ParseRunners and the Rule Tree (once constructed) are, as far as I can tell, the same in Java and Scala, so I'm assuming the documentation applies for both contexts. I.e., ParseRunners are not thread-safe but cheap to create, and Rule Trees are not cheap to create, but thread-safe.
>
> The Parser is implemented differently in Scala, though. Looking at the code of the Parser trait, its purpose seems to be to (help) create a Rule Tree. It even does caching and synchronisation. Does that mean that it is thread-safe, unlike the Parser for parboiled for Java (as long as I wrap my rules consistently inside a rule {} block)?
> I.e., can I instantiate a Parser in my main thread, and pass it around to the others? Or even make it an object instead of a class, so it becomes a singleton?
>
> Or if it's not thread-safe, could I simply instantiate a Parser to construct a Rule Tree, store that tree somewhere, and discard the Parser? If my earlier assumption is correct, the Rule Tree is thread-safe, so it should be safe to pass that around to my threads, right? Would I need the Parser object for anything else, once I've constructed the Rule Tree? (Assuming I don't put any other logic in there, of course.)
>
> I appreciate any insight you can give in this.
>
>
> Thanks!
> Jan
>
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/Thread-safety-in-Scala-tp3824885p3824885.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.
> NAML

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thread-safety in Scala

jqno
Hi Mathias,

Thank you for you quick and complete answer! It's very helpful.

Yes, my parser is indeed completely immutable, and I don't change any external state from the rules, so I'm safe there.


Thanks!
Jan
Loading...