Skip to content

Concurrency issue with useFind #418

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

Open
Poyoman39 opened this issue Feb 25, 2025 · 7 comments · Fixed by #428 · May be fixed by #436
Open

Concurrency issue with useFind #418

Poyoman39 opened this issue Feb 25, 2025 · 7 comments · Fixed by #428 · May be fixed by #436

Comments

@Poyoman39
Copy link
Contributor

I have found a problem with the current implementation of useFindClient.

A fetchData is run synchronously at first render, then useEffect run cursor.observe({ which watch for changes on cursor.

On my component there is a concurrency issue with changes happening between the first render and the useEffect (so between the first fetchData and the observer creation)

@PedroMarianoAlmeida
Copy link
Contributor

I was able to create a test that catch this error:

// File -> packages/react-meteor-data/useFind.tests.js
Tinytest.addAsync(
    'useFind - Immediate update before effect registration (race condition test)',
    async function (test, completed) {
      const container = document.createElement('div');
      document.body.appendChild(container);

      const TestDocs = new Mongo.Collection(null);
      // Insert a single document.
      TestDocs.insert({ id: 1, val: 'initial' });

      const Test = () => {
        const docs = useFind(() => TestDocs.find(), []);
        return (
          <div data-testid="doc-value">
            {docs && docs[0] && docs[0].val}
          </div>
        );
      };

      // Render the component.
      ReactDOM.render(<Test />, container);

      // Immediately update the document (this should occur
      // after the synchronous fetch in the old code but before the effect attaches).
      TestDocs.update({ id: 1 }, { $set: { val: 'updated' } });

      // Wait until the rendered output reflects the update.
      await waitFor(() => {
        const node = container.querySelector('[data-testid="doc-value"]');
        if (!node || !node.textContent.includes('updated')) {
          throw new Error('Updated value not rendered yet');
        }
      }, { container, timeout: 500 });

      test.ok(
        container.innerHTML.includes('updated'),
        'Document should display updated value; the old code would fail to capture this update.'
      );

      document.body.removeChild(container);
      completed();
    }
  );

@Poyoman39 and I tried to create solutions but doesn't look like there are good ones
But at least now it is easy to reproduce

@StorytellerCZ
Copy link
Collaborator

Probably best to add a test like this to #419.

@StorytellerCZ StorytellerCZ linked a pull request Mar 19, 2025 that will close this issue
@Poyoman39
Copy link
Contributor Author

@Grubba27 this issue should remain opened ? To me #428 only implement tests for this issue

@PedroMarianoAlmeida
Copy link
Contributor

I believe this Issue should stay open, and then @Poyoman39 PR #419 should be rebased with master and add my test

(I propose a fix, but it was not good, so I kept only the test)

@StorytellerCZ StorytellerCZ reopened this Apr 2, 2025
@Poyoman39
Copy link
Contributor Author

I finaly succeed to run tests 🙌 react-meteor-data-harness. This PR pass all the tests :)

Image

@StorytellerCZ
Copy link
Collaborator

That is #436 correct?

@StorytellerCZ StorytellerCZ linked a pull request Apr 11, 2025 that will close this issue
@Poyoman39
Copy link
Contributor Author

@StorytellerCZ no this would be for a useTracker improvement ... still working on it ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants