Re: Core Data & threads [re: Ping: Look for hints for "nested transaction" problem with Core Data]
Re: Core Data & threads [re: Ping: Look for hints for "nested transaction" problem with Core Data]
- Subject: Re: Core Data & threads [re: Ping: Look for hints for "nested transaction" problem with Core Data]
- From: Ben Trumbull <email@hidden>
- Date: Fri, 16 Mar 2007 20:48:57 -0700
At 11:07 AM +0100 3/16/07, Pierre Chatelier wrote:
I have got a multi-document application. Each document may launch a
bunch of computations. Each computation can be described by a task
do be done, and I have a central, shared factory, that receives the
tasks. The document sends a set of tasks to the factory, and waits
for the factory to return the (ordered) results for each task.
Internally, the factory dispatches the task on several threads.
Moreover, the computations are cached in a database for future use :
if a task has already be seen, it will not be computed again (such a
computation can be stored persistently).
It ought to be very natural to model that by having the factory
dispatch the tasks to several threads, and having those threads each
save their changes independently, and communicate back that the
results are available.
The save-then-notify-others idiom works quite well with multiple
threads in Core Data.
To manage the cache, I have a CoreData database. Each result of a
task is a managed object. So, when a consumer assigns itself a task
in the queue, it tries at first to fetch the managedContext for a
potential cached value, that would allow him to skip the
computation. When a consumer has to trigger a computation, it
finally store the data in the managedContext.
In a background thread, the managedContext is asked to be saved
regularly (let's say every two minutes)
I'm still not clear on what benefit there is in separating the save
operation from the tasks computing the results. It seems to
needlessly build additional dependencies between threads.
-First, the background saving thread. This is not really a problem,
buf if each thread save its context every two minutes, there is a
desynchronization. For instance, if there are 4 threads, it is
possible that the save operations are triggered every 30 seconds,
instead of being grouped. This may be have a performance impact
because of disk access.
That's true, but I would cross that bridge when you actually get
there. If you find having the threads save independently is a
problem in the real world, file a bug. We'll take a look at your
samples and provide some feedback.
-Second, different threads may be implied for the different tasks of
a single document. That is to say that the cached values fetched in
the store will be dispatched in different managedContexts. This
should not be a problem, except for optimization. Indeed, my
database contains many (!) small objects. I have noticed that
performing one fetch per object had a big performance impact. So, I
have found a way to make a big pre-fetch on a superset of the data
that may be used as cached values. Now, that means that I have to do
that pre-fetch in every managedContexts.
If you suspect the objects have already been fetched by someone else
(or yourself previously), use -objectWithID: or
-objectRegisteredForID: instead of -executeFetchRequest:
The Background Fetching example in
/Developer/Examples/CoreData/BackgroundFetching/ demonstrates some of
this, and has comments about why different methods are used in
different places to manage the cache and inter-thread life cycle
issues.
If you feel this example needs enhancements, or Core Data could do
something better in this area, please file a request with
<http://bugreport.apple.com>
Performance problems and enhancement suggestions are also considered
"bugs". Attaching a sample project that demonstrates your problem is
appreciated.
--
-Ben
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden