From a55ea42d7f5900bd5fc8fad047040c7865824f33 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 15 Jun 2019 01:11:51 +0300 Subject: Unbreak things --- ui/commands.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ui/commands.go') diff --git a/ui/commands.go b/ui/commands.go index 5bcba98..cd770b6 100644 --- a/ui/commands.go +++ b/ui/commands.go @@ -86,26 +86,26 @@ func cmdHeapProfile(cmd *Command) { func cmdRainbow(cmd *Command) { text := strings.Join(cmd.Args, " ") var html strings.Builder - fmt.Fprint(&html, "**🌈** ") + _, _ = fmt.Fprint(&html, "**🌈** ") for i, char := range text { if unicode.IsSpace(char) { html.WriteRune(char) continue } color := rainbow.GetInterpolatedColorFor(float64(i) / float64(len(text))).Hex() - fmt.Fprintf(&html, "%c", color, char) + _, _ = fmt.Fprintf(&html, "%c", color, char) } go cmd.Room.SendMessage("m.text", html.String()) cmd.UI.Render() } func cmdQuit(cmd *Command) { - cmd.Gomuks.Stop() + cmd.Gomuks.Stop(true) } func cmdClearCache(cmd *Command) { cmd.Config.Clear() - cmd.Gomuks.Stop() + cmd.Gomuks.Stop(false) } func cmdUnknownCommand(cmd *Command) { -- cgit v1.2.3 From 160b035c4d5b88516cb4d1f4e26ec2e2e0262bcc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 15 Jun 2019 17:04:08 +0300 Subject: Unbreak more things --- ui/commands.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) (limited to 'ui/commands.go') diff --git a/ui/commands.go b/ui/commands.go index cd770b6..5d92969 100644 --- a/ui/commands.go +++ b/ui/commands.go @@ -21,8 +21,11 @@ import ( "fmt" "os" "runtime" + dbg "runtime/debug" "runtime/pprof" + "strconv" "strings" + "time" "unicode" "github.com/lucasb-eyer/go-colorful" @@ -71,15 +74,56 @@ var rainbow = GradientTable{ } func cmdHeapProfile(cmd *Command) { + dbg.FreeOSMemory() runtime.GC() - memProfile, err := os.Create("gomuks.prof") + memProfile, err := os.Create("gomuks.heap.prof") if err != nil { - debug.Print(err) + debug.Print("Failed to open gomuks.heap.prof:", err) + return } - defer memProfile.Close() + defer func() { + err := memProfile.Close() + if err != nil { + debug.Print("Failed to close gomuks.heap.prof:", err) + } + }() if err := pprof.WriteHeapProfile(memProfile); err != nil { - debug.Print(err) + debug.Print("Heap profile error:", err) + } +} + +func cmdCPUProfile(cmd *Command) { + if len(cmd.Args) == 0 { + cmd.Reply("Usage: /cprof ") + return + } + dur, err := strconv.Atoi(cmd.Args[0]) + if err != nil || dur < 0 { + cmd.Reply("Usage: /cprof ") + return } + cpuProfile, err := os.Create("gomuks.cpu.prof") + if err != nil { + debug.Print("Failed to open gomuks.cpu.prof:", err) + return + } + err = pprof.StartCPUProfile(cpuProfile) + if err != nil { + _ = cpuProfile.Close() + debug.Print("CPU profile error:", err) + return + } + cmd.Reply("Started CPU profiling for %d seconds", dur) + go func() { + time.Sleep(time.Duration(dur) * time.Second) + pprof.StopCPUProfile() + cmd.Reply("CPU profiling finished.") + + err := cpuProfile.Close() + if err != nil { + debug.Print("Failed to close gomuks.cpu.prof:", err) + } + }() } // TODO this command definitely belongs in a plugin once we have a plugin system. -- cgit v1.2.3 From 6bb932212cbadac6eed59ac153ebe041523f7570 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 15 Jun 2019 19:10:18 +0300 Subject: Add call trace command --- ui/commands.go | 57 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'ui/commands.go') diff --git a/ui/commands.go b/ui/commands.go index 5d92969..ab02735 100644 --- a/ui/commands.go +++ b/ui/commands.go @@ -19,10 +19,12 @@ package ui import ( "encoding/json" "fmt" + "io" "os" "runtime" dbg "runtime/debug" "runtime/pprof" + "runtime/trace" "strconv" "strings" "time" @@ -92,38 +94,37 @@ func cmdHeapProfile(cmd *Command) { } } -func cmdCPUProfile(cmd *Command) { +func runTimedProfile(cmd *Command, start func(writer io.Writer) error, stop func(), task, file string) { if len(cmd.Args) == 0 { - cmd.Reply("Usage: /cprof ") - return - } - dur, err := strconv.Atoi(cmd.Args[0]) - if err != nil || dur < 0 { - cmd.Reply("Usage: /cprof ") - return - } - cpuProfile, err := os.Create("gomuks.cpu.prof") - if err != nil { - debug.Print("Failed to open gomuks.cpu.prof:", err) - return - } - err = pprof.StartCPUProfile(cpuProfile) - if err != nil { + cmd.Reply("Usage: /%s ", cmd.Command) + } else if dur, err := strconv.Atoi(cmd.Args[0]); err != nil || dur < 0 { + cmd.Reply("Usage: /%s ", cmd.Command) + } else if cpuProfile, err := os.Create(file); err != nil { + debug.Printf("Failed to open %s: %v", file, err) + } else if err = start(cpuProfile); err != nil { _ = cpuProfile.Close() - debug.Print("CPU profile error:", err) - return + debug.Print(task, "error:", err) + } else { + cmd.Reply("Started %s for %d seconds", task, dur) + go func() { + time.Sleep(time.Duration(dur) * time.Second) + stop() + cmd.Reply("%s finished.", task) + + err := cpuProfile.Close() + if err != nil { + debug.Print("Failed to close gomuks.cpu.prof:", err) + } + }() } - cmd.Reply("Started CPU profiling for %d seconds", dur) - go func() { - time.Sleep(time.Duration(dur) * time.Second) - pprof.StopCPUProfile() - cmd.Reply("CPU profiling finished.") +} - err := cpuProfile.Close() - if err != nil { - debug.Print("Failed to close gomuks.cpu.prof:", err) - } - }() +func cmdCPUProfile(cmd *Command) { + runTimedProfile(cmd, pprof.StartCPUProfile, pprof.StopCPUProfile, "CPU profiling", "gomuks.cpu.prof") +} + +func cmdTrace(cmd *Command) { + runTimedProfile(cmd, trace.Start, trace.Stop, "Call tracing", "gomuks.trace") } // TODO this command definitely belongs in a plugin once we have a plugin system. -- cgit v1.2.3 From 2b7d5d54011ffcc93511bf05f44163a4b7a1270c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Jun 2019 14:29:03 +0300 Subject: Fix reply rendering infinite loop bug --- ui/commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/commands.go') diff --git a/ui/commands.go b/ui/commands.go index ab02735..0b15d8e 100644 --- a/ui/commands.go +++ b/ui/commands.go @@ -76,8 +76,8 @@ var rainbow = GradientTable{ } func cmdHeapProfile(cmd *Command) { - dbg.FreeOSMemory() runtime.GC() + dbg.FreeOSMemory() memProfile, err := os.Create("gomuks.heap.prof") if err != nil { debug.Print("Failed to open gomuks.heap.prof:", err) -- cgit v1.2.3