> 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to