Skip to content

Fix listeners leaks – EXP-206 #18321

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

Merged
merged 4 commits into from
Aug 2, 2023
Merged

Fix listeners leaks – EXP-206 #18321

merged 4 commits into from
Aug 2, 2023

Conversation

AlexTugarev
Copy link
Member

@AlexTugarev AlexTugarev commented Jul 20, 2023

Description

Before this change, # of listeners plateaued at some level after closing all browser tabs.

Screenshot 2023-07-28 at 10 35 51

After this change, you can see listeners going down to zero.

Screenshot 2023-07-28 at 13 37 32
Changes summary and walkthrough generated by Copilot

🤖 Generated by Copilot at 2cd5ec4

This pull request improves the efficiency and accuracy of the server's communication with browser clients and the monitoring of redis metrics. It changes the GitpodServerImpl class to only send updates to relevant clients and fixes a prebuild bug. It also refactors the MonitoringEndpointsApp class to append redis metrics to the default registry.
-->

🤖 Generated by Copilot at 2cd5ec4

  • Refactor monitoring endpoints to append redis metrics to default registry instead of merging them (link)
  • Add shouldNotifyClients property to GitpodServerImpl class to control whether to send updates to clients about workspace instances and prebuilds (link)
  • Set shouldNotifyClients property based on client metadata type in initializeClient method of GitpodServerImpl class (link)
  • Add conditions to only call listenForWorkspaceInstanceUpdates and listenForPrebuildUpdates methods if shouldNotifyClients property is true in initializeClient method of GitpodServerImpl class (link)
  • Simplify listenForPrebuildUpdates method of GitpodServerImpl class by using push method instead of pushAll method to add disposables (link)
  • Fix bug in onWorkspaceImageBuildLogs method of GitpodServerImpl class by adding relatedPrebuildFound variable and condition to only create and register resetListenerFromRedis if client exists and prebuild is related to workspace (link)
  • Add condition to check shouldNotifyClients property before creating and registering prebuildUpdateHandler in createProject method of GitpodServerImpl class (link)

Related Issue(s)

Fixes EXP-206

How to test

Documentation

Preview status

Gitpod was successfully deployed to your preview environment.

Build Options

Build
  • /werft with-werft
    Run the build with werft instead of GHA
  • leeway-no-cache
  • /werft no-test
    Run Leeway with --dont-test
Publish
  • /werft publish-to-npm
  • /werft publish-to-jb-marketplace
Installer
  • analytics=segment
  • with-dedicated-emulation
  • workspace-feature-flags
    Add desired feature flags to the end of the line above, space separated
Preview Environment
  • /werft with-local-preview
    If enabled this will build install/preview
  • /werft with-preview
  • /werft with-large-vm
  • /werft with-gce-vm
    If enabled this will create the environment on GCE infra
  • with-integration-tests=all
    Valid options are all, workspace, webapp, ide, jetbrains, vscode, ssh
  • with-monitoring

/hold

@AlexTugarev AlexTugarev force-pushed the at/listeners-leak branch 2 times, most recently from c50e774 to 2cd5ec4 Compare July 28, 2023 10:05
@roboquat roboquat added size/M and removed size/XS labels Jul 28, 2023
@AlexTugarev AlexTugarev changed the title debug logs Fix listeners leaks Jul 28, 2023
@AlexTugarev AlexTugarev changed the title Fix listeners leaks Fix listeners leaks – EXP-206 Jul 28, 2023
@socket-security
Copy link

New dependencies detected. Learn more about Socket for GitHub ↗︎

Packages Version New capabilities Transitives Size Publisher
prom-client 14.2.0 None +0 110 kB simenb

@AlexTugarev AlexTugarev marked this pull request as ready for review July 28, 2023 11:50
@AlexTugarev AlexTugarev requested a review from a team as a code owner July 28, 2023 11:50
@@ -309,12 +311,20 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
log.debug({ userId: this.userID }, `clientRegion: ${clientHeaderFields.clientRegion}`);
log.debug({ userId: this.userID }, "initializeClient");

