use write lock for move api

This commit is contained in:
Andris Reinman 2021-07-05 22:31:25 +03:00
parent 9419e832cc
commit 864fa8d8b6
3 changed files with 29 additions and 1 deletions

6
api.js
View file

@ -21,6 +21,7 @@ const os = require('os');
const util = require('util');
const ObjectID = require('mongodb').ObjectID;
const tls = require('tls');
const Lock = require('ioredfour');
const acmeRoutes = require('./lib/api/acme');
const usersRoutes = require('./lib/api/users');
@ -498,6 +499,11 @@ module.exports = done => {
server.loggelf = message => loggelf(message);
server.lock = new Lock({
redis: db.redis,
namespace: 'mail'
});
acmeRoutes(db, server);
usersRoutes(db, server, userHandler);
addressesRoutes(db, server, userHandler);

View file

@ -121,7 +121,7 @@ let createInterface = (ifaceOptions, callback) => {
server.lock = new Lock({
redis: db.redis,
namespace: 'imap'
namespace: 'mail'
});
// setup command handlers for the server instance

View file

@ -172,6 +172,25 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler) => {
if (moveTo) {
let info;
let lockKey = ['mbwr', mailbox.toString()].join(':');
let lock;
try {
lock = await server.lock.waitAcquireLock(lockKey, 5 * 60 * 1000, 1 * 60 * 1000);
if (!lock.success) {
throw new Error('Failed to get folder write lock');
}
} catch (err) {
res.status(500);
res.json({
error: err.message,
code: err.code || 'LockFail'
});
return next();
}
try {
let data = await moveMessage({
user,
@ -188,6 +207,8 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler) => {
code: err.code
});
return next();
} finally {
await server.lock.releaseLock(lock);
}
if (!info || !info.destinationUid || !info.destinationUid.length) {
@ -204,6 +225,7 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler) => {
mailbox: moveTo,
id: info && info.sourceUid && info.sourceUid.map((uid, i) => [uid, info.destinationUid && info.destinationUid[i]])
});
return next();
}