From 2f05aacbf20d0deb69f3b7403fd1f41902ea15ac Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Fri, 20 May 2016 03:20:54 +0530 Subject: [PATCH] Stop profiling on exit of main goroutine (#1670) * Stop profiling on exit of main goroutine Previously, profiling was stopped since Stop() method was called on exit of cli.BeforeFunc. This lead to profiling to be stopped prematurely. * Moved profiling switch statement to a separate func --- main.go | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 54f8ca813..a10631eac 100644 --- a/main.go +++ b/main.go @@ -150,6 +150,19 @@ func mustGetProfilePath() string { return filepath.Join(mustGetConfigPath(), globalMinioProfilePath) } +func setupProfilingFromEnv(profiler *interface { + Stop() +}) { + switch os.Getenv("MINIO_PROFILER") { + case "cpu": + *profiler = profile.Start(profile.CPUProfile, profile.ProfilePath(mustGetProfilePath())) + case "mem": + *profiler = profile.Start(profile.MemProfile, profile.ProfilePath(mustGetProfilePath())) + case "block": + *profiler = profile.Start(profile.BlockProfile, profile.ProfilePath(mustGetProfilePath())) + } +} + func main() { // Set global trace flag. trace := os.Getenv("MINIO_TRACE") @@ -159,6 +172,9 @@ func main() { probe.SetAppInfo("Release-Tag", minioReleaseTag) probe.SetAppInfo("Commit-ID", minioShortCommitID) + var profiler interface { + Stop() + } app := registerApp() app.Before = func(c *cli.Context) error { // Sets new config folder. @@ -195,18 +211,20 @@ func main() { // Enable profiling supported modes are [cpu, mem, block]. // ``MINIO_PROFILER`` supported options are [cpu, mem, block]. - switch os.Getenv("MINIO_PROFILER") { - case "cpu": - defer profile.Start(profile.CPUProfile, profile.ProfilePath(mustGetProfilePath())).Stop() - case "mem": - defer profile.Start(profile.MemProfile, profile.ProfilePath(mustGetProfilePath())).Stop() - case "block": - defer profile.Start(profile.BlockProfile, profile.ProfilePath(mustGetProfilePath())).Stop() - } + setupProfilingFromEnv(&profiler) // Return here. return nil } + + // Stop profiling on exit. + // N B If any inner function calls os.Exit() the defer(s) stacked wouldn't be called + defer func() { + if profiler != nil { + profiler.Stop() + } + }() + // Run the app - exit on error. app.RunAndExitOnError() }