kCBLReplicationChangeNotification gets called only once, then never again

148 views
Skip to first unread message

Michael Hines

unread,
Aug 22, 2014, 12:39:04 PM8/22/14
to mobile-c...@googlegroups.com
Hi,

I've copy and pasted (almost word for word) the example from the documentation on how to use NSNotifications to track a replication from your website.

My replications themselves work great - no problems at all.

However, the below function only gets called *once* when the iOS app first starts up (I set a breakpoint).

After that, I get nothing. (Sad).

But, if I turn on all the debugging flags, I clearly see that the replication is working normally and I can see the progress messages X/Y completed documents and so for. (I have about 5000 documents in my database that are getting replicated).

Any ideas why I'm not getting any future change notifications?

- (void)pushChanged:(NSNotification *)notification {                                                                  
   
CBLReplication *push = notification.object;                                                                      
   
unsigned completed = push.completedChangesCount;                                                                  
   
unsigned total = push.changesCount;                                                                              
   
NSLog(@"COUCH: push %u/%u", completed, total);
}                                                                                                                    
                                                                                                                     
// and then later, I do this:
           
    NSURL
* url = [NSURL URLWithString: foo];
   
CBLReplication *push = [db createPushReplication:url];                                                                                                                      
                                                                                                                     
   
[[NSNotificationCenter defaultCenter] addObserver: self                                                          
                                             selector
: @selector(pushChanged:)                                        
                                                 name
: kCBLReplicationChangeNotification                              
                                               
object: push];                                                        
                                                                                                                     
                                                       
    push
.continuous = YES;                                                                          
                                                                                                                     
   
[push start];


Thanks!
- Michael Hines

Jens Alfke

unread,
Aug 22, 2014, 2:03:49 PM8/22/14
to mobile-c...@googlegroups.com

> On Aug 22, 2014, at 9:39 AM, Michael Hines <mic...@hinespot.com> wrote:
>
> Any ideas why I'm not getting any future change notifications?

Are you starting the replication on the main thread? If not:
If you run it on a background thread, does it have an active runloop?
Or if you're using a dispatch queue, have you set the CBLManager's dispatchQueue property?

Does the object that contains those two methods stay around long enough? If it's dealloced, it won't get any further notifications.

—Jens

Michael Hines

unread,
Aug 24, 2014, 1:31:34 AM8/24/14
to mobile-c...@googlegroups.com
Thanks for the reply. That was indeed the problem: I was using a background thread.

It kind of sucks that I have to keep calling the runloop's run() function from a timer just to get access to the notifications because I'm using this thread for other long-term operations. (Once I did that, the notifications started coming back again).

Does anybody have a better solution to avoid polling the runloop for CBL notifications?

Is anyone else using CBL in a background thread?

- Michael

Jens Alfke

unread,
Aug 24, 2014, 2:16:37 AM8/24/14
to mobile-c...@googlegroups.com

On Aug 23, 2014, at 10:31 PM, Michael Hines <mic...@hinespot.com> wrote:

It kind of sucks that I have to keep calling the runloop's run() function from a timer just to get access to the notifications because I'm using this thread for other long-term operations. (Once I did that, the notifications started coming back again).

I'm confused. How is the timer (I assume you mean an NSTimer) firing if the thread's not already running its runloop?

If you think about it, you really can't get the notifications without the runloop. If your thread spends all its time running your own code, the only way the notification could get called is if it interrupted your code — at some random CPU instruction — and called into your handler method. (Which is basically the way Unix signals work, and everyone agrees that signals are a terrible design and nearly impossible to handle reliably.)

—Jens

Michael R. Hines

unread,
Aug 24, 2014, 3:02:25 AM8/24/14
to mobile-c...@googlegroups.com
On Sat, 2014-08-23 at 23:16 -0700, Jens Alfke wrote:
>
> > On Aug 23, 2014, at 10:31 PM, Michael Hines <mic...@hinespot.com>
> > wrote:
> >
> > It kind of sucks that I have to keep calling the runloop's run()
> > function from a timer just to get access to the notifications
> > because I'm using this thread for other long-term operations. (Once
> > I did that, the notifications started coming back again).



>
> If you think about it, you really can't get the notifications without
> the runloop. If your thread spends all its time running your own code,
> the only way the notification could get called is if it interrupted
> your code — at some random CPU instruction — and called into your
> handler method. (Which is basically the way Unix signals work, and
> everyone agrees that signals are a terrible design and nearly
> impossible to handle reliably.)
>

Is it possible for CBL to use "distributed" notifications? Could we get
CBL to post a notification to the distributed notification center and
then receive them on the main thread instead of the current thread?

If we could do that, then I wouldn't have to use the runloop and those
notifications could be processed on another thread that *does* have a
runloop?

I'm willing to write a patch if you guys think its a reasonable idea....


> >
> I'm confused. How is the timer (I assume you mean an NSTimer) firing
if the thread's not already running its runloop?
>
>
I misspoke - my background thread code just times out and checks
the runloop to see if there's anything available to be proceseed
after a "timeout" and then goes back about its business. But that's kind
of wasteful.

>
> —Jens
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Couchbase Mobile" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/mobile-couchbase/uF-jSiLbre8/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> mobile-couchba...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/mobile-couchbase/CB48DFD7-E69D-4087-BA8B-07A30A2A0BA2%40couchbase.com.
> For more options, visit https://groups.google.com/d/optout.


Michael R. Hines

unread,
Aug 24, 2014, 3:26:47 AM8/24/14
to mobile-c...@googlegroups.com
Maybe a patch a simple as this would do the trick?

// pseudocode in CBLReplication.m

if (some_user_flag_wants_notification_on_main_thread) {
dispatch_async(dispatch_get_main_queue(),^{
// post the notification on the main thread
// which is already running in its own runloop
}
} else {

// just post the notification the normal way on the current thread
// which may or may not be running in its own runloop
}

Would that be reasonable?

- Michael


On Sat, 2014-08-23 at 23:16 -0700, Jens Alfke wrote:
>

Jens Alfke

unread,
Aug 24, 2014, 7:25:42 AM8/24/14
to mobile-c...@googlegroups.com
On Aug 24, 2014, at 12:02 AM, Michael R. Hines <mic...@hinespot.com> wrote:

Is it possible for CBL to use "distributed" notifications? Could we get
CBL to post a notification to the distributed notification center and
then receive them on the main thread instead of the current thread?

Distributed notifications are for notifying other processes; you don't need them for other threads.

If we could do that, then I wouldn't have to use the runloop and those
notifications could be processed on another thread that *does* have a
runloop?

It wouldn't be appropriate to deliver the notifications on another thread because the objects involved in the notifications (i.e. the CBLReplications) would not be safe to use on that thread.

If you want your replication notifications delivered on the main thread, then you should create the replication on that thread.

—Jens
Reply all
Reply to author
Forward
0 new messages