-
1. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
mmusgrov May 16, 2016 10:12 AM (in response to nwhitehead)If multiple threads are associated with a transaction and one of them tries to commit it then the other threads may still be still be actively making updates to transactional resources and be unaware that the transaction is about to end.
Could you not arrange things such that the fibre that wants to end the transaction tells the other fibres to finish their work and only proceeds with transaction termination when it is knows they have all finished. From your question it sounds like you can determine when they have all finished their updates.
-
2. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
tomjenkinson May 16, 2016 10:19 AM (in response to mmusgrov)Unless I missed something I think that "the fiber is never executed by more than one thread at a time". Assuming ordering is also maintained I expect the general issue you are suggesting could happen (two threads active on one transaction simultaneously, commit mid update) is guaranteed not to happen with Quasar?
-
3. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
tomjenkinson May 16, 2016 10:20 AM (in response to nwhitehead)"before the fiber is suspended (and resume it when the fiber resumes) but Quasar does not support this" - does this mean there is no API in Quasar to hook into or that you had issues using some hooks that they may provide?
-
4. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
nwhitehead May 16, 2016 11:10 AM (in response to tomjenkinson)Mchael & Tom;
Thanks for your replies.
The execution of a fiber is carried out by mutliple threads, but only one at any given time.
When the fiber is first scheduled, it is allocated a forkjoin thread which executes until the fiber is suspended (normally because it gets blocked).
At some point the fiber will be resumed and continue executing, but most likely by a different forkjoin thread (I just mean statistically speaking).
So no two threads would ever be executing in the fiber (or a fiber initiated transaction) at one time.
It looks like this (my own poor rendering)
The Quasar API does supply a callback after the fiber has been suspended, but at a point when the thread's threadlocals have been removed. At that point a call to TransactionManager.getTransaction() returns null.
I have been discussing this with Quasar's developers. They are concerned about exposing the innards of the Fiber during suspension/resumption (admittedly, it is pretty hairy), but it seems they may support the idea of a callback that only exposes the executing thread (or executes in the same thread, I suppose) before the thread locals are cleared. In this case, I would be able to suspend the transaction. This would require an associated resumption callback that would occur after the thread locals have been restored and before the fiber started execution again. This is where I would call TransactionManager.resume().
In general, I am very interested in making the TM work with Quasar. It's a very powerful processing model and the potential benfits of lightweight threads is attracting a lot of interest. It does introduce challenges when trying to integrate Quasar with thread specific functionality in other libraries, and if you take a quick look at their concurrency primitives, they've reimplemented many of the indispensible classes like ReentrantLock and CountDownLatch to make them Fiber (or Thread) specific.
....but my immediate issue is..... if I know for a fact that multiple threads have partiicipated in a transaction, but sequentially, cooperatively and never concurrently, can I ignore the Arjuna warnings, or am I fundamentally breaking something ?
Thanks !
//Nicholas
-
5. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
mmusgrov May 16, 2016 11:07 AM (in response to nwhitehead)Another option, if you can get at each thread that has ran the fibre or continuation, could be to remember all the threads that have been involved and add them as thread locals. Then when it's time to commit/end the transaction you could manually update our view of which threads have been involved by calling narayana/ThreadActionData.java at master · jbosstm/narayana · GitHub
-
6. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
nwhitehead May 16, 2016 11:12 AM (in response to mmusgrov)Michael;
Sounds promising. I will look into it.
//Nicholas
-
7. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
mmusgrov May 16, 2016 11:20 AM (in response to nwhitehead)Nicholas Whitehead wrote:
The Quasar API does supply a callback after the fiber has been suspended, but at a point when the thread's threadlocals have been removed. At that point a call to TransactionManager.getTransaction() returns null.
I have been discussing this with Quasar's developers. They are concerned about exposing the innards of the Fiber during suspension/resumption (admittedly, it is pretty hairy), but it seems they may support the idea of a callback that only exposes the executing thread (or executes in the same thread, I suppose) before the thread locals are cleared. In this case, I would be able to suspend the transaction. This would require an associated resumption callback that would occur after the thread locals have been restored and before the fiber started execution again. This is where I would call TransactionManager.resume().
You could use the existing Quasar on suspend callback to call calling narayana/ThreadActionData.java at master · jbosstm/narayana · GitHub
But you would still need to resume the transaction either by calling resume() or by calling narayana/ThreadActionData.java at master · jbosstm/narayana · GitHub
-
8. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
marklittle May 16, 2016 3:04 PM (in response to nwhitehead)Another option would be to define your own CheckedAction implementation which doesn't issue the warning message if you are sure that is safe.
-
9. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
tomjenkinson May 16, 2016 3:08 PM (in response to nwhitehead)Nicholas Whitehead wrote:
....but my immediate issue is..... if I know for a fact that multiple threads have partiicipated in a transaction, but sequentially, cooperatively and never concurrently, can I ignore the Arjuna warnings, or am I fundamentally breaking something ?
If you are using JTA then this won't work without some extra code as a transaction won't automatically be removed from the thread it was associated with originally. You will need to suspend the committed transaction from the thread. This is a safety feature to ensure that a thread which completes the transaction on behalf of the original thread does not cause unexpected consequences in the original thread.
E.g. you can't have code that just looks like:
tm.begin
// do work
tm.begin
// do work
With the commits happening in different threads. You would need to correctly disassociate the thread before the second begin.
-
10. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
nwhitehead May 16, 2016 3:27 PM (in response to tomjenkinson)Excellent point. I need to make sure that the forkjoin threads are not associated to a transaction that does not belong to a fiber that it is about to continue.
Thanks.
//Nicholas
-
11. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
marklittle May 16, 2016 3:28 PM (in response to tomjenkinson)True, but if Nicholas is sure that these fibres are all essentially aspects of the same "virtual" thread then it's logically the same as a single thread being associated with the transaction. The CheckedAction code is based on some fairly fundamental work dating back to OTS and discussed http://www.cs.ncl.ac.uk/publications/trs/papers/628.pdf
But since one approach was never going to be suitable for all threading situations (even in OTS/JTS) that's why we make it configurable. I see two possible solutions using this: one, which I mentioned earlier, that simply ignores the thread associations and doesn't issue the warning (that could be risky if truly independent threads and these "fibre threads" are being used in the same transaction), and one that does the same thing which somehow knows how to distinguish the Java language threads being used by the "same" fibre and ignore them, but issue a warning if multiple independent threads are present during commit. But I don't know Quasar to be sure this is even possible.
-
12. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
marklittle May 16, 2016 3:31 PM (in response to mmusgrov)That's very risky. Really no one should be playing with ThreadActionData directly. Go through CheckedAction.
-
13. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
nwhitehead May 16, 2016 4:09 PM (in response to mmusgrov)Michael;
I think I see where I could [carefully] go with ThreadActionData
In this scenario, I would have a reference to the Transaction (BasicAction) and I want to execute a TransactionManager.suspend(), but I can't since the underlying threadlocal will not be accessible, and there's no such javax.transaction API call as myTransaction.suspend().
But ThreadActionData fills in the missing piece where I can call ThreadActionData.pushAction (myTransaction, false) which I think accomplishes the same thing.
By the same logic, on fiber continuation, I could call ThreadActionData.popAction().
This is a large simplification, and I take Mark's caution seriously, but to make this work, I need to be able to suspend a transaction (disassociate the transaction from the fork-join thread) and then resume it again.
Assuming this works as expected, I would not expect to see any warnings issued.
In case anyone is interested, this is the enhancement I requested from Quasar. I am trying to keep the two threads synchronized (no pun intended).
-
14. Re: Using TransactionManager with Quasar Fibers (Lightweight Threads)
mmusgrov May 17, 2016 4:05 AM (in response to marklittle)I agree it is risky but CheckedAction will not help here since we print the warning before calling CheckedAction and then again in the default implementation of CheckedAction. We can fix that but it would mean Nicholas would have to wait for the next narayana release.
Nicholas are you okay with waiting for another release, the fix that marklittle refers to would be to override the default implementation (narayana/CheckedAction.java at master · jbosstm/narayana · GitHub) and suppress the warning there if you know it's safe?