Open jtran opened 2 weeks ago
Motivation?
Instead of every assertion having retry logic with a timeout:
You may be wondering, how is this better if it simply moves the timeout? In the old approach, if there's lots of async work like writing a file to disk, the assertion may pass and move on to the next step (4) before the file was written.
This proposal, on the other hand, essentially creates a synchronization point that waits until all async work is finished before moving on. This means that there are fewer race conditions in the testing code.
We could start using a similar approach in the app itself, not just tests.
For example, when transitioning from one state to another, maybe all async work is awaited and a UI spinner is shown before going to the next state. I don't think a blanket approach can be used since we don't necessarily want to introduce loading states all over the app. But this proposal would make it possible for when we would want it.
Maybe there are certain classes of async things that we wouldn't want to wait for, like engine calls. We might have to make an exception for them and not track them (or track them separately).
The conclusion from last week's meeting was that this is a good idea to make tests more resilient, but not to be used for app logic. For that, we want to lean-in to "data down, ~actions~ events up", and add state machines to handle the events and protect the resources. See https://github.com/KittyCAD/react-xstate-demo for an example of using XState in this way.
I don't know if this will work, but here is a way that I thought it could be done.
await
orreturn
a Promise.void promise
to ignore it, calltrackAsyncWork(promise)
.addSettleCallback()
.The lint already checks that we await, return, or use void for all promises. So this requires that we don't use void through diligence, which is not great.
Would this help? Would this not work? Discuss. 🙏