-
-
Notifications
You must be signed in to change notification settings - Fork 125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Read data from disk once #184
base: main
Are you sure you want to change the base?
Conversation
@@ -60,6 +60,8 @@ export default class Conf<T extends Record<string, any> = Record<string, unknown | |||
readonly #encryptionKey?: string | Buffer | NodeJS.TypedArray | DataView; | |||
readonly #options: Readonly<Partial<Options<T>>>; | |||
readonly #defaultValues: Partial<T> = {}; | |||
#readFromDisk = true; | |||
#state?: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I support this PR, but I'd like to suggest a few improvements, if you don't mind.
- To avoid a breaking change introduce a new option like
memoize/useMemoryState
get store(): T {
const state = createPlainObject();
if (this.options.memoize) {
if (this.#state) {
return this.#state;
}
this.#state = state;
}
try {
const data = fs.readFileSync(this.path, this.#encryptionKey ? null : 'utf8');
const dataString = this._encryptData(data);
const deserializedData = this._deserialize(dataString);
this._validate(deserializedData);
return Object.assign(state, deserializedData);
} catch (error: unknown) {
if ((error as any)?.code === 'ENOENT') {
this._ensureDirectory();
return state;
}
if (this.#options.clearInvalidConfig && (error as Error).name === 'SyntaxError') {
return state;
}
throw error;
}
}
- Use
change
event to triggerstate
reset instead of_watch
patch
if (options.memoize) {
this.events.on('change', this._resetState)
}
// ...
_resetState() {
this.#state = undefined;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you plz take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the suggestions here. It should be behind an option. We can make the option true by default at some point when it's more battle-tested.
Each read right now reads the data from the disk, which affects performance if conf is used in a high load application as the main storage.
This change stores each write additionally in the state and on each use of the store it deep clones the state and returns it instead of reading from disk. Deep cloning is needed to prevent the mutation of the state variable and ensure conf fully behaves as previously.
Speed improvements for reads is 100-500x, especially if encryption is used.