this.listenForWorkspaceInstanceUpdates();
if (this.client && clientMetadata.type === "browser") {
Copy link
Member

Choose a reason for hiding this comment

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

Why are notifications only relevant for browser clients?
Would be great to have the answer captured in a comment! 🧡

Copy link
Member Author

Choose a reason for hiding this comment

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

Why are notifications only relevant for browser clients?

Going to add this comment on the final pass.

But in general, you'd disagree about this change? Those events are only consumed by browser clients, no?
cc. @akosyakov on this question.

Copy link
Member

@geropl geropl Jul 28, 2023

Choose a reason for hiding this comment

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

I'm not sure what the motivation is. Looking at the other client types (source), I think some others are interested in workspace instance updates as well: supervisor, go-client.
And that makes me wonder if it's worth to introduce this distinction here, based on a field that so far we only used for observability purposes. 🤷

Copy link
Member Author

Choose a reason for hiding this comment

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

In the end, the biggest problem to solve here is the piling up of listener registrations for go-clients, which is AFAIC primarily the PAPI servers holding client connections 🙈

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment added.

Copy link
Member

Choose a reason for hiding this comment

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

In the end, the biggest problem to solve here is the piling up of listener registrations for go-clients, which is AFAIC primarily the PAPI servers holding client connections

Ok, then I feel I'm lagging context on why we try to limit it here. See Anton's comment.
Maybe we should sync on Monday quickly to get this out the door? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

I see. Didn't check too deeply with all IDE's, but only found no-op handlers for instance updates.
Going to change the PR and only disable prebuild updates to be disabled for non-browser clients.

Copy link
Member Author

Choose a reason for hiding this comment

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

@akosyakov, I reverted the changes to instance updates.

That said, I believe it would make sense to change the way instance updates are forwarded via PAPI server. If that would directly subscribe on redis, we would be in a position where no connection pooling is required anymore in PAPI server.

Copy link
Member

Choose a reason for hiding this comment

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

Why don't we observe it for instance updates but only for prebuilds?

Copy link
Member Author

Choose a reason for hiding this comment

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

We reverted the check for browser and proceed with checking for existing clients.

@@ -331,7 +344,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
);

for (const projectId of projects) {
this.disposables.pushAll([this.subscriber.listenForPrebuildUpdates(projectId, handler)]);
this.disposables.push(this.subscriber.listenForPrebuildUpdates(projectId, handler));
Copy link
Member

@akosyakov akosyakov Jul 31, 2023

Choose a reason for hiding this comment

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

here disposables can be already disposed because of async call above? Disposables should be added in sync code or we should checked whether already disposed and then dispose immediately.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice catch! I think a DisposableCollection is supposed to be prefilled with single item first, so that if it's emptied once, that state should be kept consistent.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks @svenefftinge and @akosyakov for checking on this.

The PR is updated now, with a different set of changes:

  • check for client be defined in gitpod-server-impl
  • add prebuild subscribers only if the thing is not disposed yet
    • this might have happened frequently on very short living workspacePageClose events

@AlexTugarev AlexTugarev marked this pull request as ready for review August 1, 2023 08:07
@AlexTugarev AlexTugarev force-pushed the at/listeners-leak branch 2 times, most recently from 42c1fcc to 209340a Compare August 1, 2023 08:18
Copy link
Member

@akosyakov akosyakov left a comment

Choose a reason for hiding this comment

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

I did not test, but code changes make sense to me.

@AlexTugarev
Copy link
Member Author

Still trying to validate on the preview env. Facing unrelated issues with monitoring, though.

- check for client be defined in gitpod-server-impl
- add prebuild subscribers only if the thing is not disposed yet
   - this might have happened frequently on very short living workspacePageClose events
don't override default registry, which breaks other metrics.
@AlexTugarev
Copy link
Member Author

Finally, I could validate that prebuild subscribers are going down after closing the tab. I opened the Projects view of the dashboard which rendered 4 items, just to clarify the number visualized here.

Again, the carrier wave here results from the cached PAPI server connections.

Screenshot 2023-08-02 at 12 24 26 Screenshot 2023-08-02 at 12 24 02

@AlexTugarev
Copy link
Member Author

/unhold

@roboquat roboquat merged commit 436130b into main Aug 2, 2023
@roboquat roboquat deleted the at/listeners-leak branch August 2, 2023 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants