This ended up a lot longer than I originally planned, but here goes:
So the last one is something I added in after watching locking behavior in Wonder and profiling. With defaultAutomaticLockUnlock turned on, basically what Wonder will do is ensure that before every call you make on an EC, the EC is locked, and after it is done (assuming it was he one that locked it), unlock. This TECHNICALLY works. The problem with this is two-fold:
1) Semantically speaking, it's common that your "transaction" (read: lock) really should survive multiple calls -- it's rare you do ONE EOF operation in your transaction and just stop. But automatic lock/unlock does not model this behavior well -- you will get a bunch of intermittent locks around each step. Technically each individual step is safe, but the larger transaction itself may not necessarily be. You will generally not get deadlocks like you might without locking at all, but it IS possible under load to get some wonkiness.
2) Closely related to that, it's very common to do a bunch of things in close succession. Think of rendering a page. You bind to all sorts of EO's, and every operation that touches EO's potentially needs a lock. If you were to turn on lock debugging, you'd see that Wonder is going to go locking and unlocking your EC. It's really just spending a lot of time doing things that it doesn't need to, and stack on top of that #1, that you really generally don't WANT sparse locking, and you get a recipe for obnoxious lock behavior.
So what you really want is something more like the semantics of defaultEditingContext. defaultEditingContext is pretty nice about locking at the top, and unlocking at the bottom, of your request. It doesn't churn the lock and gives you a request-wide transaction(lock). So what I wanted to do was introduce a modification to Wonder's locking behavior to make it act like that -- I want it to coalesce all these churning locks into just one.
It just so happens that Wonder automatically unlocks all your EC's for you at the end of a request (useEditingContextUnlocker=true) -- this saves your butt if you ever forget, and this behavior is actually depended on (so I understand) in ERD2W, has been in use for quite a while, and is very reliable. So what defaultCoalesceAutoLocks does is that the FIRST autolock (not your own manual locks ... only autolocks .. we don't want to mess with your own locking) that occurs for an EC on a thread, we actually leave it hanging open. Autolocking is smart enough that if there is already a lock (including your own manually, btw), it leaves well enough along. So if you lock manually, autolocking is a noop. So leaving a lock open makes all the other autolocks just not occur. What this tends to do is make peer editing contexts behave very much like defaultEditingContext, but only when you actually use it for the first time in a request (so if you don't happen to touch it, you don't take the hit, but if you do, it will lock and leave). Wonder then (because you have useEditingContextUnlocker=true) will automatically clean up the locks.
And this is why I caution the border case of EO's crossing thread boundaries. A lot of Wonder magic with EC's happens with ThreadLocals. When you cross thread boundaries with an EO, you're in a bit of a gray area in terms of editing context locking and lock management.
Incidentally, coalesced autolocks only occur in a Thread that is in a R-R loop. If you create a separate Thread, it will revert back to non-coalescing behavior. This is because locks can only be automatically cleaned up by the WhateverItIsCalledRequestGotHandled event at the end of the R-R loop. Outside of a request, there's no event we can attach to to know that you're done. Hence, coalescing = gone. So in my own threads, I tend to put a ec.lock() try { .. } finally { ec.unlock(); } in the run(). This is really the only case that you need to think about locking, though. But creating background threads tends to be rare (in my experience), so it's not too bad. And honestly, even if you don't manually lock them, autolocking will still apply, it will just churn a lot more than it needs to.
ms
On May 31, 2007, at 10:12 AM, Steven Mark McCraw wrote: Oh yes, and one more thing: You need to set up your system properties in the following way:
er.extensions.ERXApplication.useEditingContextUnlocker=true er.extensions.ERXEC.defaultAutomaticLockUnlock=true er.extensions.ERXEC.useSharedEditingContext=false er.extensions.ERXEC.defaultCoalesceAutoLocks=true
The last one is optional, I think, but I don't have a good enough grasp of what that last one is about to be able to explain it here. I saw it recommended in a posting once, and using it has done me no harm.
I think that's it. List, is there anything else I'm missing?
Mark |