Is there a way to perform instant push replication?


#1

I’ve noticed in my app that has both continuous push and replication that if a user creates a document in the CBL database on iOS and immediately hits the home button to background the app then the document doesn’t get replicated.

Is there a way to force push replication to happen immediately after a document is saved?


#2

It basically does … it wakes up as soon as a document is changed. It does wait a fraction of a second to see if other docs are being changed too, so it can send them in one request to the server instead of multiple.

It’s possible that if the app is backgrounded during that brief delay, the replicator decides not to ask the OS for extra time to run, because it’s not technically in the middle of network activity. I’d have to investigate the code to make sure. Could you file an issue?

Unfortunately I don’t think there’s a way for you to change this behavior.


#3

@jens does a one shot also wait, to bundle requests?


#4

I’ve created the issue https://github.com/couchbase/couchbase-lite-ios/issues/1475.

I’m trying to use one-shot push replication instead of continuous as a work around. Will update when I’ve done some proper testing.


#5

So far so good with using one-shot push replication instead of continuous. I’ve managed to background the app even before my UI has had a chance to update the button press that caused the document change and the replication has worked.


#6

@hod.greeley: Any push replication (continuous or not) starts by finding all the changed documents and sending them immediately. The difference is that a one-shot stops after that, while the continuous one goes into the mode I described of observing changes and batching them.


#7

But am I right in thinking that during normal running of a continuous push replication there’s a small delay between a user making a document change and that change getting pushed to the sync-gateway? And this delay would not occur if you invoked a non-continuous push replication immediately after each change?

That would certainly describe the behaviour I’ve been seeing.


#8

Exactly.

I think the situation you’ve found is a bug, though — even if the replicator hasn’t sent an HTTP request yet by the time the app is backgrounded, it should still be considered active so it should request a background session so it can push the change before the app is suspended. (Did you file an issue? I haven’t caught up on new issues yet today.)


#9

#10

Looks like it didn’t quite work. To recap, my app is a react-native app and only uses the REST API. I recently altered it to not use continuous push replication, but instead after each PUT and POST it invokes a one-shot push replication. Last night I got some logs from a device which show that this doesn’t work. I’m not sure why, but maybe you just can’t rely on HTTP when the app is backgrounded?

Here’s what happened, taken from the app logs:

 2016-10-03T23:07:47Z	app gets backgrounded
 2016-10-03T23:07:47Z	at the same moment app creates a document (and writes to console.log BEFORE making the PUT request)
 2016-10-03T23:07:47Z	the new document immediately appears in the changes feed
 ... time passes, nothing happens (the log is empty)
 2016-10-04T06:04:17Z	app wakes up in background because it received a push notification (for an unrelated event)
 2016-10-04T06:04:17Z	the push replication gets invoked
 2016-10-04T06:04:17Z	the app logs that the the PUT http request (from above) has finished (almost 7 hours later)
 ... time passes again 
 2016-10-04T07:30:26Z   the push replication finishes

The document is below - you can see large difference between the sync-gateway timestamp and my apps own audit timestamp which shows when it was written the to local CBL db.

{
  "audit": {
   "user_id": "7f3b03b8-340d-4d41-80f9-d4ebec187216",
   "build_number": "269",
   "client_timestamp_utc": "2016-10-03T23:07:47Z"
  },
  "_sync": {
    "time_saved": "2016-10-04T08:30:23.354066186+01:00",
    "sequence": 378959,
    "rev": "1-44d1adbfe765e9bf0615c1f57851aff8",
  ...   

So it seems that just by backgrounding the app I managed to prevent it from invoking the push replication somehow.

I have the background modes all set:

Uploading…

And the CBLMamanger is created with option NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication.


#11

Looks like a race condition where the app got suspended after the doc was created but before the replicator started. At what point in the timeline above did you create the replication?

Turning on SyncVerbose logging would help track down when things happen…


#12

The call to being a replication happens immediately after the http PUT request returns. In the example above the line reading the push replication gets invoked shows when it actually happened in their example. So you can see a huge gap between saving a document and the push replication being invoked, even though one line of code follows the other.

It happened again last night. Save a document and immediately hit the home button and it prevents replication from starting. It doesn’t seem to matter if I have continuous replication running, or I manually invoke it.


#13

I’ll close this topic and continue discussion in the Github issue, to avoid duplication or confusion.


#14