Make irc.Sender a function instead of coroutine.
Also, remove two channels that were used with this coroutine. This patch does not contain the necessary changes in bot package.configurable-file-paths
parent
ca3d3a2cc8
commit
30513fc0d5
56
irc/irc.go
56
irc/irc.go
|
@ -18,38 +18,29 @@ import (
|
|||
const delim byte = '\n'
|
||||
const endline string = "\r\n"
|
||||
|
||||
// Connection struct. Contains basic information about this connection, as well
|
||||
// as input and quit channels.
|
||||
// Connection struct. Contains basic information about this connection, and quit
|
||||
// channels.
|
||||
type Connection struct {
|
||||
network string
|
||||
input chan Message
|
||||
reader *bufio.Reader
|
||||
writer *bufio.Writer
|
||||
dispatcher func(chan Message, Message)
|
||||
dispatcher func(func(Message), Message)
|
||||
conn net.Conn
|
||||
reconnect chan struct{}
|
||||
reconnectCleanup chan struct{}
|
||||
Quit chan struct{}
|
||||
quitsend chan struct{}
|
||||
quitrecv chan struct{}
|
||||
quitkeeper chan struct{}
|
||||
l sync.Mutex
|
||||
}
|
||||
|
||||
// Sender sends IRC messages to server and logs their contents.
|
||||
func (c *Connection) Sender() {
|
||||
log.Println(c.network, "spawned Sender")
|
||||
for {
|
||||
select {
|
||||
case msg := <-c.input:
|
||||
c.writer.WriteString(msg.String() + endline)
|
||||
log.Println(c.network, "-->", msg.String())
|
||||
c.writer.Flush()
|
||||
case <-c.quitsend:
|
||||
log.Println(c.network, "closing Sender")
|
||||
return
|
||||
}
|
||||
}
|
||||
func (c *Connection) Sender(msg Message) {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
c.writer.WriteString(msg.String() + endline)
|
||||
log.Println(c.network, "-->", msg.String())
|
||||
c.writer.Flush()
|
||||
}
|
||||
|
||||
// Receiver receives IRC messages from server, logs their contents, sets message
|
||||
|
@ -57,7 +48,7 @@ func (c *Connection) Sender() {
|
|||
func (c *Connection) Receiver() {
|
||||
log.Println(c.network, "spawned Receiver")
|
||||
for {
|
||||
c.conn.SetReadDeadline(time.Now().Add(time.Second * 600))
|
||||
c.conn.SetDeadline(time.Now().Add(time.Second * 600))
|
||||
raw, err := c.reader.ReadString(delim)
|
||||
var src, tgt string
|
||||
|
||||
|
@ -96,7 +87,7 @@ func (c *Connection) Receiver() {
|
|||
"Target": tgt,
|
||||
}
|
||||
|
||||
c.dispatcher(c.input, *msg)
|
||||
c.dispatcher(c.Sender, *msg)
|
||||
select {
|
||||
case <-c.quitrecv:
|
||||
log.Println(c.network, "closing Receiver")
|
||||
|
@ -117,7 +108,6 @@ func (c *Connection) Cleaner() {
|
|||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
log.Println(c.network, "cleaning up!")
|
||||
c.quitsend <- struct{}{}
|
||||
c.quitrecv <- struct{}{}
|
||||
c.conn.Close()
|
||||
log.Println(c.network, "closing Cleaner")
|
||||
|
@ -126,7 +116,6 @@ func (c *Connection) Cleaner() {
|
|||
log.Println(c.network, "cleaning up before reconnect!")
|
||||
c.l.Lock()
|
||||
log.Println(c.network, "cleaning up!")
|
||||
c.quitsend <- struct{}{}
|
||||
c.quitrecv <- struct{}{}
|
||||
c.conn.Close()
|
||||
log.Println(c.network, "sending reconnect signal!")
|
||||
|
@ -137,7 +126,7 @@ func (c *Connection) Cleaner() {
|
|||
}
|
||||
|
||||
// Keeper makes sure that IRC connection is alive by reconnecting when
|
||||
// requested and restarting Sender, Receiver and Dispatcher goroutines.
|
||||
// requested and restarting Receiver goroutine.
|
||||
func (c *Connection) Keeper() {
|
||||
log.Println(c.network, "spawned Keeper")
|
||||
context := make(map[string]string)
|
||||
|
@ -145,9 +134,7 @@ func (c *Connection) Keeper() {
|
|||
for {
|
||||
select {
|
||||
case <-c.quitkeeper:
|
||||
if c.input != nil {
|
||||
close(c.input)
|
||||
close(c.quitsend)
|
||||
if c.quitrecv != nil {
|
||||
close(c.quitrecv)
|
||||
}
|
||||
return
|
||||
|
@ -155,13 +142,9 @@ func (c *Connection) Keeper() {
|
|||
}
|
||||
|
||||
c.l.Lock()
|
||||
if c.input != nil {
|
||||
close(c.input)
|
||||
close(c.quitsend)
|
||||
if c.quitrecv != nil {
|
||||
close(c.quitrecv)
|
||||
}
|
||||
c.input = make(chan Message, 1)
|
||||
c.quitsend = make(chan struct{}, 1)
|
||||
c.quitrecv = make(chan struct{}, 1)
|
||||
servers := cfg.LookupStringSlice(context, "Servers")
|
||||
|
||||
|
@ -170,19 +153,18 @@ func (c *Connection) Keeper() {
|
|||
err := c.Dial(server)
|
||||
c.l.Unlock()
|
||||
if err == nil {
|
||||
go c.Sender()
|
||||
go c.Receiver()
|
||||
|
||||
log.Println(c.network, "Initializing IRC connection")
|
||||
c.input <- Message{
|
||||
c.Sender(Message{
|
||||
Command: "NICK",
|
||||
Trailing: cfg.LookupString(context, "Nick"),
|
||||
}
|
||||
c.input <- Message{
|
||||
})
|
||||
c.Sender(Message{
|
||||
Command: "USER",
|
||||
Params: []string{cfg.LookupString(context, "User"), "0", "*"},
|
||||
Trailing: cfg.LookupString(context, "RealName"),
|
||||
}
|
||||
})
|
||||
} else {
|
||||
log.Println(c.network, "connection error", err.Error())
|
||||
c.reconnect <- struct{}{}
|
||||
|
@ -191,7 +173,7 @@ func (c *Connection) Keeper() {
|
|||
}
|
||||
|
||||
// Setup performs initialization tasks.
|
||||
func (c *Connection) Setup(dispatcher func(chan Message, Message), network string) {
|
||||
func (c *Connection) Setup(dispatcher func(func(Message), Message), network string) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
c.reconnect = make(chan struct{}, 1)
|
||||
|
|
Loading…
Reference in New Issue