> I know that if you have a dosync call in some function executed by a > thread, and then that function calls other functions (which might have > their own dosyncs, which get bundled together with the original > transaction), then everything is fine. It seems common that all of > that work would be done sequentially, in a single thread. > > But what if that thread that started the dosync did a pmap call, say, > and the function called on each of the elements of the collection > accessed Refs, and perhaps computed new values for some of them, and > those were not the same Refs that the original thread was accessing. > Do all of those get bundled together with the original transaction, > too?
Andy, No -- absent some var/binding gymnastics (which are currently possible but not very straightforward to do at the moment) -- a transaction is associated with a single thread, period. If your pmap call happens to initialize other transactions on other threads, those transactions will be completed completely independently of any transaction that may be in flight that initiated the pmap call itself (or send or send-off or future, or whatever other asynchronous mechanism at play). That said, I would urge caution in circumstances like what you've described. While you say that the refs being accessed in the other threads' transactions aren't the same as the refs being accessed in the parent transaction, you'll be in for some unpleasantness if that ceases to be true at some point. e.g. the "child" transactions will see the original value of any refs changed so far in the "parent" transaction, the parent will not see any changes made to those refs by the child transactions, and if a parent transaction is waiting on a value being returned by a child transaction, and they both ensure or ref-set or alter the same ref, then you're likely in for a deadlock. > If so, did it require anything special in the implementation to make > that work? Migrating transactions across thread boundaries *is* possible by judiciously copying thread-local bindings from one thread to another. There is a low-level API on clojure.lang.Var, etc. for doing this, but it's by no means pretty -- which I think is probably a good sign that doing so is fundamentally a bad idea at the moment. If and until a better approach is available, I'd say the best approach would be to ensure that only *values* are going into your pmap calls (as opposed to refs), as that's the only way to ensure that you're not going to get tripped up by the thread-local nature of transactions. I've done just the opposite in the recent past, and the result was a lot of confusion and frustration, which ended up being part of learning a lesson the hard way. :-/ Cheers, - Chas --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---