Skip to content

Commit

Permalink
separate functions to avoid the read system call
Browse files Browse the repository at this point in the history
Signed-off-by: shirady <57721533+shirady@users.noreply.github.com>
  • Loading branch information
shirady committed Jan 2, 2025
1 parent 5ca3891 commit 6f2284e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 36 deletions.
10 changes: 5 additions & 5 deletions src/sdk/accountspace_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const account_id_cache = new LRUCache({
*/
async function _validate_account_id(params, data) {
if (config.NC_ENABLE_ACCOUNT_ID_CACHE_STAT_VALIDATION) {
const same_stat = await check_same_stat_account(params._id, params.stat, data.config_fs);
const same_stat = await check_same_stat_account(params._id, params.name, params.stat, data.config_fs);
if (!same_stat) { // config file of account was changed
return false;
}
Expand All @@ -66,16 +66,16 @@ async function _validate_account_id(params, data) {
/**
* check_same_stat_account will return true the config file was not changed
* in case we had any issue (for example error during stat) the returned value will be undefined
* @param {string} _id
* @param {string} id
* @param {string} account_name
* @param {nb.NativeFSStats} account_stat
* @param {ConfigFS} config_fs
* @returns Promise<{boolean|undefined>}
*/
async function check_same_stat_account(_id, account_stat, config_fs) {
async function check_same_stat_account(id, account_name, account_stat, config_fs) {
if (!config_fs) return;
try {
const identity = await config_fs.get_identity_by_id_and_stat_file(_id, CONFIG_TYPES.ACCOUNT);
const current_stat = identity.stat;
const current_stat = await config_fs.stat_account_config_file_by_identity(id, account_name);
if (current_stat) {
return current_stat.ino === account_stat.ino && current_stat.mtimeNsBigint === account_stat.mtimeNsBigint;
}
Expand Down
83 changes: 52 additions & 31 deletions src/sdk/config_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,43 +383,24 @@ class ConfigFS {
* 1. try by identity path
* 2. if not found - try by account name with new accounts path
* 3. if not found - try by account name with old accounts path
* silent_if_missing is used only on get identity (if stat fails, it will throw an error)
* @param {string} id
* @param {string} [type]
* @param {{show_secrets?: boolean, decrypt_secret_key?: boolean, silent_if_missing?: boolean}} [options]
* @returns {Promise<Object>}
*/
async get_identity_by_id_and_stat_file(id, type, options = {}) {
const identity_path = this.get_identity_path_by_id(id);
const identity = await this.get_identity_by_id(id, type, options);
let identity;
try {
const stat_by_identity_path = await nb_native().fs.stat(this.fs_context, identity_path);
identity.stat = stat_by_identity_path;
} catch (err_stat_by_identity_path) {
if (err_stat_by_identity_path.code === 'ENOENT') {
dbg.warn('get_identity_by_id_and_stat_file: could not stat by identity ID will try to stat by account name');
const account_name = identity.name;
const account_name_new_path = this.get_account_path_by_name(account_name);
try {
const stat_by_account_name = await nb_native().fs.stat(this.fs_context, account_name_new_path);
identity.stat = stat_by_account_name;
} catch (err_stat_by_account_name_new_path) {
if (err_stat_by_identity_path.code === 'ENOENT') {
dbg.warn('get_identity_by_id_and_stat_file: could not stat by by account name (new accounts path)');
const account_name_old_path = this._get_old_account_path_by_name(account_name);
try {
const stat_by_account_name_old = await nb_native().fs.stat(this.fs_context, account_name_old_path);
identity.stat = stat_by_account_name_old;
} catch (err_stat_by_account_name_old_path) {
dbg.warn('get_identity_by_id_and_stat_file: could not stat by by account name (old accounts path)');
// eslint-disable-next-line max-depth
if (!options.silent_if_missing) {
const error_to_throw = new Error(`Could not stat identity by id ${id} or by account name ${account_name}`);
error_to_throw.code = 'ENOENT';
throw error_to_throw;
}
}
}
}
identity = await this.get_identity_by_id(id, type, options);
const stat = await this.stat_account_config_file_by_identity(id, identity.name);
identity.stat = stat;
} catch (err) {
dbg.error('get_identity_by_id_and_stat_file: got an error', err);
if (!identity && !options.silent_if_missing) {
const err_to_throw = new Error(`Could not find identity by id ${id}`);
err_to_throw.code = 'ENOENT';
throw err_to_throw;
}
}
return identity; // this identity object should have also a stat property
Expand Down Expand Up @@ -497,7 +478,7 @@ class ConfigFS {
}

/**
* stat_account_config_file will return the stat output on account config file
* stat_account_config_file will return the stat output on account config file by access key
* please notice that stat might throw an error - you should wrap it with try-catch and handle the error
* Note: access_key type of anonymous_access_key is a symbol, otherwise it is a string (not SensitiveString)
* @param {Symbol|string} access_key
Expand All @@ -515,6 +496,46 @@ class ConfigFS {
return nb_native().fs.stat(this.fs_context, path_for_account_or_user_config_file);
}

/**
* stat_account_config_file_by_identity will return the stat output on account config file by id or by account name
* @param {string} id
* @param {string} account_name
* @returns {Promise<nb.NativeFSStats>}
*/
async stat_account_config_file_by_identity(id, account_name) {
const identity_path = this.get_identity_path_by_id(id);
let stat;
try {
const stat_by_identity_path = await nb_native().fs.stat(this.fs_context, identity_path);
stat = stat_by_identity_path;
} catch (err_stat_by_identity_path) {
if (err_stat_by_identity_path.code === 'ENOENT') {
dbg.warn('get_identity_by_id_and_stat_file: could not stat by identity ID will try to stat by account name');
const account_name_new_path = this.get_account_path_by_name(account_name);
try {
const stat_by_account_name = await nb_native().fs.stat(this.fs_context, account_name_new_path);
stat = stat_by_account_name;
} catch (err_stat_by_account_name_new_path) {
if (err_stat_by_identity_path.code === 'ENOENT') {
dbg.warn('get_identity_by_id_and_stat_file: could not stat by by account name (new accounts path)');
const account_name_old_path = this._get_old_account_path_by_name(account_name);
try {
const stat_by_account_name_old = await nb_native().fs.stat(this.fs_context, account_name_old_path);
stat = stat_by_account_name_old;
} catch (err_stat_by_account_name_old_path) {
dbg.warn('get_identity_by_id_and_stat_file: could not stat by by account name (old accounts path)');
// eslint-disable-next-line max-depth
const error_to_throw = new Error(`Could not stat identity by id ${id} or by account name ${account_name}`);
error_to_throw.code = 'ENOENT';
throw error_to_throw;
}
}
}
}
}
return stat;
}

/**
* is_account_exists_by_name returns true if account config path exists in config dir
* if account does not exist and it's a regular account (not an IAM user)
Expand Down

0 comments on commit 6f2284e

Please sign in to comment.