Skip to content

Commit b1ba513

Browse files
committed
fix(move): Extend move operaiton lock automatically
1 parent b7f0aa6 commit b1ba513

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

lib/api/messages.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,34 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti
242242
let lockKey = ['mbwr', mailbox.toString()].join(':');
243243

244244
let lock;
245+
let extendLockIntervalTimer = null;
245246

246247
try {
247-
lock = await server.lock.waitAcquireLock(lockKey, 60 * 60 * 1000, 1 * 60 * 1000);
248+
const LOCK_TTL = 2 * 60 * 1000;
249+
250+
lock = await server.lock.waitAcquireLock(lockKey, LOCK_TTL, 1 * 60 * 1000);
248251
if (!lock.success) {
249252
throw new Error('Failed to get folder write lock');
250253
}
254+
log.verbose(
255+
'API',
256+
'Acquired lock for moving messages user=%s mailbox=%s message=%s moveTo=%s lock=%s',
257+
user.toString(),
258+
mailbox.toString(),
259+
message,
260+
moveTo,
261+
lock.id
262+
);
263+
extendLockIntervalTimer = setInterval(() => {
264+
server.lock
265+
.extendLock(lock, LOCK_TTL)
266+
.then(info => {
267+
log.verbose('API', `Lock extended lock=${info.id} result=${info.success ? 'yes' : 'no'}`);
268+
})
269+
.catch(err => {
270+
log.verbose('API', 'Failed to extend lock lock=%s error=%s', lock?.id, err.message);
271+
});
272+
}, Math.round(LOCK_TTL * 0.8));
251273
} catch (err) {
252274
res.status(500);
253275
return res.json({
@@ -272,6 +294,7 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler, setti
272294
code: err.code
273295
});
274296
} finally {
297+
clearInterval(extendLockIntervalTimer);
275298
await server.lock.releaseLock(lock);
276299
}
277300

lib/handlers/on-expunge.js

+40-1
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ module.exports = (server, messageHandler) => (mailbox, update, session, callback
7474
);
7575
};
7676

77+
const LOCK_TTL = 2 * 60 * 1000;
7778
let lockKey = ['mbwr', mailboxData._id.toString()].join(':');
78-
server.lock.waitAcquireLock(lockKey, 60 * 60 * 1000, 1 * 60 * 1000, (err, lock) => {
79+
server.lock.waitAcquireLock(lockKey, LOCK_TTL, 1 * 60 * 1000, (err, lock) => {
7980
if (err) {
8081
return callback(err);
8182
}
@@ -84,12 +85,48 @@ module.exports = (server, messageHandler) => (mailbox, update, session, callback
8485
return callback(null, new Error('Failed to get folder write lock'));
8586
}
8687

88+
server.logger.debug(
89+
{
90+
tnx: 'MOVE'
91+
},
92+
'Acquired lock for deleting messages user=%s mailbox=%s message=%s lock=%s',
93+
session.user.id.toString(),
94+
mailbox.toString(),
95+
mailboxData._id.toString(),
96+
lock.id
97+
);
98+
99+
let extendLockIntervalTimer = setInterval(() => {
100+
server.lock
101+
.extendLock(lock, LOCK_TTL)
102+
.then(info => {
103+
server.logger.debug(
104+
{
105+
tnx: 'MOVE'
106+
},
107+
`Lock extended lock=${info.id} result=${info.success ? 'yes' : 'no'}`
108+
);
109+
})
110+
.catch(err => {
111+
server.logger.debug(
112+
{
113+
tnx: 'MOVE',
114+
err
115+
},
116+
'Failed to extend lock lock=%s error=%s',
117+
lock?.id,
118+
err.message
119+
);
120+
});
121+
}, Math.round(LOCK_TTL * 0.8));
122+
87123
// fetch entire messages as these need to be copied to the archive
88124
let cursor = db.database.collection('messages').find(query).sort({ uid: 1 }).maxTimeMS(consts.DB_MAX_TIME_MESSAGES);
89125

90126
let processNext = () => {
91127
cursor.next((err, messageData) => {
92128
if (err) {
129+
clearInterval(extendLockIntervalTimer);
93130
return server.lock.releaseLock(lock, () => {
94131
updateQuota(() => callback(err));
95132
});
@@ -111,6 +148,7 @@ module.exports = (server, messageHandler) => (mailbox, update, session, callback
111148
]
112149
});
113150
}
151+
clearInterval(extendLockIntervalTimer);
114152
return server.lock.releaseLock(lock, () => {
115153
updateQuota(() => callback(null, true));
116154
});
@@ -140,6 +178,7 @@ module.exports = (server, messageHandler) => (mailbox, update, session, callback
140178
logdata._code = err.code;
141179
logdata._response = err.response;
142180
server.loggelf(logdata);
181+
clearInterval(extendLockIntervalTimer);
143182
return cursor.close(() => server.lock.releaseLock(lock, () => updateQuota(() => callback(err))));
144183
}
145184

0 commit comments

Comments
 (0)