Skip to content
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

fix: close goroutine pool to prevent goroutine leaks after multiple generate calls #499

Conversation

FelipeCooper
Copy link
Contributor

@FelipeCooper FelipeCooper commented Dec 9, 2024

Description

Hello,

While using this library in my service, I encountered an issue with goroutine leaks. Below is the graph from New Relic showing the issue I discovered:
image
My application has more than 7k open goroutines.

To identify the cause of the leak, I used pprof and discovered a bug in Maroto. Below is the result of pprof before generating any documents:

pprof goroutines before generate documents
goroutine profile: total 5
1 @ 0x104086d2c 0x1040c6ea4 0x1042f7594 0x1042f73b0 0x1042f4948 0x104309834 0x10430a148 0x1042a4198 0x1042a5d94 0x1042bf58c 0x1042a301c 0x1040d0514
#	0x1042f7593	runtime/pprof.writeRuntimeProfile+0xb3	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/pprof/pprof.go:793
#	0x1042f73af	runtime/pprof.writeGoroutine+0x4f	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/pprof/pprof.go:752
#	0x1042f4947	runtime/pprof.(*Profile).WriteTo+0x147	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/pprof/pprof.go:374
#	0x104309833	net/http/pprof.handler.ServeHTTP+0x443	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/pprof/pprof.go:272
#	0x10430a147	net/http/pprof.Index+0xc7		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/pprof/pprof.go:388
#	0x1042a4197	net/http.HandlerFunc.ServeHTTP+0x37	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2220
#	0x1042a5d93	net/http.(*ServeMux).ServeHTTP+0x1b3	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2747
#	0x1042bf58b	net/http.serverHandler.ServeHTTP+0xbb	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3210
#	0x1042a301b	net/http.(*conn).serve+0x4fb		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2092

1 @ 0x1040c8038 0x10408a548 0x1040c72e0 0x10411fc78 0x10412078c 0x10412077d 0x1041c2e08 0x1041cbe84 0x10429e704 0x1042382e8 0x104238ee0 0x104239114 0x10423ac54 0x1042be4f8 0x1042be511 0x10429f294 0x1042a2dd8 0x1040d0514
#	0x1040c72df	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x10411fc77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x10412078b	internal/poll.(*pollDesc).waitRead+0x1fb	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x10412077c	internal/poll.(*FD).Read+0x1ec			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:165
#	0x1041c2e07	net.(*netFD).Read+0x27				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_posix.go:55
#	0x1041cbe83	net.(*conn).Read+0x33				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/net.go:189
#	0x10429e703	net/http.(*connReader).Read+0x223		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:798
#	0x1042382e7	bufio.(*Reader).fill+0xf7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:110
#	0x104238edf	bufio.(*Reader).ReadSlice+0x2f			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:376
#	0x104239113	bufio.(*Reader).ReadLine+0x23			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:405
#	0x10423ac53	net/textproto.(*Reader).readLineSlice+0x83	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/textproto/reader.go:64
#	0x1042be4f7	net/textproto.(*Reader).ReadLine+0x77		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/textproto/reader.go:44
#	0x1042be510	net/http.readRequest+0x90			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/request.go:1096
#	0x10429f293	net/http.(*conn).readRequest+0x1f3		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:1048
#	0x1042a2dd7	net/http.(*conn).serve+0x2b7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2017

1 @ 0x1040c8038 0x10408a548 0x1040c72e0 0x10411fc78 0x10412122c 0x10412121d 0x1041c3d18 0x1041d3688 0x1041d2a3c 0x1042a7104 0x1042a6e34 0x104483db8 0x104483d61 0x1040910c8 0x1040d0514
#	0x1040c72df	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x10411fc77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x10412122b	internal/poll.(*pollDesc).waitRead+0x24b	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x10412121c	internal/poll.(*FD).Accept+0x23c		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:620
#	0x1041c3d17	net.(*netFD).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_unix.go:172
#	0x1041d3687	net.(*TCPListener).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock_posix.go:159
#	0x1041d2a3b	net.(*TCPListener).Accept+0x2b			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock.go:372
#	0x1042a7103	net/http.(*Server).Serve+0x293			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3330
#	0x1042a6e33	net/http.(*Server).ListenAndServe+0x83		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3259
#	0x104483db7	net/http.ListenAndServe+0xa7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3514
#	0x104483d60	main.main+0x50					/Users/mcooper/git/maroto/cmd/dev/pdf/main.go:34
#	0x1040910c7	runtime.main+0x287				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/proc.go:272

1 @ 0x1040c8038 0x10408a548 0x1040c72e0 0x10411fc78 0x10412122c 0x10412121d 0x1041c3d18 0x1041d3688 0x1041d2a3c 0x1042a7104 0x1042a6e34 0x1044857a0 0x1044857a1 0x1040d0514
#	0x1040c72df	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x10411fc77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x10412122b	internal/poll.(*pollDesc).waitRead+0x24b	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x10412121c	internal/poll.(*FD).Accept+0x23c		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:620
#	0x1041c3d17	net.(*netFD).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_unix.go:172
#	0x1041d3687	net.(*TCPListener).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock_posix.go:159
#	0x1041d2a3b	net.(*TCPListener).Accept+0x2b			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock.go:372
#	0x1042a7103	net/http.(*Server).Serve+0x293			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3330
#	0x1042a6e33	net/http.(*Server).ListenAndServe+0x83		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3259
#	0x10448579f	net/http.ListenAndServe+0x3f			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3514
#	0x1044857a0	main.main.func1+0x40				/Users/mcooper/git/maroto/cmd/dev/pdf/main.go:32

1 @ 0x1040d0514

After generating just 10 documents, the total number of open goroutines is:

pprof goroutines after generate documents
goroutine profile: total 106
100 @ 0x10268bff8 0x102621c74 0x102621844 0x102a44e24 0x1026944d4
#	0x102a44e23	github.com/f-amaral/go-async/pool.NewPool[...].func1+0x133	/Users/mcooper/go/pkg/mod/github.com/f-amaral/go-async@v0.3.0/pool/jobpool.go:31

1 @ 0x10264ad2c 0x10268ae64 0x1028bb2e4 0x1028bb100 0x1028b8698 0x1028cd584 0x1028cde98 0x102867f58 0x102869b54 0x10288334c 0x102866ddc 0x1026944d4
#	0x1028bb2e3	runtime/pprof.writeRuntimeProfile+0xb3	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/pprof/pprof.go:793
#	0x1028bb0ff	runtime/pprof.writeGoroutine+0x4f	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/pprof/pprof.go:752
#	0x1028b8697	runtime/pprof.(*Profile).WriteTo+0x147	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/pprof/pprof.go:374
#	0x1028cd583	net/http/pprof.handler.ServeHTTP+0x443	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/pprof/pprof.go:272
#	0x1028cde97	net/http/pprof.Index+0xc7		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/pprof/pprof.go:388
#	0x102867f57	net/http.HandlerFunc.ServeHTTP+0x37	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2220
#	0x102869b53	net/http.(*ServeMux).ServeHTTP+0x1b3	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2747
#	0x10288334b	net/http.serverHandler.ServeHTTP+0xbb	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3210
#	0x102866ddb	net/http.(*conn).serve+0x4fb		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2092

1 @ 0x10268bff8 0x10264e548 0x10268b2a0 0x1026e3a78 0x1026e458c 0x1026e457d 0x102786c08 0x10278fc84 0x1028624c4 0x1027fc0e8 0x1027fc250 0x102866f14 0x1026944d4
#	0x10268b29f	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x1026e3a77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x1026e458b	internal/poll.(*pollDesc).waitRead+0x1fb	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x1026e457c	internal/poll.(*FD).Read+0x1ec			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:165
#	0x102786c07	net.(*netFD).Read+0x27				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_posix.go:55
#	0x10278fc83	net.(*conn).Read+0x33				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/net.go:189
#	0x1028624c3	net/http.(*connReader).Read+0x223		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:798
#	0x1027fc0e7	bufio.(*Reader).fill+0xf7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:110
#	0x1027fc24f	bufio.(*Reader).Peek+0x5f			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:148
#	0x102866f13	net/http.(*conn).serve+0x633			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2127

1 @ 0x10268bff8 0x10264e548 0x10268b2a0 0x1026e3a78 0x1026e458c 0x1026e457d 0x102786c08 0x10278fc84 0x1028624c4 0x1027fc0e8 0x1027fcce0 0x1027fcf14 0x1027fea54 0x1028822b8 0x1028822d1 0x102863054 0x102866b98 0x1026944d4
#	0x10268b29f	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x1026e3a77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x1026e458b	internal/poll.(*pollDesc).waitRead+0x1fb	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x1026e457c	internal/poll.(*FD).Read+0x1ec			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:165
#	0x102786c07	net.(*netFD).Read+0x27				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_posix.go:55
#	0x10278fc83	net.(*conn).Read+0x33				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/net.go:189
#	0x1028624c3	net/http.(*connReader).Read+0x223		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:798
#	0x1027fc0e7	bufio.(*Reader).fill+0xf7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:110
#	0x1027fccdf	bufio.(*Reader).ReadSlice+0x2f			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:376
#	0x1027fcf13	bufio.(*Reader).ReadLine+0x23			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/bufio/bufio.go:405
#	0x1027fea53	net/textproto.(*Reader).readLineSlice+0x83	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/textproto/reader.go:64
#	0x1028822b7	net/textproto.(*Reader).ReadLine+0x77		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/textproto/reader.go:44
#	0x1028822d0	net/http.readRequest+0x90			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/request.go:1096
#	0x102863053	net/http.(*conn).readRequest+0x1f3		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:1048
#	0x102866b97	net/http.(*conn).serve+0x2b7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:2017

