Skip to content

refactor: Remove generic options parameter from OperationBase #2593

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

Closed
wants to merge 3 commits into from

Conversation

nbbeeken
Copy link
Contributor

Add a builtOptions getter that inherits options from the parent class.

NODE-2815

Description

In order to make tracing options sensible I went with this idea of inheriting the super class's builtOptions which are frozen. I'll put this small start in review to get some feedback going on how we like this methodology and I can start expanding this to other operations.

Some of the bsonOptions work is duplicated in here to get the code to work, but I will pull that in from master when its there.

Look out for a parallel PR to this that works on removing executeLegacyOperation.

src/utils.ts Outdated
Comment on lines 1171 to 1122
if (name === 'session') continue;
if (ArrayBuffer.isView(value)) continue;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty lame skip logic, but I'm thinking maybe deepFreezing is overkill anyway. thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be useful to explain why those need to be skipped with comments. Is there a reason we can't use a popular public domain implementation of this like the deep-freeze npm module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the code from the same place that dep gets it from the MDN docs, I figure for the small changes we might want to make, might as well in house it.
I did document these skips but I think I can come up with better logic.

Comment on lines +110 to +117
// if (this.writeConcern && this.writeConcern.w === 0) {
// if (this.session && this.session.explicit) {
// throw new MongoError('Cannot have explicit session with unacknowledged writes');
// }
// return;
// }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran into a test failure when trying to add a few more operations to this PR that relates to this in applySession which is commented saying it should occur at command construction, I'll still have to discover the bug, but shall we move this here?
Maybe as part of removing legacy operations so everything would go through this path.


// Freeze properties before freezing self

for (const name of propNames) {
Copy link
Contributor

@reggi reggi Oct 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concern here about the combination of using deepFreeze within getters, this for loop will run on every access this.thing, and it's pretty hefty for loop. We may be making the object immutable but it's not the same object every-time this getter is run. Thoughts on some memoization or caching functionality?

Copy link
Contributor

@reggi reggi Oct 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could easily be achieved by setting this.cacheBuildOptions from within the getter constructor, and return that if it exists.

May have to just create buildOptions in the constructor, and any builder methods overwrite it and create a new object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine in terms of performance if we minimize use of the getter, I commented about that above. In terms of immutability, I don't think we can expect something that is gradually built on an object to be the same over the object's lifespan, so I think this is OK.

Copy link
Contributor

@reggi reggi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious how this overlaps with @HanaPearlman's work.

Copy link
Contributor

@emadum emadum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple questions but this approach looks good to me 👍

const serverWireVersion = maxWireVersion(server);
const inTransaction = this.session && this.session.inTransaction();

if (this.readConcern && commandSupportsReadConcern(cmd) && !inTransaction) {
Object.assign(cmd, { readConcern: this.readConcern });
}

if (options.collation && serverWireVersion < SUPPORTS_WRITE_CONCERN_AND_COLLATION) {
if (this.builtOptions.collation && serverWireVersion < SUPPORTS_WRITE_CONCERN_AND_COLLATION) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you changed these options to this.builtOptions instead of changing above to const options = this.builtOptions? Seems like we're calling that deepFreeze getter repeatedly without need here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch I'm going through and changing, in fact I think I want to make this a method now, leaving this much work in a property access its easy to overlook that its doing work each time.


// Freeze properties before freezing self

for (const name of propNames) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine in terms of performance if we minimize use of the getter, I commented about that above. In terms of immutability, I don't think we can expect something that is gradually built on an object to be the same over the object's lifespan, so I think this is OK.

src/utils.ts Outdated
Comment on lines 1171 to 1122
if (name === 'session') continue;
if (ArrayBuffer.isView(value)) continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be useful to explain why those need to be skipped with comments. Is there a reason we can't use a popular public domain implementation of this like the deep-freeze npm module?

@nbbeeken nbbeeken force-pushed the NODE-2815/remove-generic-opteraion-base branch from 4b184ab to 3fe7652 Compare November 5, 2020 20:09
@nbbeeken nbbeeken force-pushed the NODE-2815/remove-generic-opteraion-base branch from 3fe7652 to 948725a Compare November 9, 2020 15:15
@nbbeeken
Copy link
Contributor Author

nbbeeken commented Dec 3, 2020

Superseded by #2659

@nbbeeken nbbeeken closed this Dec 3, 2020
@nbbeeken nbbeeken deleted the NODE-2815/remove-generic-opteraion-base branch January 27, 2021 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants