@cloudant/couchbackup 2.7.1-SNAPSHOT.58 → 2.7.1-SNAPSHOT.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGES.md CHANGED
@@ -4,6 +4,8 @@
4
4
  - [IMPROVED] Added quiet option to backup and restore to suppress batch messages.
5
5
  - [IMPROVED] Added a preflight check for restore function to make sure that a target database is new and empty.
6
6
  - [IMPROVED] Added handling for errors reading log file.
7
+ - [IMPROVED] Split changes spooling to improve reliability on databases with
8
+ millions of documents.
7
9
 
8
10
  # 2.7.0 (2021-09-14)
9
11
  - [UPGRADED] Cloudant client dependency from `@cloudant/cloudant` to `@ibm-cloud/cloudant`.
@@ -34,6 +34,9 @@ module.exports = function(db, log, bufferSize, ee, callback) {
34
34
  let batch = 0;
35
35
  let lastSeq = null;
36
36
  const logStream = fs.createWriteStream(log);
37
+ let pending = 0;
38
+ // The number of changes to fetch per request
39
+ const limit = 100000;
37
40
 
38
41
  // send documents ids to the queue in batches of bufferSize + the last batch
39
42
  const processBuffer = function(lastOne) {
@@ -57,36 +60,52 @@ module.exports = function(db, log, bufferSize, ee, callback) {
57
60
  processBuffer(false);
58
61
  } else if (c.last_seq) {
59
62
  lastSeq = c.last_seq;
63
+ pending = c.pending;
60
64
  }
61
65
  }
62
66
  };
63
67
 
64
- // stream the changes feed to disk
65
- db.service.postChangesAsStream({ db: db.db, seq_interval: 10000 }).then(response => {
66
- response.result.pipe(liner())
67
- .on('error', function(err) {
68
- callback(err);
68
+ function getChanges(since = 0) {
69
+ debug('making changes request since ' + since);
70
+ return db.service.postChangesAsStream({ db: db.db, since: since, limit: limit, seq_interval: limit })
71
+ .then(response => {
72
+ response.result.pipe(liner())
73
+ .on('error', function(err) {
74
+ logStream.end();
75
+ callback(err);
76
+ })
77
+ .pipe(change(onChange))
78
+ .on('error', function(err) {
79
+ logStream.end();
80
+ callback(err);
81
+ })
82
+ .on('finish', function() {
83
+ processBuffer(true);
84
+ if (!lastSeq) {
85
+ logStream.end();
86
+ debug('changes request terminated before last_seq was sent');
87
+ callback(new error.BackupError('SpoolChangesError', 'Changes request terminated before last_seq was sent'));
88
+ } else {
89
+ debug(`changes request completed with last_seq: ${lastSeq} and ${pending} changes pending.`);
90
+ if (pending > 0) {
91
+ // Return the next promise
92
+ return getChanges(lastSeq);
93
+ } else {
94
+ debug('finished streaming database changes');
95
+ logStream.end(':changes_complete ' + lastSeq + '\n', 'utf8', callback);
96
+ }
97
+ }
98
+ });
69
99
  })
70
- .pipe(change(onChange))
71
- .on('error', function(err) {
72
- callback(err);
73
- })
74
- .on('finish', function() {
75
- processBuffer(true);
76
- if (!lastSeq) {
77
- logStream.end();
78
- debug('changes request terminated before last_seq was sent');
79
- callback(new error.BackupError('SpoolChangesError', 'Changes request terminated before last_seq was sent'));
80
- } else {
81
- debug('finished streaming database changes');
82
- logStream.end(':changes_complete ' + lastSeq + '\n', 'utf8', callback);
100
+ .catch(err => {
101
+ logStream.end();
102
+ if (err.status && err.status >= 400) {
103
+ callback(error.convertResponseError(err));
104
+ } else if (err.name !== 'SpoolChangesError') {
105
+ callback(new error.BackupError('SpoolChangesError', `Failed changes request - ${err.message}`));
83
106
  }
84
107
  });
85
- }).catch(err => {
86
- if (err.status && err.status >= 400) {
87
- callback(error.convertResponseError(err));
88
- } else {
89
- callback(new error.BackupError('SpoolChangesError', `Failed changes request - ${err.message}`));
90
- }
91
- });
108
+ }
109
+
110
+ getChanges();
92
111
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudant/couchbackup",
3
- "version": "2.7.1-SNAPSHOT.58",
3
+ "version": "2.7.1-SNAPSHOT.59",
4
4
  "description": "CouchBackup - command-line backup utility for Cloudant/CouchDB",
5
5
  "homepage": "https://github.com/cloudant/couchbackup",
6
6
  "repository": "https://github.com/cloudant/couchbackup.git",