@@ -6,6 +6,7 @@ import PouchDB from 'pouchdb-http';
6
6
import * as npm from './npm.js' ;
7
7
import log from './log.js' ;
8
8
import ms from 'ms' ;
9
+ import cargo from 'async/cargo' ;
9
10
import queue from 'async/queue' ;
10
11
11
12
log . info ( '🗿 npm ↔️ Algolia replication starts ⛷ 🐌 🛰' ) ;
@@ -15,7 +16,6 @@ const defaultOptions = {
15
16
include_docs : true , // eslint-disable-line camelcase
16
17
conflicts : false ,
17
18
attachments : false ,
18
- return_docs : false , // eslint-disable-line camelcase
19
19
} ;
20
20
21
21
let loopStart = Date . now ( ) ;
@@ -105,6 +105,7 @@ async function bootstrap(state) {
105
105
. allDocs ( {
106
106
...defaultOptions ,
107
107
...options ,
108
+ return_docs : false , // eslint-disable-line camelcase
108
109
limit : c . bootstrapConcurrency ,
109
110
} )
110
111
. then ( res => {
@@ -146,38 +147,57 @@ async function moveToProduction() {
146
147
await client . deleteIndex ( c . bootstrapIndexName ) ;
147
148
}
148
149
149
- function replicate ( { seq } ) {
150
+ async function replicate ( { seq } ) {
150
151
log . info (
151
152
'🐌 Replicate: Asking for %d changes since sequence %d' ,
152
153
c . replicateConcurrency ,
153
154
seq
154
155
) ;
155
156
156
- return db
157
- . changes ( {
157
+ const { seq : npmSeqToReach } = await npm . info ( ) ;
158
+
159
+ return new Promise ( ( resolve , reject ) => {
160
+ const changes = db . changes ( {
158
161
...defaultOptions ,
159
162
since : seq ,
160
- limit : c . replicateConcurrency ,
161
- } )
162
- . then ( res =>
163
- saveDocs ( { docs : res . results , index : mainIndex } )
163
+ batch_size : c . replicateConcurrency , // eslint-disable-line camelcase
164
+ live : true ,
165
+ return_docs : true , // eslint-disable-line camelcase
166
+ } ) ;
167
+
168
+ const q = cargo ( ( docs , done ) => {
169
+ saveDocs ( { docs, index : mainIndex } )
170
+ . then ( ( ) => infoChange ( docs [ docs . length - 1 ] . seq , 1 , '🐌' ) )
164
171
. then ( ( ) =>
165
172
stateManager . save ( {
166
- seq : res . last_seq ,
173
+ seq : docs [ docs . length - 1 ] . seq ,
167
174
} )
168
175
)
169
- . then ( ( ) => infoChange ( res . last_seq , res . results . length , '🐌' ) )
170
- . then ( ( ) => {
171
- if ( res . results . length < c . replicateConcurrency ) {
172
- log . info ( '🐌 Replicate: done' ) ;
173
- return true ;
176
+ . then ( ( { seq : lastDocSeq } ) => {
177
+ if ( lastDocSeq >= npmSeqToReach ) {
178
+ log . info ( '🐌 We reached the npm current sequence' ) ;
179
+ changes . cancel ( ) ;
174
180
}
175
-
176
- return replicate ( {
177
- seq : res . last_seq ,
178
- } ) ;
179
181
} )
180
- ) ;
182
+ . then ( done )
183
+ . catch ( done ) ;
184
+ } , c . replicateConcurrency ) ;
185
+
186
+ changes . on ( 'change' , async change => {
187
+ if ( change . deleted === true ) {
188
+ await mainIndex . deleteObject ( change . id ) ;
189
+ log . info ( `🐌 Deleted ${ change . id } ` ) ;
190
+ }
191
+
192
+ q . push ( change , err => {
193
+ if ( err ) {
194
+ reject ( err ) ;
195
+ }
196
+ } ) ;
197
+ } ) ;
198
+ changes . on ( 'complete' , resolve ) ;
199
+ changes . on ( 'error' , reject ) ;
200
+ } ) ;
181
201
}
182
202
183
203
function watch ( { seq } ) {
@@ -191,7 +211,7 @@ function watch({ seq }) {
191
211
since : seq ,
192
212
live : true ,
193
213
limit : undefined ,
194
- return_docs : false , // eslint-disable-line camelcase
214
+ return_docs : true , // eslint-disable-line camelcase
195
215
} ) ;
196
216
197
217
const q = queue ( ( change , done ) => {
@@ -226,8 +246,16 @@ function watch({ seq }) {
226
246
. catch ( done ) ;
227
247
} , 1 ) ;
228
248
229
- changes . on ( 'change' , change => {
230
- q . push ( change ) ;
249
+ changes . on ( 'change' , async change => {
250
+ if ( change . deleted === true ) {
251
+ await mainIndex . deleteObject ( change . id ) ;
252
+ log . info ( `🛰 Deleted ${ change . id } ` ) ;
253
+ }
254
+ q . push ( change , err => {
255
+ if ( err ) {
256
+ reject ( err ) ;
257
+ }
258
+ } ) ;
231
259
} ) ;
232
260
changes . on ( 'error' , reject ) ;
233
261
} ) ;
0 commit comments