From 05b8be7a4b8aa3ff571f0a5729642779ff893575 Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Mon, 29 Jul 2019 20:44:50 -0400 Subject: [PATCH] provide direct quit reason support (closes #16) --- client.go | 12 ++++++++++++ conn.go | 24 ++++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/client.go b/client.go index 805afec..f803575 100644 --- a/client.go +++ b/client.go @@ -351,6 +351,18 @@ func (c *Client) Close() { c.mu.RUnlock() } +// Quit sends a QUIT message to the server with a given reason to close the +// connection. Underlying this event being sent, Client.Close() is called as well. +// This is different than just calling Client.Close() in that it provides a reason +// as to why the connection was closed (for bots to tell users the bot is restarting, +// or shutting down, etc). +// +// NOTE: servers may delay showing of QUIT reasons, until you've been connected to +// the server for a certain period of time (e.g. 5 minutes). Keep this in mind. +func (c *Client) Quit(reason string) { + c.Send(&Event{Command: QUIT, Params: []string{reason}}) +} + // ErrEvent is an error returned when the server (or library) sends an ERROR // message response. The string returned contains the trailing text from the // message. diff --git a/conn.go b/conn.go index ba6f8aa..441c3e7 100644 --- a/conn.go +++ b/conn.go @@ -455,22 +455,20 @@ func (c *Client) Send(event *Event) { } <-time.After(delay) - - // Relock client again as there may be an extended delay. - c.mu.RLock() - if c.conn == nil { - // Drop the event if disconnected. - c.debugLogEvent(event, true) - c.mu.RUnlock() - return - } c.write(event) - c.mu.RUnlock() } // write is the lower level function to write an event. It does not have a // write-delay when sending events. func (c *Client) write(event *Event) { + c.mu.RLock() + defer c.mu.RUnlock() + + if c.conn == nil { + // Drop the event if disconnected. + c.debugLogEvent(event, true) + return + } c.tx <- event } @@ -538,6 +536,12 @@ func (c *Client) sendLoop(ctx context.Context, errs chan error, wg *sync.WaitGro } } + if event.Command == QUIT { + c.Close() + wg.Done() + return + } + if err != nil { errs <- err wg.Done()