Skip to content

Commit

Permalink
[Live] Fixing edge case parallel rendering bug
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed Jan 22, 2024
1 parent f63cb59 commit 0ab7e7f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/LiveComponent/assets/dist/live_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -1946,7 +1946,6 @@ class Component {
this.valueStore.flushDirtyPropsToPending();
this.isRequestPending = false;
this.backendRequest.promise.then(async (response) => {
this.backendRequest = null;
const backendResponse = new BackendResponse(response);
const html = await backendResponse.getBody();
for (const input of Object.values(this.pendingFiles)) {
Expand All @@ -1960,10 +1959,12 @@ class Component {
if (controls.displayError) {
this.renderError(html);
}
this.backendRequest = null;
thisPromiseResolve(backendResponse);
return response;
}
this.processRerender(html, backendResponse);
this.backendRequest = null;
thisPromiseResolve(backendResponse);
if (this.isRequestPending) {
this.isRequestPending = false;
Expand Down
3 changes: 2 additions & 1 deletion src/LiveComponent/assets/src/Component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ export default class Component {
this.isRequestPending = false;

this.backendRequest.promise.then(async (response) => {
this.backendRequest = null;
const backendResponse = new BackendResponse(response);
const html = await backendResponse.getBody();

Expand All @@ -410,6 +409,7 @@ export default class Component {
this.renderError(html);
}

this.backendRequest = null;
thisPromiseResolve(backendResponse);

return response;
Expand All @@ -418,6 +418,7 @@ export default class Component {
this.processRerender(html, backendResponse);

// finally resolve this promise
this.backendRequest = null;
thisPromiseResolve(backendResponse);

// do we already have another request pending?
Expand Down
48 changes: 48 additions & 0 deletions src/LiveComponent/assets/test/controller/render.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,54 @@ describe('LiveController rendering Tests', () => {
await waitFor(() => expect(test.element).toHaveTextContent('Title: "greetings to you"'));
});

it('waits for the rendering process of previous request to finish before starting a new one', async () => {
const test = await createTest({
title: 'greetings',
contents: '',
}, (data: any) => `
<div ${initComponent(data)}>
<input data-model='title' value='${data.title}'>
Title: "${data.title}"
<button data-action='live#$render'>Reload</button>
</div>
`);

let didSecondRenderStart = false;
let secondRenderStartedAt = 0;
test.component.on('render:started', () => {
if (didSecondRenderStart) {
return;
}
didSecondRenderStart = true;

test.component.on('loading.state:started', () => {
secondRenderStartedAt = Date.now();
});

test.expectsAjaxCall();
test.component.render();
});

let firstRenderFinishedAt = 0;
test.component.on('render:finished', () => {
// set the finish time for the first render only
if (firstRenderFinishedAt === 0) {
firstRenderFinishedAt = Date.now();
}
});

test.expectsAjaxCall();

await test.component.render();

await waitFor(() => expect(didSecondRenderStart).toBe(true));
await waitFor(() => expect(firstRenderFinishedAt).not.toBe(0));
await waitFor(() => expect(secondRenderStartedAt).not.toBe(0));
expect(secondRenderStartedAt).toBeGreaterThan(firstRenderFinishedAt);
});

it('can update svg', async () => {
const test = await createTest({ text: 'SVG' }, (data: any) => `
<div ${initComponent(data)}>
Expand Down

0 comments on commit 0ab7e7f

Please sign in to comment.