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: Pierre Chatelier <email@hidden>
- Date: Fri, 16 Mar 2007 11:07:59 +0100
Can I summarize with "if I use several thread, I should use one
NSManagedObjectContext per thread" ?
At least one, yes.
Ok
Are you having performance problems with a vanilla save ?
Hu ? I do not know what is a vanilla save; I have never seen that term.
What problem are you actually trying to solve ?
Here are some details about what I wanted to do, and how I did it. As
you will see, evolving from one to several contexts is definitely
possible, but is not that simple. If you have time to read that and
think "this guy is doing things wrong", I would be happy to get some
advices, but anyway, I am happy with your explanations so far. In the
future, I will be careful with that CoreData & threads problem.
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).
To implement that, I have a shared object (the factory) that manages
one queue of tasks. When it is created, the factory launches several
threads which are "consumers" regarding the queue. They will be
asleep when the queue is empty.
Each consumer computes one task at a time. It takes each task in the
queue, and incrementally fills an array of results, to be returned to
the producer of that task when all the tasks for that producer have
been handled.
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)
No, you tell me that I should use one managedContext per thread. This
implies many modifications in my structure.
-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.
-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.
-Third, when the factory fills the array of results to be returned,
it takes the data into the managedContext. If there all several
managedContexts, it means that I have to fetch all of them to find
which one contains the new data.
Regards,
Pierre Chatelier
_______________________________________________
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