Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add (*Client).RunContext to allow for cancelation #64

Merged
merged 2 commits into from
Apr 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ functions and other additions will most likely not result in a major
version increase unless they break the API. This library aims to
follow the semver recommendations mentioned on gopkg.in.

Due to complications in how to support x/net/context vs the built-in context
package, only go 1.7+ is officially supported.

## Import Paths

All development happens on the `master` branch and when features are
Expand Down
18 changes: 15 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package irc

import (
"context"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -357,6 +358,12 @@ func (c *Client) startReadLoop(wg *sync.WaitGroup) {
// strange and unexpected ways if it is called again before the first connection
// exits.
func (c *Client) Run() error {
return c.RunContext(context.TODO())
}

// RunContext is the same as Run but a context.Context can be passed in for
// cancelation.
func (c *Client) RunContext(ctx context.Context) error {
// exiting is used by the main goroutine here to ensure any sub-goroutines
// get closed when exiting.
exiting := make(chan struct{})
Expand All @@ -382,9 +389,14 @@ func (c *Client) Run() error {
// messages.
c.startReadLoop(&wg)

// Wait for an error from any goroutine, then signal we're exiting and wait
// for the goroutines to exit.
err := <-c.errChan
// Wait for an error from any goroutine or for the context to time out, then
// signal we're exiting and wait for the goroutines to exit.
var err error
select {
case err = <-c.errChan:
case <-ctx.Done():
}

close(exiting)
wg.Wait()

Expand Down