From 881f2194a3cca7cbc58dd241b4e3cc43439d7a53 Mon Sep 17 00:00:00 2001 From: "diamondburned (Forefront)" Date: Sat, 20 Jun 2020 00:28:47 -0700 Subject: [PATCH] Added proper session disconnections --- go.mod | 2 +- go.sum | 2 ++ internal/gts/gts.go | 25 ++++++++++++++++++++----- internal/log/log.go | 4 ++++ internal/ui/ui.go | 24 ++++++++++++++++++------ main.go | 1 + 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 790e345..d614acf 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ replace github.com/gotk3/gotk3 => github.com/diamondburned/gotk3 v0.0.0-20200619 require ( github.com/Xuanwo/go-locale v0.2.0 - github.com/diamondburned/cchat v0.0.31 + github.com/diamondburned/cchat v0.0.32 github.com/diamondburned/cchat-discord v0.0.0-20200619222738-e5babcbb42e3 github.com/diamondburned/cchat-mock v0.0.0-20200615015702-8cac8b16378d github.com/diamondburned/imgutil v0.0.0-20200611215339-650ac7cfaf64 diff --git a/go.sum b/go.sum index ec121f7..9453feb 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/diamondburned/cchat v0.0.28 h1:+1VnltW0rl8/NZTUP+x89jVhi3YTTR+e6iLprZ github.com/diamondburned/cchat v0.0.28/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU= github.com/diamondburned/cchat v0.0.31 h1:yUgrh5xbGX0R55glyxYtVewIDL2eXLJ+okIEfVaVoFk= github.com/diamondburned/cchat v0.0.31/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU= +github.com/diamondburned/cchat v0.0.32 h1:nLiD4sL9+DLBnvNb9XLidd5peRzTgM9lWcqRsUmm474= +github.com/diamondburned/cchat v0.0.32/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU= github.com/diamondburned/cchat-discord v0.0.0-20200619222738-e5babcbb42e3 h1:8RCcaY3gtA+8NG2mwkcC/PIFK+eS8XnGyeVaUbCXbF0= github.com/diamondburned/cchat-discord v0.0.0-20200619222738-e5babcbb42e3/go.mod h1:4q0jHEl1gJEzkS92oacwcSf9+3fFcNPukOpURDJpV/A= github.com/diamondburned/cchat-mock v0.0.0-20200615015702-8cac8b16378d h1:LkzARyvdGRvAsaKEPTV3XcqMHENH6J+KRAI+3sq41Qs= diff --git a/internal/gts/gts.go b/internal/gts/gts.go index 0d23d30..2f3a8dc 100644 --- a/internal/gts/gts.go +++ b/internal/gts/gts.go @@ -53,7 +53,7 @@ func init() { type WindowHeaderer interface { Window() gtk.IWidget Header() gtk.IWidget - Destroy() + Close() } func Main(wfn func() WindowHeaderer) { @@ -71,22 +71,37 @@ func Main(wfn func() WindowHeaderer) { App.Window, _ = gtk.ApplicationWindowNew(App.Application) App.Window.SetDefaultSize(1000, 500) App.Window.SetTitlebar(App.Header) - App.Window.Connect("destroy", App.Application.Quit) + App.Window.Show() // Execute the function later, because we need it to run after // initialization. w := wfn() - App.Window.Connect("destroy", w.Destroy) App.Window.Add(w.Window()) App.Header.Add(w.Header()) - // Connect extra events. + // Connect extra actions. AddAppAction("quit", App.Window.Destroy) + + // Connect the destructor. + App.Window.Connect("destroy", func() { + // Hide the application window. + App.Window.Hide() + + // Let the main loop run once by queueing the stop loop afterwards. + // This is to allow the main loop to properly hide the Gtk window + // before trying to disconnect. + ExecAsync(func() { + // Stop the application loop. + App.Application.Quit() + // Finalize the application by running the closer. + w.Close() + }) + }) }) // Use a special function to run the application. Exit with the appropriate - // exit code. + // exit code if necessary. if code := App.Run(Args); code > 0 { os.Exit(code) } diff --git a/internal/log/log.go b/internal/log/log.go index 4c651f8..4b92488 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -76,3 +76,7 @@ func WriteEntry(entry Entry) { func Println(v ...interface{}) { log.Println(v...) } + +func Printlnf(f string, v ...interface{}) { + log.Printf(f+"\n", v...) +} diff --git a/internal/ui/ui.go b/internal/ui/ui.go index ca636b1..a6c7c04 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -3,6 +3,7 @@ package ui import ( "github.com/diamondburned/cchat" "github.com/diamondburned/cchat-gtk/internal/gts" + "github.com/diamondburned/cchat-gtk/internal/log" "github.com/diamondburned/cchat-gtk/internal/ui/config/preferences" "github.com/diamondburned/cchat-gtk/internal/ui/messages" "github.com/diamondburned/cchat-gtk/internal/ui/service" @@ -11,6 +12,7 @@ import ( "github.com/diamondburned/cchat-gtk/internal/ui/service/session/server" "github.com/gotk3/gotk3/gtk" "github.com/markbates/pkger" + "github.com/pkg/errors" ) func init() { @@ -118,12 +120,22 @@ func (app *App) AuthenticateSession(container *service.Container, svc cchat.Serv }) } -// Destroy is called when the main window is destroyed or closed. -func (app *App) Destroy() { - // Disconnect everything. - for _, service := range app.window.Services.Services { - for _, session := range service.Sessions() { - session.DisconnectSession() +// Close is called when the application finishes gracefully. +func (app *App) Close() { + // Disconnect everything. This blocks the main thread, so by the time we're + // done, the application would exit immediately. There's no need to update + // the GUI. + for _, s := range app.window.Services.Services { + for _, session := range s.Sessions() { + if session.Session == nil { + continue + } + + log.Printlnf("Disconnecting %s session %s", s.Service.Name(), session.ID()) + + if err := session.Session.Disconnect(); err != nil { + log.Error(errors.Wrap(err, "Failed to disconnect "+session.ID())) + } } } } diff --git a/main.go b/main.go index 0d7a6b5..5bba24e 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( _ "github.com/diamondburned/cchat-mock" ) +// destructor is used for debugging and profiling. var destructor = func() {} func main() {