Merge pull request #40 from slingamn/no_callback_timeout

remove support for CallbackTimeout
This commit is contained in:
Shivaram Lingamneni 2021-02-23 18:18:04 -05:00 committed by GitHub
commit a1973eec96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 81 deletions

@ -1,7 +1,6 @@
package ircevent
import (
"context"
"fmt"
"log"
"runtime/debug"
@ -93,6 +92,14 @@ func (irc *Connection) getCallbacks(code string) (result []Callback) {
// Execute all callbacks associated with a given event.
func (irc *Connection) runCallbacks(msg ircmsg.IRCMessage) {
if !irc.AllowPanic {
defer func() {
if r := recover(); r != nil {
log.Printf("Caught panic in callback: %v\n%s", r, debug.Stack())
}
}()
}
event := Event{IRCMessage: msg}
if irc.EnableCTCP {
@ -100,62 +107,12 @@ func (irc *Connection) runCallbacks(msg ircmsg.IRCMessage) {
}
callbacks := irc.getCallbacks(event.Command)
if len(callbacks) == 0 {
return
// just run the callbacks in serial, since it's not safe for them
// to take a long time to execute in any case
for _, callback := range callbacks {
callback(event)
}
if irc.CallbackTimeout == 0 {
// just run the callbacks in serial in this case;
// it's not safe for them to take a long time anyway
if !irc.AllowPanic {
defer func() {
if r := recover(); r != nil {
log.Printf("Caught panic in callback: %v\n%s", r, debug.Stack())
}
}()
}
for _, callback := range callbacks {
callback(event)
}
} else {
event.Ctx = context.Background()
ctx, cancel := context.WithTimeout(event.Ctx, irc.CallbackTimeout)
event.Ctx = ctx
defer cancel()
remaining := len(callbacks)
done := make(chan empty, remaining)
for _, callback := range callbacks {
go runCallbackConcurrent(event, callback, done, irc.Log, irc.AllowPanic)
}
for remaining > 0 {
select {
case <-done:
remaining--
case <-event.Ctx.Done():
irc.Log.Printf("Timeout on %s while waiting for %d callback(s)\n", event.Command, remaining)
return
}
}
}
}
func runCallbackConcurrent(event Event, callback Callback, done chan empty, log *log.Logger, allowPanic bool) {
if !allowPanic {
defer func() {
if r := recover(); r != nil {
if !allowPanic {
log.Printf("Caught panic in callback: %v\n%s", r, debug.Stack())
}
}
}()
}
callback(event)
done <- empty{}
}
// Set up some initial callbacks to handle the IRC/CTCP protocol.

@ -5,7 +5,6 @@
package ircevent
import (
"context"
"crypto/tls"
"log"
"net"
@ -27,29 +26,28 @@ type capResult struct {
type Connection struct {
// config data, user-settable
Server string
TLSConfig *tls.Config
Nick string
User string
RealName string // IRC realname/gecos
WebIRC []string // parameters for the WEBIRC command
Password string // server password (PASS command)
RequestCaps []string // IRCv3 capabilities to request (failure is non-fatal)
SASLLogin string // SASL credentials to log in with (failure is fatal)
SASLPassword string
SASLMech string
QuitMessage string
Version string
Timeout time.Duration
KeepAlive time.Duration
ReconnectFreq time.Duration
CallbackTimeout time.Duration
MaxLineLen int // maximum line length, not including tags
UseTLS bool
UseSASL bool
EnableCTCP bool
Debug bool
AllowPanic bool // if set, don't recover() from panics in callbacks
Server string
TLSConfig *tls.Config
Nick string
User string
RealName string // IRC realname/gecos
WebIRC []string // parameters for the WEBIRC command
Password string // server password (PASS command)
RequestCaps []string // IRCv3 capabilities to request (failure is non-fatal)
SASLLogin string // SASL credentials to log in with (failure is fatal)
SASLPassword string
SASLMech string
QuitMessage string
Version string
Timeout time.Duration
KeepAlive time.Duration
ReconnectFreq time.Duration
MaxLineLen int // maximum line length, not including tags
UseTLS bool
UseSASL bool
EnableCTCP bool
Debug bool
AllowPanic bool // if set, don't recover() from panics in callbacks
// networking and synchronization
stateMutex sync.Mutex // innermost mutex: don't block while holding this
@ -86,7 +84,6 @@ type Connection struct {
// A struct to represent an event.
type Event struct {
ircmsg.IRCMessage
Ctx context.Context
}
// Retrieve the last message from Event arguments.