-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Conversation
c50e774
to
2cd5ec4
Compare
New dependencies detected. Learn more about Socket for GitHub ↗︎
|
@@ -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") { |
There was a problem hiding this comment.
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! 🧡
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. 🤷
There was a problem hiding this comment.
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 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment added.
There was a problem hiding this comment.
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? 🤔
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
376dd42
to
458940c
Compare
@@ -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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
- this might have happened frequently on very short living
42c1fcc
to
209340a
Compare
There was a problem hiding this 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.
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.
209340a
to
90495f4
Compare
/unhold |
Description
Before this change, # of listeners plateaued at some level after closing all browser tabs.
After this change, you can see listeners going down to zero.
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 theMonitoringEndpointsApp
class to append redis metrics to the default registry.-->
🤖 Generated by Copilot at 2cd5ec4
shouldNotifyClients
property toGitpodServerImpl
class to control whether to send updates to clients about workspace instances and prebuilds (link)shouldNotifyClients
property based on client metadata type ininitializeClient
method ofGitpodServerImpl
class (link)listenForWorkspaceInstanceUpdates
andlistenForPrebuildUpdates
methods ifshouldNotifyClients
property is true ininitializeClient
method ofGitpodServerImpl
class (link)listenForPrebuildUpdates
method ofGitpodServerImpl
class by usingpush
method instead ofpushAll
method to add disposables (link)onWorkspaceImageBuildLogs
method ofGitpodServerImpl
class by addingrelatedPrebuildFound
variable and condition to only create and registerresetListenerFromRedis
if client exists and prebuild is related to workspace (link)shouldNotifyClients
property before creating and registeringprebuildUpdateHandler
increateProject
method ofGitpodServerImpl
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
Run the build with werft instead of GHA
Run Leeway with
--dont-test
Publish
Installer
Add desired feature flags to the end of the line above, space separated
Preview Environment
If enabled this will build
install/preview
If enabled this will create the environment on GCE infra
Valid options are
all
,workspace
,webapp
,ide
,jetbrains
,vscode
,ssh
/hold