projectwonder/wonder — pull request #256 by maiksd (2012-07-31 19:26:44+00:00)
Title: globalIDForObject() without autoLock

Added a property to not autolock on globalIDForObject() since that
1) isn't an operation that goes into the EOF stack and needs locking
2) is a huge source for deadlocks when trying to transfer EOs into other ECs.

Explanation:

I'm currently wonderizing a large complicated existing concurrent app, migrating from MultiECLockManager to ERXEC's auto locking in the process. Besides stuff that autolocking covers well and background threads that are better off with manual locking, I also have foreground operations that spread work off to multiple threads. In that case, those threads all have their own EditingContext do to their work. When spawning them off, the source collection of EOs to operate on has to be distributed to those thread's editingContexts. However you do that, it always comes down to retrieving the global ID from the EO sitting in another thread's editingContext. Autolocking will in this case always lead to a deadlock.

In some cases I could run over the EOs and extract their IDs first, then distribute those to the worker threads. In other cases, changing APIs to accept global IDs instead of EOs would be a looot of refactoring.

When you look up the implementation of how the global ID is retrieved and delivered, there is really no reason to lock the editingContext for that operation. It's just a retrieval of a fixed existing value. Thus this addition. And I recommend to have the default of that setting "true" because I believe it can solve a lot of deadlock situations without causing any trouble.

Note: It is often recommended do not "pass EOs between editingContexts" but rather pass their global ID. EOUtilities.localInstanceIn() does exactly that if you look it up.