-
Notifications
You must be signed in to change notification settings - Fork 244
fix(router): release executor schema refs on graphMux shutdown #3011
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -51,6 +51,19 @@ type Executor struct { | |||
| TrackUsageInfo bool | ||||
| } | ||||
|
|
||||
| // Close releases schema and planner references held by the executor so a replaced | ||||
| // graph mux can be garbage-collected after config reload. | ||||
| func (e *Executor) Close() { | ||||
| if e == nil { | ||||
| return | ||||
| } | ||||
| e.ClientSchema = nil | ||||
| e.RouterSchema = nil | ||||
| e.PlanConfig = plan.Configuration{} | ||||
| e.RenameTypeNames = nil | ||||
| e.Resolver = nil | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think we can exclude this one. Compared to the other fields it's not heavy and reduces the risk surface. Also this executor instance the pointer points to is referenced by other pointers in other places as well (the WS handler/graphql handler), which is still active when we are here. So GC can't clean it up immediately anyways. EDIT: Also fixed by #3010 but review there still pending |
||||
| } | ||||
|
|
||||
| type ExecutorBuildOptions struct { | ||||
| EngineConfig *nodev1.EngineConfiguration | ||||
| Subgraphs []*nodev1.Subgraph | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package core | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
| "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" | ||
| "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/plan" | ||
| ) | ||
|
|
||
| func TestExecutorCloseReleasesSchemaReferences(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| executor := &Executor{ | ||
| ClientSchema: &ast.Document{}, | ||
| RouterSchema: &ast.Document{}, | ||
| PlanConfig: plan.Configuration{DataSources: []plan.DataSource{nil}}, | ||
| RenameTypeNames: nil, | ||
| } | ||
|
|
||
| executor.Close() | ||
|
|
||
| require.Nil(t, executor.ClientSchema) | ||
| require.Nil(t, executor.RouterSchema) | ||
| require.Empty(t, executor.PlanConfig.DataSources) | ||
| require.Nil(t, executor.RenameTypeNames) | ||
| require.Nil(t, executor.Resolver) | ||
| } | ||
|
|
||
| func TestExecutorCloseNilSafe(t *testing.T) { | ||
| t.Parallel() | ||
|
|
||
| var executor *Executor | ||
| require.NotPanics(t, func() { | ||
| executor.Close() | ||
| }) | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
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.
The problem is websockets use this Executor and they are closed async. When this function is called websocket connections are still alive (got signaled to close but might take a moment) and might use the Executor, which has just nilled its components. It can cause nil panics or unwanted errors at least. I need to check this in more depth and how to solve it.