Skip to content

Async hooks run in parallel to the collection operationΒ #301

@pmogollons

Description

@pmogollons

Describe the bug
Async hooks dont wait for the hook to return to perform the Collection op, for example.

To Reproduce

Tickets.before.insert(async function ticketsBeforeInsert(userId, doc) {
  doc.idNumber = await incrementCounter(`PQR::${doc.orgId}`);
});

console.log(doc.idNumber) // This will be undefined

Expected behavior
Async hooks should await for the response before calling the collection op.

Additional context
Happens in all of the package versions.

Workaround
In a Meteor version before 3.0 you can just use Promise.await

Tickets.before.insert(function ticketsBeforeInsert(userId, doc) {
  doc.idNumber = Promise.await(incrementCounter(`PQR::${doc.orgId}`));
});

Possible way to fix it
When we call the aspect function callbacks (hooks) we should await them, this will require to use async on CollectionHooks.defineAdvice and to use await Promise.all on each aspect.

For example, this are the changes done to the insert advice:

      await Promise.all(aspects.before.map(async (o) => {
        const r = await o.aspect.call({ transform: getTransform(doc), ...ctx }, userId, doc)
        if (r === false) abort = true
      }))

The issue with this is that this makes the collection methods to be async too and test will fail.

Any ideas on how to approac this issue will be appreciated.

Related issues
#71

Metadata

Metadata

Assignees

No one assigned

    Labels

    buggood first issueThis is an easy issue that beginners can tackle to get to know the code base.

    Type

    No type

    Projects

    Status

    Todo

    Status

    Investigation πŸ”­

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions