Skip to content

Instantly share code, notes, and snippets.

@gszr
Created February 7, 2025 21:46
Show Gist options
  • Save gszr/b7c97691e8d1a70c67b7a4ae52490740 to your computer and use it in GitHub Desktop.
Save gszr/b7c97691e8d1a70c67b7a4ae52490740 to your computer and use it in GitHub Desktop.
Go plugin investigation

After some more testing, I found no confirmation for the hypothesis below.

In testing, I instrumented Go pluginserver with the pprof library, as follows:

import (
  ...
	_ "net/http/pprof"
)
func main() {
  go func() {
    log.Println(http.ListenAndServe("localhost:6060", nil))
  }()
  ...
}

Subsequently, observed the memory consumption behavior with

$ go tool pprof -top http://localhost:6060/debug/pprof/heap  | head

Which shows:

Showing nodes accounting for 1028.13kB, 100% of 1028.13kB total

No significant increase was observed over time -- ran th tests for about 30 minutes.

I also modified the Go PDK server code to dump all instances in use at a given time, periodically -- patch here[1] if the 'how' is of interest.

That is, I get a list of all running instances periodically. If the instance leak was indeed happening, we would see that list grow indefinitely. Instead, what we see is the expected behavior of two total instances -- one for each worker (2 in my case):

2025/01/25 19:19:23 [info] 77663#0: *651 [go-hello:77667] 2025/01/25 19:19:23 INSTANCES, context: ngx.timer
2025/01/25 19:19:23 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  603, context: ngx.timer
2025/01/25 19:19:23 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  604, context: ngx.timer
2025/01/25 19:19:25 [info] 77663#0: *651 [go-hello:77667] 2025/01/25 19:19:25 INSTANCES, context: ngx.timer
2025/01/25 19:19:25 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  603, context: ngx.timer
2025/01/25 19:19:25 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  604, context: ngx.timer
2025/01/25 19:19:28 [info] 77663#0: *651 [go-hello:77667] 2025/01/25 19:19:28 INSTANCES, context: ngx.timer
2025/01/25 19:19:28 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  603, context: ngx.timer
2025/01/25 19:19:28 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  604, context: ngx.timer
2025/01/25 19:19:30 [info] 77663#0: *651 [go-hello:77667] 2025/01/25 19:19:30 INSTANCES, context: ngx.timer
2025/01/25 19:19:30 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  603, context: ngx.timer
2025/01/25 19:19:30 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  604, context: ngx.timer
2025/01/25 19:19:33 [info] 77663#0: *651 [go-hello:77667] 2025/01/25 19:19:33 INSTANCES, context: ngx.timer
2025/01/25 19:19:33 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  603, context: ngx.timer
2025/01/25 19:19:33 [info] 77663#0: *651 [go-hello:77667] GO: INSTANCE ID =  604, context: ngx.timer

On the Kong side, I start a simple configuration with a Go plugin enabled, start a loop with calls to and another loop with calls to while true; do http post :8001/config config=@~/Code/issues/go-pdk/go-pdk-210/kong.yml; done – effectively, causing the plugin iterator to be rebuilt repeatedly and new instances to be requested.

[1] https://gist.github.com/gszr/fefa5b7e3e7b334921616bdb2e668b77

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment