0
votes

I wrote pouchdb sync (in Angular app) with remote db that send remote changes to the app.

I understood according to PouchDb documentation, that data should be synchronized by PouchDb.sync between local IndexedDb and remote server. After that it will be gotten by second client.

This is the code I used for the Sync:

export const appDataDbSyncArgs: IDbSyncArguments = {
    localDbName: "app_data",
    remoteDbUrl: "http://localhost:4984/app_data",    
    syncOptions: {
        live: true,
        retry: true,
        since: 0,
        batch_size: 1,
        batches_limit: 1
    }
};


PouchDB.replicate(remoteDbUrl, localDbName)
        .on("active", () => {
            console.log("replication is active");
            const replicationStartedMessage = applyMessageType({}, replicationStarted);
            messenger.postMessage(replicationStartedMessage);
        })
        .on("complete", info => {
            console.log("%cReplication has been completed.", "color: lightgreen; font-size: 20px;");
            const replicationCompleteMessage = applyMessageType(info, replicationComplete);
            messenger.postMessage(replicationCompleteMessage);

            PouchDB.sync(localDbName, remoteDbUrl, syncOptions)
                .on("change", changeInfo => {
                    console.log("%cSync changes", "color: green; font-size: 20px;");
                    const changesInfoMessage = applyMessageType(changeInfo, syncChanges);
                    messenger.postMessage(changesInfoMessage);
                })
                .on("error", err => {
                    console.log("sync error", err);
                    const errorMessage = applyMessageType(err, syncError);
                    messenger.postMessage(errorMessage);

                })
                .on("paused", err => {
                    console.log("sync error (paused)", err);                

                })
                .on("active", () => {
                    console.log("sync active");

                })
                .on("denied", err => {
                    console.log("sync error (denied)", err);        

                })
                .on("complete", info => {
                    console.log("sync complete", info);                   

                });
        })
        .on("error", err => {
            console.log("replication error", err);
            const replicationErrorMessage = applyMessageType(err, replicationError);
            messenger.postMessage(replicationErrorMessage);
        });

And this is the code I used for saving data:

protected _addDocument<T> (id: string, document: PutDocument<{} & T>): Observable<Response> {
        document['_id'] = id;
        //document._rev = null;
        return fromPromise(this._db.put<T>(document))
            .pipe(
                take(1) 
            );
    }

// Where this._db = new PouchDB(localDbName);

It saves the data to IndexedDb immediately, but it doesn't save it in the remote db. Sometimes the data come to remote db after 5-10 minutes or more. Sometimes immediately. But if the data comes to remote db, or I I change data in remote server, pouchDb fire "onChange" event and the second client gets it in the application.

But I need that data saved in IndexedDb will be immediately saved in remote db.

1

1 Answers

1
votes

This is expected behavior. CouchDB, and by extension PouchDB, are "eventually consistent." This means that data across nodes is guaranteed to become consistent eventually, but there are no guarantees as to how quickly. You should design your apps with this in mind.

Having said that, there may be some things you can do to help increase the chances that data is replicated faster. In particular, look at the options for replication in PouchDB.

Of particular interest, based on your description, are the retry, and back_off_function options. If PouchDB detects that you're offline, it will start introducing delays, up to 10 minutes, between replications. That may be what you're experiencing.

You could consider disabling the retry option (and either manually or programmatically re-start replication when you detect your client is back online), or write a custom back off function, to limit the maximum time to something you're comfortable with.