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

[IMP] runtime: only destroy component in raf cb #1466

Merged
merged 1 commit into from
Jul 17, 2023

Conversation

ged-odoo
Copy link
Contributor

No description provided.

@ged-odoo ged-odoo force-pushed the master-no-destroy-guarantee-ged branch 7 times, most recently from d3a6b3e to 0a5f2ee Compare June 27, 2023 14:29
@ged-odoo ged-odoo changed the title [POC] runtime: only destroy component in raf cb [IMP] runtime: only destroy component in raf cb Jun 27, 2023
@ged-odoo ged-odoo force-pushed the master-no-destroy-guarantee-ged branch 3 times, most recently from 665c6c7 to f4a3f74 Compare June 27, 2023 15:08
@ged-odoo ged-odoo marked this pull request as ready for review June 27, 2023 15:08
@ged-odoo ged-odoo force-pushed the master-no-destroy-guarantee-ged branch 3 times, most recently from 41168cf to 5da4f63 Compare July 17, 2023 08:38
Before this commit, most of the time, components are destroyed when the
virtual dom is patched and a component node is removed. However, since
Owl is asynchronous and a component may take some time to get ready
(with onWillStart), it can happen that a component is created, then
before it is ready, it is recreated.  In that case, the initial instance
has to be destroyed.

Before this commit, the destroy operation was done immediately, when we
cancel the current fibers.  However, this means that we cannot have a
guarantee between micro task ticks that a component has not been
destroyed in the meantime.

For example, in Odoo, it is common to use the rpc service, which will
throw an error if called by a destroyed component. But because of the
possible destruction of a component at any time, the following code is
unsafe:

async loadSomeData() {
  // guaranteed to be called when component is alive
  await Promise.resolve();
  // however here, component may have been destroyed
  this.rpc(...)
}

So, to prevent this issue, we can slightly delay the destroy operation.
It is not entirely trivial, since we need to find a way to neutralize
the component in the meantime. But it seems like performing all that
kind of operation at the "commit" phase (so, the request animation frame
callback) makes sense to me.

So, this commit modifies the code to add a new component status
(cancelled) and use it to cancel components that are waiting to be
destroyed. These components will then be destroyed as soon as the
requestanimation frame starts, before all other dom operations.
@ged-odoo ged-odoo force-pushed the master-no-destroy-guarantee-ged branch from 5da4f63 to 766aa1a Compare July 17, 2023 08:48
@sdegueldre sdegueldre merged commit 7538aea into master Jul 17, 2023
3 checks passed
@sdegueldre sdegueldre deleted the master-no-destroy-guarantee-ged branch July 17, 2023 09:05
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