implementing multi-process shared DB in macOS using XPC

自古美人都是妖i 提交于 2019-12-11 15:19:59

问题


My Goal is to develop robust, coherent, and persistent DB that can be shared between processes, just list Windows Registry.

On a previous question I advised not to use CFPreferences (and NSUserDefaults) due to the following reason

Current versions of macOS have a great deal of difficulty, and sometimes outright refuse, to update the values in one process with the values set by a second process.

Alternatively, I advised to use the following approach:

To have one process responsible for all of the shared values and the other processes get/set those values via XPC.

The XPC is quite new to me but from what I've read so far, it seems to use GCD queues for each connection, so how can I keep coherency if there are multiple processes asking to access the same DB for R/W operations (how can I enforce single thread to execute items in all queues).

Furthermore, I'd like to make this DB to fulfill ACID requirements, how can I achieve this ?


回答1:


Here's my suggestion, and the solution I use in my applications.

(1) Create a named XPC service.

If you need to connect with your service from multiple apps, you'll need to name and register your service app with launchd.

(XPC make it pretty easy to create an anonymous service used only by your app, but connecting from other apps gets a little trickier. Start with the Daemons and Services Programming Guide.)

Note that in my solution, I already had a user agent registered with launchd, so this was just a matter of moving on to step (2).

(2) Add XPC message handlers to get and set the values you want to share.

- (void)queryPreferenceForKey:(NSString*)key withReply:(void(^)(id value))reply
{
    reply([[NSUserDefaults standardUserDefaults] objectForKey:key]);
}

- (void)setPreferenceValue:(id)value forKey:(NSString*)key withReply:(void(^)(BOOL changed))reply
{
    BOOL changed = NO;
    id previous = [[DDUserPreferences standardUserDefaults] objectForKey:key];
    if (!OBJECTS_EQUAL(previous,value))
        {
        [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
        changed = YES;
        }
    reply(changed);
}

(3) There is no step 3.

Basically, that's it. The NSUserDefault class is thread safe, so there are no concurrently issues, and it automatically takes care of serializing the property values and synchronizing them with the app's persistent defaults .plist file.

Note: since this is based on NSUserDefaults, the value objects must be property-list objects (NSString, NSNumber, NSArray, NSDictionary, NSDate, NSData, ...). See Preferences and Settings Programming Guide.



来源:https://stackoverflow.com/questions/51756142/implementing-multi-process-shared-db-in-macos-using-xpc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!