1
mirror of https://github.com/rclone/rclone synced 2024-10-22 09:31:57 +02:00

Introduce AtExit to fix --cpuprofile and --memprofile to write profiles at end of run

This commit is contained in:
Nick Craig-Wood 2017-02-20 16:33:45 +00:00
parent 6e0e1ad9cb
commit 2da6cd7f84
2 changed files with 53 additions and 3 deletions

45
cmd/atexit.go Normal file
View File

@ -0,0 +1,45 @@
package cmd
// Atexit handling
import (
"os"
"os/signal"
"sync"
"github.com/ncw/rclone/fs"
)
var (
atExitFns []func()
atExitOnce sync.Once
atExitRegisterOnce sync.Once
)
// AtExit registers a function to be added on exit
func AtExit(fn func()) {
atExitFns = append(atExitFns, fn)
// Run AtExit handlers on SIGINT or SIGTERM so everything gets
// tidied up properly
atExitRegisterOnce.Do(func() {
go func() {
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt) // syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT
sig := <-ch
fs.Infof(nil, "Signal received: %s", sig)
runAtExitFunctions()
fs.Infof(nil, "Exiting...")
os.Exit(0)
}()
})
}
// Runs all the AtExit functions if they haven't been run already
func runAtExitFunctions() {
atExitOnce.Do(func() {
for _, fn := range atExitFns {
fn()
}
})
}

View File

@ -69,6 +69,9 @@ and configuration walkthroughs.
* http://rclone.org/
`,
PersistentPostRun: func(cmd *cobra.Command, args []string) {
runAtExitFunctions()
},
}
// runRoot implements the main rclone command with no subcommands
@ -341,12 +344,14 @@ func initConfig() {
fs.Stats.Error()
log.Fatal(err)
}
defer pprof.StopCPUProfile()
AtExit(func() {
pprof.StopCPUProfile()
})
}
// Setup memory profiling if desired
if *memProfile != "" {
defer func() {
AtExit(func() {
fs.Infof(nil, "Saving Memory profile %q\n", *memProfile)
f, err := os.Create(*memProfile)
if err != nil {
@ -363,7 +368,7 @@ func initConfig() {
fs.Stats.Error()
log.Fatal(err)
}
}()
})
}
if m, _ := regexp.MatchString("^(bits|bytes)$", *dataRateUnit); m == false {