couchbase / couchbase-lite-ios

Lightweight, embedded, syncable NoSQL database engine for iOS and MacOS apps.
Apache License 2.0
1.62k stars 297 forks source link

request for _changes using internalURL gives kCFHostErrorUnknown in change tracker #45

Closed pegli closed 11 years ago

pegli commented 11 years ago

I'm trying to set up local replication between two databases, and it seems like the NSURLProtocol isn't being picked up by CBLSocketChangeTracker. Here's the test code:

self.sourceDb = [[CBLManager sharedInstance] createDatabaseNamed:kSourceDbName error:nil];
for (unsigned i=0; i<20; i++) {
    NSDictionary * properties = @{@"name":@"test",@"sequence": @(i)};
    CBLDocument * doc = [self.sourceDb untitledDocument];
    [doc putProperties: properties error:nil];
}
self.targetDb = [[CBLManager sharedInstance] createDatabaseNamed:kTargetDbName error:nil];
self.replication = [self.targetDb pullFromURL:self.sourceDb.internalURL];
[self.replication addObserver:self forKeyPath:@"completed" options:0 context:nil];
[self.replication addObserver:self forKeyPath:@"mode" options:0 context:nil];
[self.replication start];

The log shows that the initial connection to http://lite.couchbase./source/_local/235aa4ef8704428da3bcd63596f7efc7269d840f works fine but the change tracker requests for //lite.couchbase./source/_changes are failing with a kCFHostErrorUnknown error with kCFGetAddrInfoFailureKey of 8 ("hostname nor servname provided, or not known"). I put in some debugging and saw that CBL_URLProtocol canInitWithRequest: was not being called for HTTP requests originating in the CBLSocketChangeTracker class, probably because the change tracker is using CFHTTPMessageCreateRequest instead of NSURLRequest.

Full debug log is here: https://gist.github.com/pegli/5447998

snej commented 11 years ago

Yup, this is issue #5.

pegli commented 11 years ago

sigh... Sorry about that. I'll see if I can get it fixed now that I have a test app for the issue.

snej commented 11 years ago

The simplest way to fix it would require resurrecting the CBLConnectionChangeTracker class (sigh), and configuring the base class initializer to instantiate it when the URL is an internal CBL URL.

pegli commented 11 years ago

Is there some reason I can't use a combination of CBLDatabase+Internal changesSinceSequence:options:filter:params: and a NSNotification listener for CBL_DatabaseChangesNotification and do it all in-process?

snej commented 11 years ago

Yes, you can effectively do the same thing that -[CBLRouter do_GET_changes:] does in the continuous case. You'd need to implement a new subclass of CBLChangeListener to do this, but it shouldn't be too hard, especially since you can copy/adapt a lot of the code out of CBLRouter.