Skip to content
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

createMany method triggers the create hook before the item is created #11353

Closed
3 tasks done
sarthakgaur opened this issue Jan 31, 2022 · 2 comments
Closed
3 tasks done

Comments

@sarthakgaur
Copy link

Preflight Checklist

Describe the Bug

The createMany method of ItemsService triggers the create hook on the item before the item is created in the table.

To Reproduce

  1. Create two collections a and b.
  2. Use the following code to create many b items when a item is created.
const B = "b";

module.exports = ({ action }, { services, exceptions }) => {
  action("a.items.create", async (meta, context) => {
    const event = { meta, context };
    await handleACreateAfter(event, services, exceptions);
  });

  action("b.items.create", async (meta, context) => {
    const event = { meta, context };
    await handleBCreateAfter(event, services, exceptions);
  });
};

async function handleACreateAfter(event, services, exceptions) {
  const { context } = event;
  const permission = getPermission(context);

  await createManyB(services, permission);
}

async function handleBCreateAfter(event, services, exceptions) {
  const { meta, context } = event;
  const permission = getPermission(context);

  const id = meta.key;

  // If you wait for some time, you get the row back.
  // await wait(100);
  const b = await getBById(services, permission, id);
  // Prints undefined on directus 9.5.0.
  console.log(b);
}

function getPermission(context) {
  const schema = context.schema;
  const accountability = context.accountability;
  return { schema, accountability };
}

async function createManyB(services, permission) {
  const { ItemsService } = services;
  const bService = new ItemsService(B, permission);

  const bRows = Array(5).fill({});
  await bService.createMany(bRows);
}

async function getBById(services, permission, id) {
  const { ItemsService } = services;
  const bService = new ItemsService(B, permission);

  const result = await bService.readByQuery({
    filter: {
      id: {
        _eq: id,
      },
    },
    fields: ["*"],
  });

  return result[0];
}

function wait(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

Errors Shown

const b = await getBById(services, permission, id);
console.log(b);

This should print the item the create hook was triggered on. But, I get undefined here. If I wait for, say 100 ms, before calling getBById, I get the correct item printed on the terminal.

Note:
If I print the meta object before running getBById, I am able to see the key field in it.

What version of Directus are you using?

9.5.0

What version of Node.js are you using?

14.18.3

What database are you using?

PostgreSQL 13.4

What browser are you using?

Firefox 95.0.2

What operating system are you using?

Fedora 34

How are you deploying Directus?

Locally

@nickrum
Copy link
Member

nickrum commented Jan 31, 2022

While the reproduction steps are a little different, the root cause of this issue should be the same as #11172.

@sarthakgaur
Copy link
Author

@nickrum I read through #11172, and I have updated my code. The getPermission function now looks like this:

function getPermission(context) {
  const schema = context.schema;
  const accountability = context.accountability;
  const knex = context.database;
  return { knex, schema, accountability };
}

Now, when the following code runs, I can see 4 out of the 5 items printed out.

const b = await getBById(services, permission, id);
console.log(b);

The 5th item is not printed, and I get the following error message.

Error: Transaction query already complete, run with DEBUG=knex:tx for more info
    at completedError (/home/dv/projects/create_many_test/node_modules/knex/lib/execution/transaction.js:396:9)
    at /home/dv/projects/create_many_test/node_modules/knex/lib/execution/transaction.js:362:24
    at new Promise (<anonymous>)
    at Client_PG.trxClient.query (/home/dv/projects/create_many_test/node_modules/knex/lib/execution/transaction.js:358:12)
    at Runner.query (/home/dv/projects/create_many_test/node_modules/knex/lib/execution/runner.js:130:36)
    at ensureConnectionCallback (/home/dv/projects/create_many_test/node_modules/knex/lib/execution/internal/ensure-connection-callback.js:13:17)
    at Runner.ensureConnection (/home/dv/projects/create_many_test/node_modules/knex/lib/execution/runner.js:272:20)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async Runner.run (/home/dv/projects/create_many_test/node_modules/knex/lib/execution/runner.js:30:19)
    at async run (/home/dv/projects/create_many_test/node_modules/directus/dist/database/run-ast.js:36:26)

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants