Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

@hybrist
Copy link
Contributor

@hybrist hybrist commented May 3, 2025

Other code may depend on ngServerMode and it might have been set globally / via a bundler. Forcing it to undefined in those situations can lead to hard debug issues where the only symptom is that "suddenly" browser-specific code paths run on the server and (obviously) break.


Note: This is the less aggressive version that still forces ngServerMode to undefined if that's how we found it. I think it would also be reasonable to remove this cleanup all together but I tried to err on the side of caution.

@pullapprove pullapprove bot requested a review from kirjs May 3, 2025 02:21
@angular-robot angular-robot bot added the area: server Issues related to server-side rendering label May 3, 2025
@ngbot ngbot bot added this to the Backlog milestone May 3, 2025
@hybrist hybrist added target: patch This PR is targeted for the next patch release action: review The PR is still awaiting reviews from at least one requested reviewer labels May 3, 2025
Other code may depend on `ngServerMode` and it might have been set
globally / via a bundler. Forcing it to `undefined` in those situations
can lead to hard debug issues where the only symptom is that "suddenly"
browser-specific code paths run on the server and (obviously) break.
@hybrist hybrist force-pushed the jk-cond-server-mode-cleanup branch from 12bca02 to 4e69312 Compare May 3, 2025 23:31
@AndrewKushnir AndrewKushnir requested review from alan-agius4 and removed request for kirjs May 6, 2025 04:08
@pullapprove pullapprove bot requested a review from kirjs May 6, 2025 04:08
Copy link
Contributor

@alan-agius4 alan-agius4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@alan-agius4 alan-agius4 requested review from thePunderWoman and removed request for kirjs May 6, 2025 05:22
Copy link
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels May 6, 2025
AndrewKushnir pushed a commit that referenced this pull request May 6, 2025
Other code may depend on `ngServerMode` and it might have been set
globally / via a bundler. Forcing it to `undefined` in those situations
can lead to hard debug issues where the only symptom is that "suddenly"
browser-specific code paths run on the server and (obviously) break.

PR Close #61106
@AndrewKushnir
Copy link
Contributor

This PR was merged into the repository by commit 06d6da3.

The changes were merged into the following branches: main, 19.2.x, 20.0.x

AndrewKushnir pushed a commit that referenced this pull request May 6, 2025
Other code may depend on `ngServerMode` and it might have been set
globally / via a bundler. Forcing it to `undefined` in those situations
can lead to hard debug issues where the only symptom is that "suddenly"
browser-specific code paths run on the server and (obviously) break.

PR Close #61106
Comment on lines +131 to +133
platform.onDestroy(() => {
globalThis['ngServerMode'] = undefined;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @alan-agius4

Reading and overwriting a global shared state sounds like being prone to race conditions, when it happens for various independent incoming requests. Am I missing something?

I'm worried by seeing that a global shared state being accessed and overwritten by specific a instances of Angular app (on its creation and on its destroy), because there may exist many parallel requests coming to the server, meaning many parallel renderings, meaning many instances of Angular app, meaning many calls of platformServer() (please correct me if my reasoning is wrong...). I guess it may lead to race conditions on reading/writing this global shared state globalThis['ngServerMode'].

Let's imagine the following example:

  1. a first request comes for the URL A and a PlatformRef is created for this request with calling platformServer(). It's a first request, so the global shared state ngServerMode is undefined. In other words, const noServerModeSet = typeof ngServerMode === 'undefined'; is evaluated to true. Now a global state is overwritten: globalThis['ngServerMode'] is set to true.
  2. While the rendering for the request A is still pending, in the meantime comes a new request B, and a new PlatformRef is created for the rendering of the request B, with calling platformServer() to create a new instance of Angular app B. At this moment ngServerMode is true (becasue it was set by the creation of PlatformRef A). In other words const noServerModeSet = typeof ngServerMode === 'undefined'; is evaluated to false, so no side effects will happen on creation nor destroying this PlatformRef B.
  3. Some time passes and the server-side rendering for request A finishes, so its PlatformRef is destroyed and the global shared state is overwritten to: globalThis['ngServerMode'] = undefined;
  4. But(!) the rendering of the request B is still pending, and if any logic in that rendering attempts to read the global shared state globalThis['ngServerMode'] now, then it will get a value undefined instead of true.

As far as I understand from the simple Angular codebase search, there are plenty of places in the Angular logic that attempt to read the ngServerMode global shared state. So I understand that the remaining rendering for the request B potentnially can have bugs.
image

I guess perhaps I'm missing something obvious and important in my reasoning. Then please let me know, I'm happy to learn.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ngServerMode is replaced with a constant at build time by the bundler.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I wasn't aware of it. Thank you for letting me know! 👍

If not a problem, let me ask to understand even better:
If ngServerMode is set at build time, then why/when it makes sense to set this value at runtime inside the logic of the function platformServer()? (What is the usecase)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: merge The PR is ready for merge by the caretaker area: server Issues related to server-side rendering target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.