Re: Core Data : Multiprocess (was Multiuser) ?
Re: Core Data : Multiprocess (was Multiuser) ?
- Subject: Re: Core Data : Multiprocess (was Multiuser) ?
- From: Ben Trumbull <email@hidden>
- Date: Sat, 7 Aug 2010 16:01:29 -0700
> Sorry. I see I've created confusion by putting "Multiuser" in the subject. I should have said "Multiprocess"
yeah.
>> Yes, several Apple frameworks use Core Data databases from multiple processes simultaneously with a single user account and single physical machine.
>
> Later, a reference is made to the iCal, Mail and Address Book apps.
>
> That's what I'm interested in. Specifically, an app + a background process, same Mac, same user, sharing a non-document sqlite file. So it appears that all should work, presumably as described in the "Change Management" section of "Core Data Programming Guide".
yes, that works out of the box.
> One thing still bothers me. Twice in that document, it mentions "managed object contexts in the *same application*". What if they are in *different processes*? Possibly the author just wasn't thinking of that?
On the same physical machine and local file system, the behavior between MOCs in the same process but with different PSCs and MOCs in different processes is effectively the same.
> I've done some more testing since my original post and it appear does appear to work ˆ the errors I was seeing yesterday were "Could not merge changes" errors (133020 in NSCocoaErrorDomain), and I presume these were due to the fact that I had not set a merge policy on these managed object contexts.
yes. That's correct.
> But I have yet to reproduce and prove this. Any additional assurance that what I'm doing should work would be appreciated.
There are a few things to be mindful of:
(1) creating the db originally requires additional coordination (like your own NSDistributedLock). Basically, there can be a race condition between the 2 processes creating the file. After creating the db, you'll want to save immediately to force the schema and UUID to get persisted so other processes see the same one at that path
(2) store metadata does not have optimistic concurrency control like the managed objects do (e.g. no version tracking). you'll want to minimize any custom metadata, and perhaps store it in an entity with a single row.
(3) you may want to refresh data more aggressively. If so, you should NEVER use -refreshObject:mergeChanges:NO on objects that are -isInserted, -isUpdated, or -isDeleted. You should use -refreshObject:mergeChanges:YES on any dirty managed objects.
Depending on how much data you want merged into the other process, you may wish to send a little IPC or NSDistributedNotification with bread crumbs to only refresh the changed objects of importance. It's a common mistake to post a generic notification to the other process that says "world changed; have fun".
(4) As with multi-threading, deleting data out from underneath the other MOCs can create challenges (faults that throw because the requested data has been nuked into oblivion). You'll probably want to use prefetching and setReturnsObjectsAsFaults:NO more than usual as well as this method added in 10.6 instead of -objectWithID:
/* returns the object for the specified ID if it is already registered in the context, or faults the object into the context. It might perform I/O if the data is uncached. If the object cannot be fetched, or does not exist, or cannot be faulted, it returns nil. Unlike -objectWithID: it never returns a fault. */
- (NSManagedObject*)existingObjectWithID:(NSManagedObjectID*)objectID error:(NSError**)error __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
- Ben
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please 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