Re: Q about locked ec (again)
Hi Phillippe, Short Story: I have not had a chance to get back to this - just been too busy - and I have been using my quick-fix anonymous subclass as shown in that patch for my abstract task superclass. Long Story: That patch will not be implemented because it is not architecturally clean enough. I just need to get around to doing what Mike suggested in the comments on that JIRA - you can have a shot at that if you like and send me a git diff patch. In any case, if you setCoalesceLocks and setAutoLock after instance creation, there is (or at least there was back in early 2010) a tiny risk in a highly concurrent busy app that the ec gets auto-locked (as a result of a notification for example) between the statement of creation and the statements where you disable locking. However, the use of ERXExecutorService will ensure that you have a ERXTaskThreadPoolExecutor in play which will in turn ensure that you will not get a deadlock since any locked ec will be unlocked at the end of the task (even after you do your own balanced lock/unlock) The downside of this is that because of that tiny risk of autolock when your background ec was created, you have a case where you cannot call ec.dispose because if an autolock happened and you try to call ec.dispose you get an error. So if you want GC and ec.dispose'ing, you must create a manually locked instance from the start and we don't have API in Wonder for that right now yet. Regards, Kieran On Oct 17, 2011, at 6:49 PM, Philippe Rabier wrote: The question is mainly for Kieran. In the framework COScheduler (job scheduling), I expose an abstract method newEditingContext() to let the developer create his own ec with autolock = false (see discussion in february 2010) like this: @Override public EOEditingContext newEditingContext() { return COEditingContextFactory.newManualLockingEditingContext(new EOObjectStoreCoordinator()); } After seeing your presentation at the WOWODC'11, I was plenty of hope because I discover the class ERXTaskObjectStoreCoordinatorPool which is great. So I decided to remove this method to simplify the use of the framework and use the obs pool. However, I see the pb remains in the class ERXAbstractTask when I read the javadoc: /** * strongYou must manually lock and unlock the editing context returned by * this method.strong It is not recommended that you depend on auto * locking in background threads. * * Even though this method currently returns an auto-locking EC if * auto-locking is turned on for the app, a future update is planned that * will return a manually locking EC from this method even if auto-locking * is turned on for regular ECs used in normal request-response execution. * * @return a new EOEditingContext. */ protected EOEditingContext newEditingContext() IMH, we can't set this kind of setting at the application level because it's dangerous: we can mix background threads and UI in the same app. Regarding the framework I'm working on, I see 2 options: - set the abstract method newEditingContext() and let the user/developer create its own method like that: EOObjectStoreCoordinator osc = ERXTaskObjectStoreCoordinatorPool.objectStoreCoordinator(); ERXEC ec = (ERXEC) MyECFactory.newManualLockingEditingContext(osc); or provide a newEditingContext() method like you but I would add: EOObjectStoreCoordinator osc = ERXTaskObjectStoreCoordinatorPool.objectStoreCoordinator(); ERXEC ec = (ERXEC) ERXEC.newEditingContext(osc);; ec.setCoalesceAutoLocks(false); ec.setUseAutoLock(false); I don't like very much the 2 options even if the first one can guarantee a good working. Sorry to be so long but do you have an update about the ticket below? Philippe On 19 févr. 2010, at 20:07, Kieran Kelleher wrote: http://issues.objectstyle.org/jira/browse/WONDER-478 ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/kelleherk%40gmail.com This email sent to kelleh...@gmail.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Q about locked ec (again)
The question is mainly for Kieran. In the framework COScheduler (job scheduling), I expose an abstract method newEditingContext() to let the developer create his own ec with autolock = false (see discussion in february 2010) like this: @Override public EOEditingContext newEditingContext() { return COEditingContextFactory.newManualLockingEditingContext(new EOObjectStoreCoordinator()); } After seeing your presentation at the WOWODC'11, I was plenty of hope because I discover the class ERXTaskObjectStoreCoordinatorPool which is great. So I decided to remove this method to simplify the use of the framework and use the obs pool. However, I see the pb remains in the class ERXAbstractTask when I read the javadoc: /** * strongYou must manually lock and unlock the editing context returned by * this method.strong It is not recommended that you depend on auto * locking in background threads. * * Even though this method currently returns an auto-locking EC if * auto-locking is turned on for the app, a future update is planned that * will return a manually locking EC from this method even if auto-locking * is turned on for regular ECs used in normal request-response execution. * * @return a new EOEditingContext. */ protected EOEditingContext newEditingContext() IMH, we can't set this kind of setting at the application level because it's dangerous: we can mix background threads and UI in the same app. Regarding the framework I'm working on, I see 2 options: - set the abstract method newEditingContext() and let the user/developer create its own method like that: EOObjectStoreCoordinator osc = ERXTaskObjectStoreCoordinatorPool.objectStoreCoordinator(); ERXEC ec = (ERXEC) MyECFactory.newManualLockingEditingContext(osc); or provide a newEditingContext() method like you but I would add: EOObjectStoreCoordinator osc = ERXTaskObjectStoreCoordinatorPool.objectStoreCoordinator(); ERXEC ec = (ERXEC) ERXEC.newEditingContext(osc);; ec.setCoalesceAutoLocks(false); ec.setUseAutoLock(false); I don't like very much the 2 options even if the first one can guarantee a good working. Sorry to be so long but do you have an update about the ticket below? Philippe On 19 févr. 2010, at 20:07, Kieran Kelleher wrote: http://issues.objectstyle.org/jira/browse/WONDER-478 ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
Because ERXLongResponseTask, which I don't use, uses auto lock/unlock, just like a request thread. That code is useful for plain old java task Threads that implement Callable or Runnable and do not extend ERXLongResponseTask. It is also useful for any other time you don't want an autolocking EC, perhaps for lazily initialization of an EO in the database in a business logic method where there is no guarantees that you can assume you are in a request thread with autolocking. I will make a patch and see if someone with commit rights can apply it. Regards, Kieran On Feb 19, 2010, at 10:21 AM, John Huss wrote: So why don't we add that code (or something similar) to ERXLongResponseTask.DefaultImplementation? John On Thu, Feb 18, 2010 at 6:02 AM, Kieran Kelleher kieran_li...@mac.com wrote: Really, just paste the few lines of code I gave u yesterday into a file and name it MyEOUtils.java, and then change your code below to use the static factory method to create the 'manual locking' ec. ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
http://issues.objectstyle.org/jira/browse/WONDER-478 On Feb 19, 2010, at 11:44 AM, Kieran Kelleher wrote: Because ERXLongResponseTask, which I don't use, uses auto lock/unlock, just like a request thread. That code is useful for plain old java task Threads that implement Callable or Runnable and do not extend ERXLongResponseTask. It is also useful for any other time you don't want an autolocking EC, perhaps for lazily initialization of an EO in the database in a business logic method where there is no guarantees that you can assume you are in a request thread with autolocking. I will make a patch and see if someone with commit rights can apply it. Regards, Kieran On Feb 19, 2010, at 10:21 AM, John Huss wrote: So why don't we add that code (or something similar) to ERXLongResponseTask.DefaultImplementation? John On Thu, Feb 18, 2010 at 6:02 AM, Kieran Kelleher kieran_li...@mac.com wrote: Really, just paste the few lines of code I gave u yesterday into a file and name it MyEOUtils.java, and then change your code below to use the static factory method to create the 'manual locking' ec. ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/kieran_lists%40mac.com This email sent to kieran_li...@mac.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
Thank you VERY much... I'll use it right away!! :-D On Feb 19, 2010, at 2:07 PM, Kieran Kelleher wrote: http://issues.objectstyle.org/jira/browse/WONDER-478 On Feb 19, 2010, at 11:44 AM, Kieran Kelleher wrote: Because ERXLongResponseTask, which I don't use, uses auto lock/unlock, just like a request thread. That code is useful for plain old java task Threads that implement Callable or Runnable and do not extend ERXLongResponseTask. It is also useful for any other time you don't want an autolocking EC, perhaps for lazily initialization of an EO in the database in a business logic method where there is no guarantees that you can assume you are in a request thread with autolocking. I will make a patch and see if someone with commit rights can apply it. Regards, Kieran On Feb 19, 2010, at 10:21 AM, John Huss wrote: So why don't we add that code (or something similar) to ERXLongResponseTask.DefaultImplementation? John On Thu, Feb 18, 2010 at 6:02 AM, Kieran Kelleher kieran_li...@mac.com wrote: Really, just paste the few lines of code I gave u yesterday into a file and name it MyEOUtils.java, and then change your code below to use the static factory method to create the 'manual locking' ec. ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/kieran_lists%40mac.com This email sent to kieran_li...@mac.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/rparada%40mac.com This email sent to rpar...@mac.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
Thanks Kieran, Ricardo, Anjo, Jon. Kieran, I follow your lead actually. I don't have too many threads/classes (just 3 classes) so I just modified my editingContext() in the classes like that: protected EOEditingContext editingContext() { if (editingContext == null) { editingContext = ERXEC.newEditingContext(); ((ERXEC) editingContext).setUseAutoLock(false); } return editingContext; } I thought about passing globalIDs but my description is a little bit simpler than my code so I can't (without changing the design). Have a good day. Philippe On 17 févr. 2010, at 21:23, Kieran Kelleher wrote: Some tidbits that might help: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) 2) If you have autolocking on and if you are using ERXEC.newEditingContext, you may get deadlocks. To continue to use autolocking in request threads and to created guaranteed non-autolocking EC's in plain old background threads, you can paste this into your own EO Utils class and just use the static creation method: /** * Anonymous ERXEC factory that creates manual locking ec's in an app where safeLocking is on by default */ private static ERXEC.Factory manualLockingEditingContextFactory = new ERXEC.DefaultFactory() { @Override protected EOEditingContext _createEditingContext(EOObjectStore parent) { return new ERXEC(parent == null ? EOEditingContext.defaultParentObjectStore() : parent) { @Override public boolean useAutoLock() {return false;} @Override public boolean coalesceAutoLocks() {return false;} }; } }; /** * @return a regular ERXEC with no auto-locking features */ public static EOEditingContext newManualLockingEditingContext() { return manualLockingEditingContextFactory._newEditingContext(); } /** * I do not want autolocking in non-request threads * * @param parent * @return an ERXEC with safeLocking properties turned OFF. */ public static EOEditingContext newManualLockingEditingContext(EOObjectStore parent) { return manualLockingEditingContextFactory._newEditingContext(parent); } 3) Depending on the intensity of the EOF activity, you may want to use a different EOObjectStoreCoordinator than the default or a pool of them for background threads so as not to interfere with request thread EOF performance. On Feb 17, 2010, at 2:34 PM, Philippe Rabier wrote: Hi all, I get an issue with a multi threaded application. To be easier to understand, my description is simpler than the reality but that's enough to see what's going on I guess. I'm using: WO 5.4.3 Snow Leopard/ java 6 Wonder (not the very last but not old) I put the following properties: er.extensions.ERXEC.traceOpenLocks=true er.extensions.ERXEC.markOpenLocks=true There 2 threads (not worker threads handled by WO) created by a frameworkPrincipal (in the wonder sense) with a classical run loop (while (true)). BigObject A running in thread A has an editingContext A (ecA) that fetches, for example, customers from entity Customer BigObject B running in thread B has an editingContext B (ecB) that fetches objects, for example invoices from entity Invoice. Invoice has a to one relationship with Customer BigObject A passes to BigObject B a list of customers. Suppose there is only one customer in the list. Object B periodically fetches invoices, customer by customer, so it constructs a qualifier like invoice.customer.eq(aCustomer), then a fetchspec, ... Of course, there is some code like: ecB.lock(); try invoices = ecB.objectsWithFetchSpecification(fetchSpecification); catch finally ecB.unlock(); The log tells me that when ecB.objectsWithFetchSpecification is executed, ecA is locked. And it's locked forever. I wasn't sure to have to use a localInstance of customer because I use it only to create a qualifier. But I did the test and it's worth. If I execute something like that before the construction of the qualifier: myCustomers = EOUtilities.localInstanceOfObject(ecB, customers); ecA and ecB are locked automatically and never unlocked. I found a solution, that's to lock/unlock both editingContexts but I'm unsatisfied because I don't understand why EOUtilities.localInstance locks ecA
Re: Q about locked ec
Philippe, This isn't the same thing. Between the line that creates and the line that sets autolock to false below, another thread could call a method that triggers an autolock. If you can find the old discussion on this, you will see that I was actually doing sth like you have shown here and I still got deadlocks. Anjo's smart suggestion to return the anonymous inline subclass (if that's the right terminology) was the correct way to *guarantee* that the autolocking was off during instantiation of the EC. Really, just paste the few lines of code I gave u yesterday into a file and name it MyEOUtils.java, and then change your code below to use the static factory method to create the 'manual locking' ec. Regards, Kieran On Feb 18, 2010, at 5:30 AM, Philippe Rabier wrote: Thanks Kieran, Ricardo, Anjo, Jon. Kieran, I follow your lead actually. I don't have too many threads/classes (just 3 classes) so I just modified my editingContext() in the classes like that: protected EOEditingContext editingContext() { if (editingContext == null) { editingContext = ERXEC.newEditingContext(); ((ERXEC) editingContext).setUseAutoLock(false); } return editingContext; } I thought about passing globalIDs but my description is a little bit simpler than my code so I can't (without changing the design). Have a good day. Philippe On 17 févr. 2010, at 21:23, Kieran Kelleher wrote: Some tidbits that might help: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) 2) If you have autolocking on and if you are using ERXEC.newEditingContext, you may get deadlocks. To continue to use autolocking in request threads and to created guaranteed non-autolocking EC's in plain old background threads, you can paste this into your own EO Utils class and just use the static creation method: /** * Anonymous ERXEC factory that creates manual locking ec's in an app where safeLocking is on by default */ private static ERXEC.Factory manualLockingEditingContextFactory = new ERXEC.DefaultFactory() { @Override protected EOEditingContext _createEditingContext(EOObjectStore parent) { return new ERXEC(parent == null ? EOEditingContext.defaultParentObjectStore() : parent) { @Override public boolean useAutoLock() {return false;} @Override public boolean coalesceAutoLocks() {return false;} }; } }; /** * @return a regular ERXEC with no auto-locking features */ public static EOEditingContext newManualLockingEditingContext() { return manualLockingEditingContextFactory._newEditingContext(); } /** * I do not want autolocking in non-request threads * * @param parent * @return an ERXEC with safeLocking properties turned OFF. */ public static EOEditingContext newManualLockingEditingContext(EOObjectStore parent) { return manualLockingEditingContextFactory._newEditingContext(parent); } 3) Depending on the intensity of the EOF activity, you may want to use a different EOObjectStoreCoordinator than the default or a pool of them for background threads so as not to interfere with request thread EOF performance. On Feb 17, 2010, at 2:34 PM, Philippe Rabier wrote: Hi all, I get an issue with a multi threaded application. To be easier to understand, my description is simpler than the reality but that's enough to see what's going on I guess. I'm using: WO 5.4.3 Snow Leopard/ java 6 Wonder (not the very last but not old) I put the following properties: er.extensions.ERXEC.traceOpenLocks=true er.extensions.ERXEC.markOpenLocks=true There 2 threads (not worker threads handled by WO) created by a frameworkPrincipal (in the wonder sense) with a classical run loop (while (true)). BigObject A running in thread A has an editingContext A (ecA) that fetches, for example, customers from entity Customer BigObject B running in thread B has an editingContext B (ecB) that fetches objects, for example invoices from entity Invoice. Invoice has a to one relationship with Customer BigObject A passes to BigObject B a list of customers. Suppose there is only one customer in the list. Object B periodically fetches invoices, customer by customer, so it constructs a qualifier like invoice.customer.eq(aCustomer), then a fetchspec, ... Of course,
Re: Q about locked ec
Does this apply to ERXLongResponse pages? I have a report that I moved to an ERXLongResponse page and now the app hangs occasionally. Could this be a locking issue? Thanks, Steve On Feb 17, 2010, at 5:21 PM, Anjo Krank wrote: You *can* pass EOs between threads. You just really, wanna make sure your threads don't block each other (and do proper locking, auto may not be good enough). In particular, you don't wanna use the session EC in a long running thread. Cheers, Anjo Am 17.02.2010 um 21:23 schrieb Kieran Kelleher: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/speery%40me.com This email sent to spe...@me.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
I demand a WOWODC session about locking, this is one thing that popup every week in the lists :-) Does this apply to ERXLongResponse pages? I have a report that I moved to an ERXLongResponse page and now the app hangs occasionally. Could this be a locking issue? Thanks, Steve On Feb 17, 2010, at 5:21 PM, Anjo Krank wrote: You *can* pass EOs between threads. You just really, wanna make sure your threads don't block each other (and do proper locking, auto may not be good enough). In particular, you don't wanna use the session EC in a long running thread. Cheers, Anjo Am 17.02.2010 um 21:23 schrieb Kieran Kelleher: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/speery%40me.com This email sent to spe...@me.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/probert%40macti.ca This email sent to prob...@macti.ca ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
A long response most of the time locks in start and unlocks on end. If you use the session EC for... well, you figure it out. Cheers, Anjo Am 18.02.2010 um 22:09 schrieb Steve Peery: Does this apply to ERXLongResponse pages? I have a report that I moved to an ERXLongResponse page and now the app hangs occasionally. Could this be a locking issue? Thanks, Steve On Feb 17, 2010, at 5:21 PM, Anjo Krank wrote: You *can* pass EOs between threads. You just really, wanna make sure your threads don't block each other (and do proper locking, auto may not be good enough). In particular, you don't wanna use the session EC in a long running thread. Cheers, Anjo Am 17.02.2010 um 21:23 schrieb Kieran Kelleher: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/speery%40me.com This email sent to spe...@me.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
That could explain a few things. Thanks, Steve On Feb 18, 2010, at 4:20 PM, Anjo Krank wrote: A long response most of the time locks in start and unlocks on end. If you use the session EC for... well, you figure it out. Cheers, Anjo Am 18.02.2010 um 22:09 schrieb Steve Peery: Does this apply to ERXLongResponse pages? I have a report that I moved to an ERXLongResponse page and now the app hangs occasionally. Could this be a locking issue? Thanks, Steve On Feb 17, 2010, at 5:21 PM, Anjo Krank wrote: You *can* pass EOs between threads. You just really, wanna make sure your threads don't block each other (and do proper locking, auto may not be good enough). In particular, you don't wanna use the session EC in a long running thread. Cheers, Anjo Am 17.02.2010 um 21:23 schrieb Kieran Kelleher: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/speery%40me.com This email sent to spe...@me.com ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Q about locked ec
Hi all, I get an issue with a multi threaded application. To be easier to understand, my description is simpler than the reality but that's enough to see what's going on I guess. I'm using: WO 5.4.3 Snow Leopard/ java 6 Wonder (not the very last but not old) I put the following properties: er.extensions.ERXEC.traceOpenLocks=true er.extensions.ERXEC.markOpenLocks=true There 2 threads (not worker threads handled by WO) created by a frameworkPrincipal (in the wonder sense) with a classical run loop (while (true)). BigObject A running in thread A has an editingContext A (ecA) that fetches, for example, customers from entity Customer BigObject B running in thread B has an editingContext B (ecB) that fetches objects, for example invoices from entity Invoice. Invoice has a to one relationship with Customer BigObject A passes to BigObject B a list of customers. Suppose there is only one customer in the list. Object B periodically fetches invoices, customer by customer, so it constructs a qualifier like invoice.customer.eq(aCustomer), then a fetchspec, ... Of course, there is some code like: ecB.lock(); try invoices = ecB.objectsWithFetchSpecification(fetchSpecification); catch finally ecB.unlock(); The log tells me that when ecB.objectsWithFetchSpecification is executed, ecA is locked. And it's locked forever. I wasn't sure to have to use a localInstance of customer because I use it only to create a qualifier. But I did the test and it's worth. If I execute something like that before the construction of the qualifier: myCustomers = EOUtilities.localInstanceOfObject(ecB, customers); ecA and ecB are locked automatically and never unlocked. I found a solution, that's to lock/unlock both editingContexts but I'm unsatisfied because I don't understand why EOUtilities.localInstance locks ecA and ecB and doesn't unlock them. Naturally I would find the good way to use it. Any idea what's going on? The stack trace when ecA is locked by BigObjectB: Outstanding at @Thread[Thread-4,5,main] java.lang.Exception: Locked at er.extensions.eof.ERXEC.traceLock(ERXEC.java:532) at er.extensions.eof.ERXEC.lock(ERXEC.java:502) at er.extensions.eof.ERXEC.autoLock(ERXEC.java:627) at er.extensions.eof.ERXEC.globalIDForObject(ERXEC.java:844) at com.webobjects.eoaccess.EODatabaseContext._globalIDForObject(EODatabaseContext.java:4644) at com.webobjects.eoaccess.EODatabaseContext.databaseOperationForObject(EODatabaseContext.java:4767) at com.webobjects.eoaccess.EODatabaseContext.valuesForKeys(EODatabaseContext.java:6535) at com.webobjects.eocontrol.EOObjectStoreCoordinator.valuesForKeys(EOObjectStoreCoordinator.java:326) at com.webobjects.eoaccess.EOQualifierSQLGeneration$_KeyValueQualifierSupport.schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:439) at er.extensions.ERXExtensions$KeyValueQualifierSQLGenerationSupport.schemaBasedQualifierWithRootEntity(ERXExtensions.java:333) at com.webobjects.eoaccess.EOQualifierSQLGeneration$Support._schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:179) at com.webobjects.eoaccess.EOQualifierSQLGeneration$_AndQualifierSupport.schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:530) at com.webobjects.eoaccess.EOQualifierSQLGeneration$Support._schemaBasedQualifierWithRootEntity(EOQualifierSQLGeneration.java:179) at com.webobjects.eoaccess.EODatabaseChannel.selectObjectsWithFetchSpecification(EODatabaseChannel.java:227) at com.webobjects.eoaccess.EODatabaseContext._objectsWithFetchSpecificationEditingContext(EODatabaseContext.java:3055) at com.webobjects.eoaccess.EODatabaseContext.objectsWithFetchSpecification(EODatabaseContext.java:3195) at com.webobjects.eocontrol.EOObjectStoreCoordinator.objectsWithFetchSpecification(EOObjectStoreCoordinator.java:488) at com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:4069) at er.extensions.eof.ERXEC.objectsWithFetchSpecification(ERXEC.java:1211) at com.webobjects.eocontrol.EOEditingContext.objectsWithFetchSpecification(EOEditingContext.java:) at fr.sophiacom.ynp.push.BigObjectB.fetchesInvoice(BigObjectB.java:238) at fr.sophiacom.BigObjectB._run(BigObjectB.java:110) at er.extensions.concurrency.ERXRunnable.run(ERXRunnable.java:23) at java.lang.Thread.run(Thread.java:637) Philippe ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
Some tidbits that might help: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) 2) If you have autolocking on and if you are using ERXEC.newEditingContext, you may get deadlocks. To continue to use autolocking in request threads and to created guaranteed non-autolocking EC's in plain old background threads, you can paste this into your own EO Utils class and just use the static creation method: /** * Anonymous ERXEC factory that creates manual locking ec's in an app where safeLocking is on by default */ private static ERXEC.Factory manualLockingEditingContextFactory = new ERXEC.DefaultFactory() { @Override protected EOEditingContext _createEditingContext(EOObjectStore parent) { return new ERXEC(parent == null ? EOEditingContext.defaultParentObjectStore() : parent) { @Override public boolean useAutoLock() {return false;} @Override public boolean coalesceAutoLocks() {return false;} }; } }; /** * @return a regular ERXEC with no auto-locking features */ public static EOEditingContext newManualLockingEditingContext() { return manualLockingEditingContextFactory._newEditingContext(); } /** * I do not want autolocking in non-request threads * * @param parent * @return an ERXEC with safeLocking properties turned OFF. */ public static EOEditingContext newManualLockingEditingContext(EOObjectStore parent) { return manualLockingEditingContextFactory._newEditingContext(parent); } 3) Depending on the intensity of the EOF activity, you may want to use a different EOObjectStoreCoordinator than the default or a pool of them for background threads so as not to interfere with request thread EOF performance. On Feb 17, 2010, at 2:34 PM, Philippe Rabier wrote: Hi all, I get an issue with a multi threaded application. To be easier to understand, my description is simpler than the reality but that's enough to see what's going on I guess. I'm using: WO 5.4.3 Snow Leopard/ java 6 Wonder (not the very last but not old) I put the following properties: er.extensions.ERXEC.traceOpenLocks=true er.extensions.ERXEC.markOpenLocks=true There 2 threads (not worker threads handled by WO) created by a frameworkPrincipal (in the wonder sense) with a classical run loop (while (true)). BigObject A running in thread A has an editingContext A (ecA) that fetches, for example, customers from entity Customer BigObject B running in thread B has an editingContext B (ecB) that fetches objects, for example invoices from entity Invoice. Invoice has a to one relationship with Customer BigObject A passes to BigObject B a list of customers. Suppose there is only one customer in the list. Object B periodically fetches invoices, customer by customer, so it constructs a qualifier like invoice.customer.eq(aCustomer), then a fetchspec, ... Of course, there is some code like: ecB.lock(); try invoices = ecB.objectsWithFetchSpecification(fetchSpecification); catch finally ecB.unlock(); The log tells me that when ecB.objectsWithFetchSpecification is executed, ecA is locked. And it's locked forever. I wasn't sure to have to use a localInstance of customer because I use it only to create a qualifier. But I did the test and it's worth. If I execute something like that before the construction of the qualifier: myCustomers = EOUtilities.localInstanceOfObject(ecB, customers); ecA and ecB are locked automatically and never unlocked. I found a solution, that's to lock/unlock both editingContexts but I'm unsatisfied because I don't understand why EOUtilities.localInstance locks ecA and ecB and doesn't unlock them. Naturally I would find the good way to use it. Any idea what's going on? The stack trace when ecA is locked by BigObjectB: Outstanding at @Thread[Thread-4,5,main] java.lang.Exception: Locked at er.extensions.eof.ERXEC.traceLock(ERXEC.java:532) at er.extensions.eof.ERXEC.lock(ERXEC.java:502) at er.extensions.eof.ERXEC.autoLock(ERXEC.java:627) at er.extensions.eof.ERXEC.globalIDForObject(ERXEC.java:844) at com.webobjects.eoaccess.EODatabaseContext._globalIDForObject(EODatabaseContext.java:4644) at com.webobjects.eoaccess.EODatabaseContext.databaseOperationForObject(EODatabaseContext.java:4767) at
Re: Q about locked ec
Hmm... I'm using background threads in my apps to do some processing. The thread creates is editing context for its own use. Something like this: EOObjectStoreCoordinator parentObjectStore = new EOObjectStoreCoordinator(); editingContext = ERXEC.newEditingContext(parentObjectStore); I pass GIDs to this background thread. But if I understand what you are saying, creating the editing context like this can still get me in trouble still. Ricardo On Feb 17, 2010, at 3:23 PM, Kieran Kelleher wrote: Some tidbits that might help: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) 2) If you have autolocking on and if you are using ERXEC.newEditingContext, you may get deadlocks. To continue to use autolocking in request threads and to created guaranteed non-autolocking EC's in plain old background threads, you can paste this into your own EO Utils class and just use the static creation method: /** * Anonymous ERXEC factory that creates manual locking ec's in an app where safeLocking is on by default */ private static ERXEC.Factory manualLockingEditingContextFactory = new ERXEC.DefaultFactory() { @Override protected EOEditingContext _createEditingContext(EOObjectStore parent) { return new ERXEC(parent == null ? EOEditingContext.defaultParentObjectStore() : parent) { @Override public boolean useAutoLock() {return false;} @Override public boolean coalesceAutoLocks() {return false;} }; } }; /** * @return a regular ERXEC with no auto-locking features */ public static EOEditingContext newManualLockingEditingContext() { return manualLockingEditingContextFactory._newEditingContext(); } /** * I do not want autolocking in non-request threads * * @param parent * @return an ERXEC with safeLocking properties turned OFF. */ public static EOEditingContext newManualLockingEditingContext(EOObjectStore parent) { return manualLockingEditingContextFactory._newEditingContext(parent); } 3) Depending on the intensity of the EOF activity, you may want to use a different EOObjectStoreCoordinator than the default or a pool of them for background threads so as not to interfere with request thread EOF performance. On Feb 17, 2010, at 2:34 PM, Philippe Rabier wrote: Hi all, I get an issue with a multi threaded application. To be easier to understand, my description is simpler than the reality but that's enough to see what's going on I guess. I'm using: WO 5.4.3 Snow Leopard/ java 6 Wonder (not the very last but not old) I put the following properties: er.extensions.ERXEC.traceOpenLocks=true er.extensions.ERXEC.markOpenLocks=true There 2 threads (not worker threads handled by WO) created by a frameworkPrincipal (in the wonder sense) with a classical run loop (while (true)). BigObject A running in thread A has an editingContext A (ecA) that fetches, for example, customers from entity Customer BigObject B running in thread B has an editingContext B (ecB) that fetches objects, for example invoices from entity Invoice. Invoice has a to one relationship with Customer BigObject A passes to BigObject B a list of customers. Suppose there is only one customer in the list. Object B periodically fetches invoices, customer by customer, so it constructs a qualifier like invoice.customer.eq(aCustomer), then a fetchspec, ... Of course, there is some code like: ecB.lock(); try invoices = ecB.objectsWithFetchSpecification(fetchSpecification); catch finally ecB.unlock(); The log tells me that when ecB.objectsWithFetchSpecification is executed, ecA is locked. And it's locked forever. I wasn't sure to have to use a localInstance of customer because I use it only to create a qualifier. But I did the test and it's worth. If I execute something like that before the construction of the qualifier: myCustomers = EOUtilities.localInstanceOfObject(ecB, customers); ecA and ecB are locked automatically and never unlocked. I found a solution, that's to lock/unlock both editingContexts but I'm unsatisfied because I don't understand why EOUtilities.localInstance locks ecA and ecB and doesn't unlock them. Naturally I would find the good way to use it. Any idea what's going on? The stack trace when ecA is locked by BigObjectB: Outstanding at
Re: Q about locked ec
You *can* pass EOs between threads. You just really, wanna make sure your threads don't block each other (and do proper locking, auto may not be good enough). In particular, you don't wanna use the session EC in a long running thread. Cheers, Anjo Am 17.02.2010 um 21:23 schrieb Kieran Kelleher: 1) Don't pass EOs between threads. Pass their EOGlobalIDs and use ec.faultForGlobalID to rehydrate them in an ec in the thread that needs them. Use Wonder ERXEOSomethingUtilities.convertEOtoGID if desired. (Something = 'Access' or 'Control', I can never remember which) ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
Ricardo J. Parada wrote: Hmm... I'm using background threads in my apps to do some processing. The thread creates is editing context for its own use. Something like this: EOObjectStoreCoordinator parentObjectStore = new EOObjectStoreCoordinator(); editingContext = ERXEC.newEditingContext(parentObjectStore); I pass GIDs to this background thread. But if I understand what you are saying, creating the editing context like this can still get me in trouble still. Ricardo Ricardo, It might be useful to consider using ERXTimerTask or dive into its implementation for more info. I run all my background threads this way and I have zero lock issues. I don't create my own OSC either for what that's worth. Jon ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Q about locked ec
Am 17.02.2010 um 23:18 schrieb Ricardo J. Parada: 2) If you have autolocking on and if you are using ERXEC.newEditingContext, you may get deadlocks. How so? Cheers, Anjo ___ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com