Skip to content

Commit 8aefb7e

Browse files
authored
Merge pull request #8342 from romayalon/romy-versioning-con-put-same-key
NC | Versioning | Concurrent put of same key
2 parents 5a60fca + 7e31be7 commit 8aefb7e

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ config.NSFS_REMOVE_PARTS_ON_COMPLETE = true;
764764
config.NSFS_BUF_POOL_WARNING_TIMEOUT = 2 * 60 * 1000;
765765
config.NSFS_SEM_WARNING_TIMEOUT = 10 * 60 * 1000;
766766
// number of rename retries in case of deleted destination directory
767-
config.NSFS_RENAME_RETRIES = 3;
767+
config.NSFS_RENAME_RETRIES = 10;
768768

769769
config.NSFS_VERSIONING_ENABLED = true;
770770
config.NSFS_UPDATE_ISSUES_REPORT_ENABLED = true;

src/sdk/namespace_fs.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,9 +1473,10 @@ class NamespaceFS {
14731473
break;
14741474
} catch (err) {
14751475
retries -= 1;
1476-
if (retries <= 0 || !native_fs_utils.should_retry_link_unlink(is_gpfs, err)) throw err;
1477-
dbg.warn(`NamespaceFS._move_to_dest_version retrying retries=${retries}` +
1476+
const should_retry = native_fs_utils.should_retry_link_unlink(is_gpfs, err);
1477+
dbg.warn(`NamespaceFS._move_to_dest_version retrying retries=${retries} should_retry=${should_retry}` +
14781478
` new_ver_tmp_path=${new_ver_tmp_path} latest_ver_path=${latest_ver_path}`, err);
1479+
if (!should_retry || retries <= 0) throw err;
14791480
} finally {
14801481
if (gpfs_options) await this._close_files_gpfs(fs_context, gpfs_options.move_to_dst, open_mode);
14811482
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* Copyright (C) 2016 NooBaa */
2+
'use strict';
3+
4+
const path = require('path');
5+
const P = require('../../../util/promise');
6+
const fs_utils = require('../../../util/fs_utils');
7+
const NamespaceFS = require('../../../sdk/namespace_fs');
8+
const buffer_utils = require('../../../util/buffer_utils');
9+
const { TMP_PATH } = require('../../system_tests/test_utils');
10+
const endpoint_stats_collector = require('../../../sdk/endpoint_stats_collector');
11+
12+
function make_dummy_object_sdk(nsfs_config, uid, gid) {
13+
return {
14+
requesting_account: {
15+
nsfs_account_config: nsfs_config && {
16+
uid: uid || process.getuid(),
17+
gid: gid || process.getgid(),
18+
backend: '',
19+
}
20+
},
21+
abort_controller: new AbortController(),
22+
throw_if_aborted() {
23+
if (this.abort_controller.signal.aborted) throw new Error('request aborted signal');
24+
}
25+
};
26+
}
27+
28+
const DUMMY_OBJECT_SDK = make_dummy_object_sdk(true);
29+
describe('test versioning concurrency', () => {
30+
const tmp_fs_path = path.join(TMP_PATH, 'test_versioning_concurrency');
31+
32+
const nsfs = new NamespaceFS({
33+
bucket_path: tmp_fs_path,
34+
bucket_id: '1',
35+
namespace_resource_id: undefined,
36+
access_mode: undefined,
37+
versioning: 'ENABLED',
38+
force_md5_etag: false,
39+
stats: endpoint_stats_collector.instance(),
40+
});
41+
42+
beforeEach(async () => {
43+
await fs_utils.create_fresh_path(tmp_fs_path);
44+
});
45+
46+
afterEach(async () => {
47+
await fs_utils.folder_delete(tmp_fs_path);
48+
});
49+
50+
it('multiple puts of the same key', async () => {
51+
const bucket = 'bucket1';
52+
const key = 'key1';
53+
for (let i = 0; i < 5; i++) {
54+
const random_data = Buffer.from(String(i));
55+
const body = buffer_utils.buffer_to_read_stream(random_data);
56+
nsfs.upload_object({ bucket: bucket, key: key, source_stream: body }, DUMMY_OBJECT_SDK).catch(err => console.log('multiple puts of the same key error - ', err));
57+
}
58+
await P.delay(1000);
59+
const versions = await nsfs.list_object_versions({ bucket: bucket }, DUMMY_OBJECT_SDK);
60+
expect(versions.objects.length).toBe(5);
61+
});
62+
});

src/util/native_fs_utils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ async function safe_unlink_gpfs(fs_context, to_delete_path, to_delete_file, dir_
239239
function should_retry_link_unlink(is_gpfs, err) {
240240
return is_gpfs ?
241241
[gpfs_link_unlink_retry_err, gpfs_unlink_retry_catch].includes(err.code) :
242-
[posix_link_retry_err, posix_unlink_retry_err].includes(err.message);
242+
[posix_link_retry_err, posix_unlink_retry_err].includes(err.message) ||
243+
['EEXIST'].includes(err.code);
243244
}
244245

245246
////////////////////////

0 commit comments

Comments
 (0)