Changeset 33 in code for trunk


Ignore:
Timestamp:
Feb 6, 2020, 9:46:46 PM (5 years ago)
Author:
contact
Message:

Use a dedicated goroutine to write upstream messages

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/upstream.go

    r27 r33  
    2929        irc      *irc.Conn
    3030        srv      *Server
     31        messages chan<- *irc.Message
    3132
    3233        serverName            string
     
    3637
    3738        registered bool
     39        closed     bool
    3840        modes      modeSet
    3941        channels   map[string]*upstreamChannel
     42}
     43
     44func connectToUpstream(s *Server, upstream *Upstream) (*upstreamConn, error) {
     45        logger := &prefixLogger{s.Logger, fmt.Sprintf("upstream %q: ", upstream.Addr)}
     46        logger.Printf("connecting to server")
     47
     48        netConn, err := tls.Dial("tcp", upstream.Addr, nil)
     49        if err != nil {
     50                return nil, fmt.Errorf("failed to dial %q: %v", upstream.Addr, err)
     51        }
     52
     53        msgs := make(chan *irc.Message, 64)
     54        conn := &upstreamConn{
     55                upstream: upstream,
     56                logger:   logger,
     57                net:      netConn,
     58                irc:      irc.NewConn(netConn),
     59                srv:      s,
     60                messages: msgs,
     61                channels: make(map[string]*upstreamChannel),
     62        }
     63
     64        go func() {
     65                for msg := range msgs {
     66                        if err := conn.irc.WriteMessage(msg); err != nil {
     67                                conn.logger.Printf("failed to write message: %v", err)
     68                        }
     69                }
     70        }()
     71
     72        return conn, nil
     73}
     74
     75func (c *upstreamConn) Close() error {
     76        if c.closed {
     77                return fmt.Errorf("upstream connection already closed")
     78        }
     79        if err := c.net.Close(); err != nil {
     80                return err
     81        }
     82        close(c.messages)
     83        c.closed = true
     84        return nil
    4085}
    4186
     
    5297        case "PING":
    5398                // TODO: handle params
    54                 return c.irc.WriteMessage(&irc.Message{
     99                c.messages <- &irc.Message{
    55100                        Command: "PONG",
    56101                        Params:  []string{c.srv.Hostname},
    57                 })
     102                }
     103                return nil
    58104        case "MODE":
    59105                if len(msg.Params) < 2 {
     
    71117
    72118                for _, ch := range c.upstream.Channels {
    73                         err := c.irc.WriteMessage(&irc.Message{
     119                        c.messages <- &irc.Message{
    74120                                Command: "JOIN",
    75121                                Params:  []string{ch},
    76                         })
    77                         if err != nil {
    78                                 return err
    79122                        }
    80123                }
     
    192235
    193236func (c *upstreamConn) readMessages() error {
    194         defer c.net.Close()
    195 
    196         err := c.irc.WriteMessage(&irc.Message{
     237        defer c.Close()
     238
     239        c.messages <- &irc.Message{
    197240                Command: "NICK",
    198241                Params:  []string{c.upstream.Nick},
    199         })
    200         if err != nil {
    201                 return err
    202         }
    203 
    204         err = c.irc.WriteMessage(&irc.Message{
     242        }
     243
     244        c.messages <- &irc.Message{
    205245                Command: "USER",
    206246                Params:  []string{c.upstream.Username, "0", "*", c.upstream.Realname},
    207         })
    208         if err != nil {
    209                 return err
    210247        }
    211248
     
    223260        }
    224261
    225         return c.net.Close()
    226 }
    227 
    228 func connectToUpstream(s *Server, upstream *Upstream) (*upstreamConn, error) {
    229         logger := &prefixLogger{s.Logger, fmt.Sprintf("upstream %q: ", upstream.Addr)}
    230         logger.Printf("connecting to server")
    231 
    232         netConn, err := tls.Dial("tcp", upstream.Addr, nil)
    233         if err != nil {
    234                 return nil, fmt.Errorf("failed to dial %q: %v", upstream.Addr, err)
    235         }
    236 
    237         return &upstreamConn{
    238                 upstream: upstream,
    239                 logger:   logger,
    240                 net:      netConn,
    241                 irc:      irc.NewConn(netConn),
    242                 srv:      s,
    243                 channels: make(map[string]*upstreamChannel),
    244         }, nil
    245 }
     262        return c.Close()
     263}
Note: See TracChangeset for help on using the changeset viewer.