Skip to content

Conversation

aherlihy
Copy link
Contributor

No description provided.

@aherlihy aherlihy added the wip Work in Progress label Aug 11, 2020
@aherlihy aherlihy changed the title [DNM] Bulk API MONGOSH-296 - Bulk API Aug 12, 2020
@aherlihy aherlihy removed the wip Work in Progress label Aug 12, 2020
Copy link
Collaborator

@mcasimir mcasimir left a comment

Choose a reason for hiding this comment

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

Looks great. Left some sneaky comment, there are 3 you may want to check before merging:

  • is it ok to log operations?
  • set this._executed in the same context when is read
  • there is an !== null that would pass with undefined, is that ok?

export default class Bulk extends ShellApiClass {
_mongo: Mongo;
_collection: any; // to avoid circular ref
_batchCounts: any;
Copy link
Collaborator

@mcasimir mcasimir Aug 13, 2020

Choose a reason for hiding this comment

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

Maybe is better to add the type for _batchCounts, _batches, _innerBulk, just to make clear what those variables are for, and establish a contract with the different service provider implementations .. and also to get TS to complain a bit more 😄.

Copy link
Collaborator

@mcasimir mcasimir Aug 13, 2020

Choose a reason for hiding this comment

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

for example would be great to have a type BatchCounters

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yes, so for _innerBulk it would be a node driver type but the shell-api class can't import that directly. So instead you are saying we should define interfaces in the service-provider-core that indicate what the innerBulk/batches types should be? I can definitely do that

}

if (this._innerBulk.s !== undefined && Array.isArray(this._innerBulk.s.batches)) {
this._batches = [...this._innerBulk.s.batches];
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need to keep track of the batches in a class property or we should rather have a _getAllBatches method so we always use the service provider state as source of truth?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can only call getOperations after a bulk op is executed, but the bulk op class for the driver deletes the batches attribute after it's executed. So we need to save the batches locally right before we execute. Just a difference from driver to shell api.

async execute(writeConcern?: WriteConcern): Promise<BulkWriteResult> {
if (this._executed) {
throw new MongoshInvalidInputError('A bulk operation cannot be re-executed');
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

to be precise in order to avoid race conditions in scripts this._executed should be set right here in the same "synchronous" context where is checked, or in any case before calling any async operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can get rid of this entirely because the driver will throw the same error. Or we could just set it to false in the constructor?

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 removed the error check but kept it it for modifying the batch count - it wouldn't make sense if calling execute twice changed the batch count. Let me know if you think there's a problem with that

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think having this._executed there makes sense. my point was that we should not wait to set it to true though:

 async execute(writeConcern?: WriteConcern): Promise<BulkWriteResult> {
    if (this._executed) {
      throw new MongoshInvalidInputError('A bulk operation cannot be re-executed');
    }
    this._executed = true;
   ...

which is different from:

    if (this._executed) {
      throw new MongoshInvalidInputError('A bulk operation cannot be re-executed');
    }

    await doSomething();  // <--

    this._executed = true;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But shouldn't this._executed only be set true if the driver successfully executes the bulk op? That's why it's after the await

@aherlihy aherlihy merged commit 4431221 into master Aug 14, 2020
@aherlihy aherlihy deleted the bulk branch August 14, 2020 10:23
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.

2 participants