From 0c5441b17636b9471175d84460aecb278feb37f4 Mon Sep 17 00:00:00 2001 From: George Gevoian Date: Mon, 15 Aug 2022 12:52:38 -0700 Subject: [PATCH] (core) Add unquarantine command to admin CLI Summary: Adds a CLI command to un-quarantine an active document. Also tweaks the name of related environment variable to avoid a naming conflict. Test Plan: Server test. Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D3583 --- app/gen-server/lib/DocWorkerMap.ts | 8 ++++++++ app/gen-server/lib/Housekeeper.ts | 6 +++--- app/server/lib/DocApi.ts | 11 ++++++++--- app/server/lib/DocWorkerMap.ts | 4 ++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/gen-server/lib/DocWorkerMap.ts b/app/gen-server/lib/DocWorkerMap.ts index 20898ba4..8a694fd3 100644 --- a/app/gen-server/lib/DocWorkerMap.ts +++ b/app/gen-server/lib/DocWorkerMap.ts @@ -141,6 +141,10 @@ class DummyDocWorkerMap implements IDocWorkerMap { // nothing to do } + public async removeDocGroup(docId: string): Promise { + // nothing to do + } + public getRedisClient() { return null; } @@ -525,6 +529,10 @@ export class DocWorkerMap implements IDocWorkerMap { await this._client.setAsync(`doc-${docId}-group`, docGroup); } + public async removeDocGroup(docId: string): Promise { + await this._client.delAsync(`doc-${docId}-group`); + } + public getRedisClient(): RedisClient { return this._client; } diff --git a/app/gen-server/lib/Housekeeper.ts b/app/gen-server/lib/Housekeeper.ts index baf33d7f..ab4b16aa 100644 --- a/app/gen-server/lib/Housekeeper.ts +++ b/app/gen-server/lib/Housekeeper.ts @@ -166,12 +166,12 @@ export class Housekeeper { // actions. // // Optionally accepts a `group` query param for updating the document's group prior - // to moving. This is useful for controlling which worker group the document is assigned - // a worker from. + // to moving. A blank string unsets the current group, if any. This is useful for controlling + // which worker group the document is assigned a worker from. app.post('/api/housekeeping/docs/:docId/assign', this._withSupport(async (req, docId, headers) => { const url = new URL(await this._server.getHomeUrlByDocId(docId, `/api/docs/${docId}/assign`)); const group = optStringParam(req.query.group); - if (group) { url.searchParams.set('group', group); } + if (group !== undefined) { url.searchParams.set('group', group); } return fetch(url.toString(), { method: 'POST', headers, diff --git a/app/server/lib/DocApi.ts b/app/server/lib/DocApi.ts index 42673d8c..fcc82999 100644 --- a/app/server/lib/DocApi.ts +++ b/app/server/lib/DocApi.ts @@ -601,12 +601,17 @@ export class DocWorkerApi { // is freed up for reassignment, otherwise false. // // Optionally accepts a `group` query param for updating the document's group prior - // to (possible) reassignment. (Note: Requires special permit.) + // to (possible) reassignment. A blank string unsets the current group, if any. + // (Requires a special permit.) this._app.post('/api/docs/:docId/assign', canEdit, throttled(async (req, res) => { const docId = getDocId(req); const group = optStringParam(req.query.group); - if (group && req.specialPermit?.action === 'assign-doc') { - await this._docWorkerMap.updateDocGroup(docId, group); + if (group !== undefined && req.specialPermit?.action === 'assign-doc') { + if (group.trim() === '') { + await this._docWorkerMap.removeDocGroup(docId); + } else { + await this._docWorkerMap.updateDocGroup(docId, group); + } } const status = await this._docWorkerMap.getDocWorker(docId); if (!status) { res.json(false); return; } diff --git a/app/server/lib/DocWorkerMap.ts b/app/server/lib/DocWorkerMap.ts index 9ff09128..870b1b0f 100644 --- a/app/server/lib/DocWorkerMap.ts +++ b/app/server/lib/DocWorkerMap.ts @@ -66,8 +66,12 @@ export interface IDocWorkerMap extends IPermitStores, IElectionStore, IChecksumS getAssignments(workerId: string): Promise; getWorkerGroup(workerId: string): Promise; + getDocGroup(docId: string): Promise; + updateDocGroup(docId: string, docGroup: string): Promise; + removeDocGroup(docId: string): Promise; + getRedisClient(): RedisClient|null; }