1 @ 0x10268bff8 0x10264e548 0x10268b2a0 0x1026e3a78 0x1026e502c 0x1026e501d 0x102787b18 0x102797488 0x10279683c 0x10286aec4 0x10286abf4 0x102a47908 0x102a478b1 0x1026550c8 0x1026944d4
#	0x10268b29f	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x1026e3a77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x1026e502b	internal/poll.(*pollDesc).waitRead+0x24b	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x1026e501c	internal/poll.(*FD).Accept+0x23c		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:620
#	0x102787b17	net.(*netFD).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_unix.go:172
#	0x102797487	net.(*TCPListener).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock_posix.go:159
#	0x10279683b	net.(*TCPListener).Accept+0x2b			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock.go:372
#	0x10286aec3	net/http.(*Server).Serve+0x293			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3330
#	0x10286abf3	net/http.(*Server).ListenAndServe+0x83		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3259
#	0x102a47907	net/http.ListenAndServe+0xa7			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3514
#	0x102a478b0	main.main+0x50					/Users/mcooper/git/maroto/cmd/dev/pdf/main.go:34
#	0x1026550c7	runtime.main+0x287				/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/proc.go:272

1 @ 0x10268bff8 0x10264e548 0x10268b2a0 0x1026e3a78 0x1026e502c 0x1026e501d 0x102787b18 0x102797488 0x10279683c 0x10286aec4 0x10286abf4 0x102a492f0 0x102a492f1 0x1026944d4
#	0x10268b29f	internal/poll.runtime_pollWait+0x9f		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/runtime/netpoll.go:351
#	0x1026e3a77	internal/poll.(*pollDesc).wait+0x27		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:84
#	0x1026e502b	internal/poll.(*pollDesc).waitRead+0x24b	/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_poll_runtime.go:89
#	0x1026e501c	internal/poll.(*FD).Accept+0x23c		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/internal/poll/fd_unix.go:620
#	0x102787b17	net.(*netFD).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/fd_unix.go:172
#	0x102797487	net.(*TCPListener).accept+0x27			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock_posix.go:159
#	0x10279683b	net.(*TCPListener).Accept+0x2b			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/tcpsock.go:372
#	0x10286aec3	net/http.(*Server).Serve+0x293			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3330
#	0x10286abf3	net/http.(*Server).ListenAndServe+0x83		/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3259
#	0x102a492ef	net/http.ListenAndServe+0x3f			/Users/mcooper/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.darwin-arm64/src/net/http/server.go:3514
#	0x102a492f0	main.main.func1+0x40				/Users/mcooper/git/maroto/cmd/dev/pdf/main.go:32

1 @ 0x1026944d4


More than 100 goroutines remain open, so when generating a large number of documents, memory usage increases and the instance crashes.

Upon analyzing the code, I noticed that the pool of goroutines was never closed, leading to the leak. I have refactored the code to ensure that the goroutines are closed after execution. Additionally, I moved the pool initialization to the Generate function to ensure that a new pool is created each time Generate is called, preventing any unnecessary goroutines from being left open.

I also added unit tests to ensure that no further goroutine leaks occur, particularly in concurrent mode.

Related Issue

Checklist

check with "x", ONLY IF APPLIED to your change

  • All methods associated with structs has func (<first letter of struct> *struct) method() {} name style.
  • Wrote unit tests for new/changed features.
  • Followed the unit test when,should naming pattern.
  • All mocks created with m := mocks.NewConstructor(t).
  • All mocks using m.EXPECT().MethodName() method to mock methods.
  • Updated docs/doc.go and docs/*
  • Updated example_test.go.
  • Updated README.md
  • New public methods/structs/interfaces has comments upside them explaining they responsibilities
  • Executed make dod with none issues pointed out by golangci-lint

Copy link
Collaborator

@Fernando-hub527 Fernando-hub527 left a comment

Choose a reason for hiding this comment

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

very good!
I just fixed one thing lint pointed out.

Copy link

codecov bot commented Dec 10, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 87.09%. Comparing base (da3191b) to head (5f8b8c0).
Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #499      +/-   ##
==========================================
- Coverage   87.09%   87.09%   -0.00%     
==========================================
  Files          61       61              
  Lines        2331     2330       -1     
==========================================
- Hits         2030     2029       -1     
  Misses        268      268              
  Partials       33       33              
Flag Coverage Δ
unittests 87.09% <100.00%> (-<0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@johnfercher johnfercher merged commit 53eb473 into johnfercher:master Dec 10, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants