Promisify ProjectHistoryClient, ProjectHistoryApp, SyncTests and SendingUpdatesTests (#28890)
GitOrigin-RevId: 7bf26c6ed1a172c6506449a821d4e43f424a72bd
This commit is contained in:
committed by
Copybot
parent
3a35b8680e
commit
267fc5393a
@@ -23,7 +23,7 @@ describe('Deleting project', function () {
|
||||
.get(`/api/projects/${this.historyId}/latest/history`)
|
||||
.replyWithFile(200, fixture('chunks/0-3.json'))
|
||||
MockHistoryStore().delete(`/api/projects/${this.historyId}`).reply(204)
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
})
|
||||
|
||||
describe('when the project has no pending updates', function () {
|
||||
@@ -34,16 +34,13 @@ describe('Deleting project', function () {
|
||||
|
||||
describe('when the project has pending updates', function () {
|
||||
beforeEach(async function () {
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(this.projectId, {
|
||||
await ProjectHistoryClient.pushRawUpdate(this.projectId, {
|
||||
pathname: '/main.tex',
|
||||
docLines: 'hello',
|
||||
doc: this.docId,
|
||||
meta: { userId: this.userId, ts: new Date() },
|
||||
})
|
||||
await ProjectHistoryClient.promises.setFirstOpTimestamp(
|
||||
this.projectId,
|
||||
Date.now()
|
||||
)
|
||||
await ProjectHistoryClient.setFirstOpTimestamp(this.projectId, Date.now())
|
||||
await ProjectHistoryClient.deleteProject(this.projectId)
|
||||
})
|
||||
|
||||
@@ -53,9 +50,7 @@ describe('Deleting project', function () {
|
||||
})
|
||||
|
||||
it('clears the first op timestamp', async function () {
|
||||
const ts = await ProjectHistoryClient.promises.getFirstOpTimestamp(
|
||||
this.projectId
|
||||
)
|
||||
const ts = await ProjectHistoryClient.getFirstOpTimestamp(this.projectId)
|
||||
expect(ts).to.be.null
|
||||
})
|
||||
})
|
||||
|
||||
@@ -24,7 +24,7 @@ function createMockBlob(historyId, content) {
|
||||
|
||||
describe('Diffs', function () {
|
||||
beforeEach(async function () {
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
this.historyId = new ObjectId().toString()
|
||||
this.projectId = new ObjectId().toString()
|
||||
@@ -39,7 +39,7 @@ describe('Diffs', function () {
|
||||
overleaf: { history: { id: this.historyId } },
|
||||
})
|
||||
|
||||
await ProjectHistoryClient.promises.initializeProject(this.historyId)
|
||||
await ProjectHistoryClient.initializeProject(this.historyId)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('DiscardingUpdates', function () {
|
||||
beforeEach(async function () {
|
||||
this.timestamp = new Date()
|
||||
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
this.user_id = new ObjectId().toString()
|
||||
this.project_id = new ObjectId().toString()
|
||||
this.doc_id = new ObjectId().toString()
|
||||
@@ -22,7 +22,7 @@ describe('DiscardingUpdates', function () {
|
||||
MockWeb()
|
||||
.get(`/project/${this.project_id}/details`)
|
||||
.reply(200, { name: 'Test Project' })
|
||||
await ProjectHistoryClient.promises.initializeProject(this.project_id)
|
||||
await ProjectHistoryClient.initializeProject(this.project_id)
|
||||
})
|
||||
|
||||
it('should discard updates', async function () {
|
||||
@@ -32,7 +32,7 @@ describe('DiscardingUpdates', function () {
|
||||
doc: this.doc_id,
|
||||
meta: { user_id: this.user_id, ts: new Date() },
|
||||
}
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(this.project_id, update)
|
||||
await ProjectHistoryClient.promises.flushProject(this.project_id)
|
||||
await ProjectHistoryClient.pushRawUpdate(this.project_id, update)
|
||||
await ProjectHistoryClient.flushProject(this.project_id)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ const sha = data => crypto.createHash('sha1').update(data).digest('hex')
|
||||
|
||||
describe('FileTree Diffs', function () {
|
||||
beforeEach(async function () {
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
this.historyId = new ObjectId().toString()
|
||||
this.projectId = new ObjectId().toString()
|
||||
@@ -28,7 +28,7 @@ describe('FileTree Diffs', function () {
|
||||
overleaf: { history: { id: this.historyId } },
|
||||
})
|
||||
|
||||
await ProjectHistoryClient.promises.initializeProject(this.historyId)
|
||||
await ProjectHistoryClient.initializeProject(this.historyId)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
@@ -17,7 +17,7 @@ describe('Flushing old queues', function () {
|
||||
beforeEach(async function () {
|
||||
this.timestamp = new Date()
|
||||
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
this.projectId = new ObjectId().toString()
|
||||
this.docId = new ObjectId().toString()
|
||||
this.fileId = new ObjectId().toString()
|
||||
@@ -45,7 +45,7 @@ describe('Flushing old queues', function () {
|
||||
},
|
||||
},
|
||||
})
|
||||
await ProjectHistoryClient.promises.initializeProject(historyId)
|
||||
await ProjectHistoryClient.initializeProject(historyId)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
@@ -68,11 +68,8 @@ describe('Flushing old queues', function () {
|
||||
doc: this.docId,
|
||||
meta: { user_id: this.user_id, ts: new Date() },
|
||||
}
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(
|
||||
this.projectId,
|
||||
update
|
||||
)
|
||||
await ProjectHistoryClient.promises.setFirstOpTimestamp(
|
||||
await ProjectHistoryClient.pushRawUpdate(this.projectId, update)
|
||||
await ProjectHistoryClient.setFirstOpTimestamp(
|
||||
this.projectId,
|
||||
Date.now() - 24 * 3600 * 1000
|
||||
)
|
||||
@@ -131,11 +128,8 @@ describe('Flushing old queues', function () {
|
||||
doc: this.docId,
|
||||
meta: { user_id: this.user_id, ts: new Date() },
|
||||
}
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(
|
||||
this.projectId,
|
||||
update
|
||||
)
|
||||
await ProjectHistoryClient.promises.setFirstOpTimestamp(
|
||||
await ProjectHistoryClient.pushRawUpdate(this.projectId, update)
|
||||
await ProjectHistoryClient.setFirstOpTimestamp(
|
||||
this.projectId,
|
||||
Date.now() - 60 * 1000
|
||||
)
|
||||
@@ -177,11 +171,8 @@ describe('Flushing old queues', function () {
|
||||
doc: this.docId,
|
||||
meta: { user_id: this.user_id, ts: new Date() },
|
||||
}
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(
|
||||
this.projectId,
|
||||
update
|
||||
)
|
||||
await ProjectHistoryClient.promises.setFirstOpTimestamp(
|
||||
await ProjectHistoryClient.pushRawUpdate(this.projectId, update)
|
||||
await ProjectHistoryClient.setFirstOpTimestamp(
|
||||
this.projectId,
|
||||
Date.now() - 60 * 1000
|
||||
)
|
||||
@@ -241,16 +232,8 @@ describe('Flushing old queues', function () {
|
||||
meta: { user_id: this.user_id, ts: new Date() },
|
||||
}
|
||||
this.startDate = Date.now()
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(
|
||||
this.projectId,
|
||||
update
|
||||
)
|
||||
await new Promise((resolve, reject) => {
|
||||
ProjectHistoryClient.clearFirstOpTimestamp(this.projectId, err => {
|
||||
if (err) reject(err)
|
||||
else resolve()
|
||||
})
|
||||
})
|
||||
await ProjectHistoryClient.pushRawUpdate(this.projectId, update)
|
||||
await ProjectHistoryClient.clearFirstOpTimestamp(this.projectId)
|
||||
})
|
||||
|
||||
it('flushes the project history queue anyway', async function () {
|
||||
@@ -266,15 +249,9 @@ describe('Flushing old queues', function () {
|
||||
'made calls to history service to store updates'
|
||||
)
|
||||
|
||||
const result = await new Promise((resolve, reject) => {
|
||||
ProjectHistoryClient.getFirstOpTimestamp(
|
||||
this.projectId,
|
||||
(err, result) => {
|
||||
if (err) reject(err)
|
||||
else resolve(result)
|
||||
}
|
||||
)
|
||||
})
|
||||
const result = await ProjectHistoryClient.getFirstOpTimestamp(
|
||||
this.projectId
|
||||
)
|
||||
expect(result).to.be.null
|
||||
})
|
||||
})
|
||||
|
||||
@@ -19,14 +19,13 @@ describe('GetChangesInChunkSince', function () {
|
||||
beforeEach(async function () {
|
||||
projectId = new ObjectId().toString()
|
||||
historyId = new ObjectId().toString()
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
MockHistoryStore().post('/api/projects').reply(200, {
|
||||
projectId: historyId,
|
||||
})
|
||||
|
||||
const olProject =
|
||||
await ProjectHistoryClient.promises.initializeProject(historyId)
|
||||
const olProject = await ProjectHistoryClient.initializeProject(historyId)
|
||||
MockWeb()
|
||||
.get(`/project/${projectId}/details`)
|
||||
.reply(200, {
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('Health Check', function () {
|
||||
const historyId = new ObjectId().toString()
|
||||
settings.history.healthCheck = { project_id: projectId }
|
||||
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
MockHistoryStore().post('/api/projects').reply(200, {
|
||||
projectId: historyId,
|
||||
@@ -43,7 +43,7 @@ describe('Health Check', function () {
|
||||
},
|
||||
})
|
||||
|
||||
await ProjectHistoryClient.promises.initializeProject(historyId)
|
||||
await ProjectHistoryClient.initializeProject(historyId)
|
||||
})
|
||||
|
||||
it('should respond to the health check', async function () {
|
||||
|
||||
@@ -12,14 +12,14 @@ const fixture = path => new URL(`../fixtures/${path}`, import.meta.url)
|
||||
|
||||
describe('Labels', function () {
|
||||
beforeEach(async function () {
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
this.historyId = new ObjectId().toString()
|
||||
MockHistoryStore().post('/api/projects').reply(200, {
|
||||
projectId: this.historyId,
|
||||
})
|
||||
|
||||
const olProject = await ProjectHistoryClient.promises.initializeProject(
|
||||
const olProject = await ProjectHistoryClient.initializeProject(
|
||||
this.historyId
|
||||
)
|
||||
this.project_id = new ObjectId().toString()
|
||||
|
||||
@@ -13,14 +13,14 @@ const fixture = path => new URL(`../fixtures/${path}`, import.meta.url)
|
||||
|
||||
describe('LatestSnapshot', function () {
|
||||
beforeEach(async function () {
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
this.historyId = new ObjectId().toString()
|
||||
MockHistoryStore().post('/api/projects').reply(200, {
|
||||
projectId: this.historyId,
|
||||
})
|
||||
|
||||
const v1Project = await ProjectHistoryClient.promises.initializeProject(
|
||||
const v1Project = await ProjectHistoryClient.initializeProject(
|
||||
this.historyId
|
||||
)
|
||||
this.projectId = new ObjectId().toString()
|
||||
|
||||
@@ -12,14 +12,14 @@ const fixture = path => new URL(`../fixtures/${path}`, import.meta.url)
|
||||
|
||||
describe('ReadSnapshot', function () {
|
||||
beforeEach(async function () {
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
this.historyId = new ObjectId().toString()
|
||||
MockHistoryStore().post('/api/projects').reply(200, {
|
||||
projectId: this.historyId,
|
||||
})
|
||||
|
||||
const v1Project = await ProjectHistoryClient.promises.initializeProject(
|
||||
const v1Project = await ProjectHistoryClient.initializeProject(
|
||||
this.historyId
|
||||
)
|
||||
this.projectId = new ObjectId().toString()
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('Retrying failed projects', function () {
|
||||
beforeEach(async function () {
|
||||
this.timestamp = new Date()
|
||||
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
this.project_id = new ObjectId().toString()
|
||||
this.doc_id = new ObjectId().toString()
|
||||
@@ -47,7 +47,7 @@ describe('Retrying failed projects', function () {
|
||||
},
|
||||
},
|
||||
})
|
||||
await ProjectHistoryClient.promises.initializeProject(historyId)
|
||||
await ProjectHistoryClient.initializeProject(historyId)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
@@ -71,10 +71,7 @@ describe('Retrying failed projects', function () {
|
||||
meta: { user_id: this.user_id, ts: new Date() },
|
||||
}
|
||||
|
||||
await ProjectHistoryClient.promises.pushRawUpdate(
|
||||
this.project_id,
|
||||
update
|
||||
)
|
||||
await ProjectHistoryClient.pushRawUpdate(this.project_id, update)
|
||||
await ProjectHistoryClient.setFailure({
|
||||
project_id: this.project_id,
|
||||
attempts: 1,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,13 +15,13 @@ describe('Summarized updates', function () {
|
||||
this.projectId = new ObjectId().toString()
|
||||
this.historyId = new ObjectId().toString()
|
||||
|
||||
await ProjectHistoryApp.promises.ensureRunning()
|
||||
await ProjectHistoryApp.ensureRunning()
|
||||
|
||||
MockHistoryStore().post('/api/projects').reply(200, {
|
||||
projectId: this.historyId,
|
||||
})
|
||||
|
||||
const olProject = await ProjectHistoryClient.promises.initializeProject(
|
||||
const olProject = await ProjectHistoryClient.initializeProject(
|
||||
this.historyId
|
||||
)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +1,37 @@
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS205: Consider reworking code to avoid use of IIFEs
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
import { app } from '../../../../app/js/server.js'
|
||||
import { mongoClient } from '../../../../app/js/mongodb.js'
|
||||
import { promisify } from '@overleaf/promise-utils'
|
||||
|
||||
let running = false
|
||||
let initing = false
|
||||
const callbacks = []
|
||||
let initPromise = null
|
||||
|
||||
export function ensureRunning(callback) {
|
||||
if (callback == null) {
|
||||
callback = function () {}
|
||||
}
|
||||
if (running) {
|
||||
return callback()
|
||||
} else if (initing) {
|
||||
return callbacks.push(callback)
|
||||
}
|
||||
initing = true
|
||||
callbacks.push(callback)
|
||||
app.listen(3054, '127.0.0.1', error => {
|
||||
if (error != null) {
|
||||
throw error
|
||||
}
|
||||
async function initialize() {
|
||||
try {
|
||||
await new Promise((resolve, reject) => {
|
||||
app.listen(3054, '127.0.0.1', error => {
|
||||
if (error) return reject(error)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
// Wait for mongo
|
||||
mongoClient.connect(error => {
|
||||
if (error != null) {
|
||||
throw error
|
||||
}
|
||||
running = true
|
||||
for (callback of Array.from(callbacks)) {
|
||||
callback()
|
||||
}
|
||||
})
|
||||
})
|
||||
await mongoClient.connect()
|
||||
|
||||
running = true
|
||||
} catch (error) {
|
||||
initPromise = null
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export const promises = {
|
||||
ensureRunning: promisify(ensureRunning),
|
||||
export async function ensureRunning() {
|
||||
if (running) {
|
||||
return
|
||||
}
|
||||
|
||||
if (initPromise) {
|
||||
return await initPromise
|
||||
}
|
||||
|
||||
initPromise = initialize()
|
||||
return await initPromise
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import request from 'request'
|
||||
import Settings from '@overleaf/settings'
|
||||
import RedisWrapper from '@overleaf/redis-wrapper'
|
||||
import { db } from '../../../../app/js/mongodb.js'
|
||||
import { promisify } from '@overleaf/promise-utils'
|
||||
import {
|
||||
fetchJson,
|
||||
fetchJsonWithResponse,
|
||||
@@ -19,44 +18,34 @@ export function resetDatabase(callback) {
|
||||
rclient.flushdb(callback)
|
||||
}
|
||||
|
||||
export function initializeProject(historyId, callback) {
|
||||
request.post(
|
||||
export async function initializeProject(historyId) {
|
||||
const response = await fetchJsonWithResponse(
|
||||
'http://127.0.0.1:3054/project',
|
||||
{
|
||||
url: 'http://127.0.0.1:3054/project',
|
||||
method: 'POST',
|
||||
json: { historyId },
|
||||
},
|
||||
(error, res, body) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
expect(res.statusCode).to.equal(200)
|
||||
callback(null, body.project)
|
||||
}
|
||||
)
|
||||
expect(response.response.status).to.equal(200)
|
||||
return response.json.project
|
||||
}
|
||||
|
||||
export function flushProject(projectId, options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = null
|
||||
}
|
||||
if (!options) {
|
||||
options = { allowErrors: false }
|
||||
}
|
||||
request.post(
|
||||
{
|
||||
url: `http://127.0.0.1:3054/project/${projectId}/flush`,
|
||||
},
|
||||
(error, res, body) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (!options.allowErrors) {
|
||||
expect(res.statusCode).to.equal(204)
|
||||
}
|
||||
callback(error, res)
|
||||
export async function flushProject(projectId, options = {}) {
|
||||
try {
|
||||
const response = await fetchNothing(
|
||||
`http://127.0.0.1:3054/project/${projectId}/flush`,
|
||||
{ method: 'POST' }
|
||||
)
|
||||
if (!options.allowErrors) {
|
||||
expect(response.status).to.equal(204)
|
||||
}
|
||||
)
|
||||
return { statusCode: response.status }
|
||||
} catch (error) {
|
||||
if (options.allowErrors && error instanceof RequestFailedError) {
|
||||
return { statusCode: error.response.status }
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSummarizedUpdates(projectId, query) {
|
||||
@@ -135,33 +124,29 @@ export async function getSnapshot(projectId, pathname, version, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function pushRawUpdate(projectId, update, callback) {
|
||||
rclient.rpush(
|
||||
export async function pushRawUpdate(projectId, update) {
|
||||
await rclient.rpush(
|
||||
Keys.projectHistoryOps({ project_id: projectId }),
|
||||
JSON.stringify(update),
|
||||
callback
|
||||
JSON.stringify(update)
|
||||
)
|
||||
}
|
||||
|
||||
export function setFirstOpTimestamp(projectId, timestamp, callback) {
|
||||
rclient.set(
|
||||
export async function setFirstOpTimestamp(projectId, timestamp) {
|
||||
await rclient.set(
|
||||
Keys.projectHistoryFirstOpTimestamp({ project_id: projectId }),
|
||||
timestamp,
|
||||
callback
|
||||
timestamp
|
||||
)
|
||||
}
|
||||
|
||||
export function getFirstOpTimestamp(projectId, callback) {
|
||||
rclient.get(
|
||||
Keys.projectHistoryFirstOpTimestamp({ project_id: projectId }),
|
||||
callback
|
||||
export async function getFirstOpTimestamp(projectId) {
|
||||
return await rclient.get(
|
||||
Keys.projectHistoryFirstOpTimestamp({ project_id: projectId })
|
||||
)
|
||||
}
|
||||
|
||||
export function clearFirstOpTimestamp(projectId, callback) {
|
||||
rclient.del(
|
||||
Keys.projectHistoryFirstOpTimestamp({ project_id: projectId }),
|
||||
callback
|
||||
export async function clearFirstOpTimestamp(projectId) {
|
||||
await rclient.del(
|
||||
Keys.projectHistoryFirstOpTimestamp({ project_id: projectId })
|
||||
)
|
||||
}
|
||||
|
||||
@@ -179,21 +164,15 @@ export function getQueueCounts(callback) {
|
||||
)
|
||||
}
|
||||
|
||||
export function resyncHistory(projectId, callback) {
|
||||
request.post(
|
||||
export async function resyncHistory(projectId) {
|
||||
const response = await fetchNothing(
|
||||
`http://127.0.0.1:3054/project/${projectId}/resync`,
|
||||
{
|
||||
url: `http://127.0.0.1:3054/project/${projectId}/resync`,
|
||||
json: true,
|
||||
body: { origin: { kind: 'test-origin' } },
|
||||
},
|
||||
(error, res, body) => {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
expect(res.statusCode).to.equal(204)
|
||||
callback(error)
|
||||
method: 'POST',
|
||||
json: { origin: { kind: 'test-origin' } },
|
||||
}
|
||||
)
|
||||
expect(response.status).to.equal(204)
|
||||
}
|
||||
|
||||
export async function createLabel(
|
||||
@@ -257,11 +236,3 @@ export async function deleteProject(projectId) {
|
||||
)
|
||||
expect(response.status).to.equal(204)
|
||||
}
|
||||
|
||||
export const promises = {
|
||||
initializeProject: promisify(initializeProject),
|
||||
pushRawUpdate: promisify(pushRawUpdate),
|
||||
setFirstOpTimestamp: promisify(setFirstOpTimestamp),
|
||||
getFirstOpTimestamp: promisify(getFirstOpTimestamp),
|
||||
flushProject: promisify(flushProject),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user