Skip to content

Commit d1c3f68

Browse files
committed
Delete object version id concurrency
Signed-off-by: Romy <35330373+romayalon@users.noreply.github.com>
1 parent fb9c96c commit d1c3f68

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

src/sdk/namespace_fs.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,12 +1356,7 @@ class NamespaceFS {
13561356

13571357
await this._assign_dir_content_to_xattr(fs_context, fs_xattr, params, copy_xattr);
13581358
// when .folder exist and it's no upload flow - .folder should be deleted if it exists
1359-
try {
1360-
await nb_native().fs.unlink(fs_context, file_path);
1361-
} catch (err) {
1362-
if (err.code !== 'ENOENT') throw err;
1363-
dbg.log0(`namespace_fs._create_empty_dir_content: dir object file ${config.NSFS_FOLDER_OBJECT_NAME} was already deleted`);
1364-
}
1359+
await native_fs_utils.unlink_ignore_enoent(fs_context, file_path);
13651360
const dir_path = this._get_file_md_path(params);
13661361
const stat = await nb_native().fs.stat(fs_context, dir_path);
13671362
const upload_info = this._get_upload_info(stat, fs_xattr[XATTR_VERSION_ID]);
@@ -1916,11 +1911,7 @@ class NamespaceFS {
19161911

19171912

19181913
async _delete_single_object(fs_context, file_path, params) {
1919-
try {
1920-
await nb_native().fs.unlink(fs_context, file_path);
1921-
} catch (err) {
1922-
if (err.code !== 'ENOENT') throw err;
1923-
}
1914+
await native_fs_utils.unlink_ignore_enoent(fs_context, file_path);
19241915
await this._delete_path_dirs(file_path, fs_context);
19251916
// when deleting the data of a directory object, we need to remove the directory dir object xattr
19261917
// if the dir still exists - occurs when deleting dir while the dir still has entries in it
@@ -2777,7 +2768,7 @@ class NamespaceFS {
27772768
await native_fs_utils.safe_unlink(fs_context, file_path, version_info, gpfs_options, bucket_tmp_dir_path);
27782769
return { ...version_info, latest: true };
27792770
} else {
2780-
await nb_native().fs.unlink(fs_context, file_path);
2771+
await native_fs_utils.unlink_ignore_enoent(fs_context, file_path);
27812772
}
27822773
return version_info;
27832774
} catch (err) {

src/test/unit_tests/jest_tests/test_versioning_concurrency.test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,26 @@ describe('test versioning concurrency', () => {
5959
const versions = await nsfs.list_object_versions({ bucket: bucket }, DUMMY_OBJECT_SDK);
6060
expect(versions.objects.length).toBe(5);
6161
});
62+
63+
it('multiple delete version id and key', async () => {
64+
const bucket = 'bucket1';
65+
const key = 'key2';
66+
const versions_arr = [];
67+
// upload 5 versions of key2
68+
for (let i = 0; i < 5; i++) {
69+
const random_data = Buffer.from(String(i));
70+
const body = buffer_utils.buffer_to_read_stream(random_data);
71+
const res = await nsfs.upload_object({ bucket: bucket, key: key, source_stream: body }, DUMMY_OBJECT_SDK).catch(err => console.log('put error - ', err));
72+
versions_arr.push(res.etag);
73+
}
74+
const mid_version_id = versions_arr[3];
75+
const number_of_successful_operations = [];
76+
for (let i = 0; i < 15; i++) {
77+
nsfs.delete_object({ bucket: bucket, key: key, version_id: mid_version_id }, DUMMY_OBJECT_SDK)
78+
.then(res => number_of_successful_operations.push(res))
79+
.catch(err => console.log('delete the same key & version id error - ', err));
80+
}
81+
await P.delay(1000);
82+
expect(number_of_successful_operations.length).toBe(15);
83+
});
6284
});

src/util/native_fs_utils.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,23 @@ async function safe_unlink_posix(fs_context, to_delete_path, to_delete_version_i
229229
}
230230
}
231231

232+
/**
233+
* unlink_ignore_enoent unlinks a file and if recieved an ENOENT error it'll not fail
234+
* @param {nb.NativeFSContext} fs_context
235+
* @param {String} to_delete_path
236+
* @returns {Promise<Void>}
237+
*/
238+
async function unlink_ignore_enoent(fs_context, to_delete_path) {
239+
dbg.log1('native_fs_utils.unlink_ignore_enoent:', to_delete_path);
240+
try {
241+
await nb_native().fs.unlink(fs_context, to_delete_path);
242+
} catch (err) {
243+
dbg.warn(`native_fs_utils.unlink_ignore_enoent unlink error: file path ${to_delete_path} error`, err);
244+
if (err.code !== 'ENOENT') throw err;
245+
dbg.warn(`native_fs_utils.unlink_ignore_enoent unlink: file ${to_delete_path} already deleted, ignoring..`);
246+
}
247+
}
248+
232249
// safe_link_gpfs links source_path to dest_path while verifing dest.fd
233250
async function safe_link_gpfs(fs_context, dst_path, src_file, dst_file) {
234251
dbg.log1('Namespace_fs.safe_link_gpfs source_file:', src_file, src_file.fd, dst_file, dst_file && dst_file.fd);
@@ -671,6 +688,7 @@ exports.validate_bucket_creation = validate_bucket_creation;
671688
exports.is_path_exists = is_path_exists;
672689
exports.is_dir_rw_accessible = is_dir_rw_accessible;
673690
exports.folder_delete = folder_delete;
691+
exports.unlink_ignore_enoent = unlink_ignore_enoent;
674692
exports.get_bucket_tmpdir_full_path = get_bucket_tmpdir_full_path;
675693
exports.get_bucket_tmpdir_name = get_bucket_tmpdir_name;
676694
exports.entity_enum = entity_enum;

0 commit comments

Comments
 (0)