- Timestamp:
- Aug 19, 2020, 5:42:33 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/conn.go
r384 r398 107 107 } 108 108 109 type rateLimiter struct { 110 C <-chan struct{} 111 ticker *time.Ticker 112 stopped chan struct{} 113 } 114 115 func newRateLimiter(delay time.Duration, burst int) *rateLimiter { 116 ch := make(chan struct{}, burst) 117 for i := 0; i < burst; i++ { 118 ch <- struct{}{} 119 } 120 ticker := time.NewTicker(delay) 121 stopped := make(chan struct{}) 122 go func() { 123 for { 124 select { 125 case <-ticker.C: 126 select { 127 case ch <- struct{}{}: 128 // This space is intentionally left blank 129 case <-stopped: 130 return 131 } 132 case <-stopped: 133 return 134 } 135 } 136 }() 137 return &rateLimiter{ 138 C: ch, 139 ticker: ticker, 140 stopped: stopped, 141 } 142 } 143 144 func (rl *rateLimiter) Stop() { 145 rl.ticker.Stop() 146 close(rl.stopped) 147 } 148 149 type connOptions struct { 150 Logger Logger 151 RateLimitDelay time.Duration 152 RateLimitBurst int 153 } 154 109 155 type conn struct { 110 156 conn ircConn … … 117 163 } 118 164 119 func newConn(srv *Server, ic ircConn, logger Logger) *conn {165 func newConn(srv *Server, ic ircConn, options *connOptions) *conn { 120 166 outgoing := make(chan *irc.Message, 64) 121 167 c := &conn{ … … 123 169 srv: srv, 124 170 outgoing: outgoing, 125 logger: logger,171 logger: options.Logger, 126 172 } 127 173 128 174 go func() { 175 var rl *rateLimiter 176 if options.RateLimitDelay > 0 && options.RateLimitBurst > 0 { 177 rl = newRateLimiter(options.RateLimitDelay, options.RateLimitBurst) 178 defer rl.Stop() 179 } 180 129 181 for msg := range outgoing { 182 if rl != nil { 183 <-rl.C 184 } 185 130 186 if c.srv.Debug { 131 187 c.logger.Printf("sent: %v", msg) -
trunk/downstream.go
r387 r398 103 103 remoteAddr := ic.RemoteAddr().String() 104 104 logger := &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", remoteAddr)} 105 options := connOptions{Logger: logger} 105 106 dc := &downstreamConn{ 106 conn: *newConn(srv, ic, logger),107 conn: *newConn(srv, ic, &options), 107 108 id: id, 108 109 supportedCaps: make(map[string]string), -
trunk/server.go
r385 r398 17 17 18 18 // TODO: make configurable 19 var retryConnect MinDelay = time.Minute19 var retryConnectDelay = time.Minute 20 20 var connectTimeout = 15 * time.Second 21 21 var writeTimeout = 10 * time.Second 22 var upstreamMessageDelay = 2 * time.Second 23 var upstreamMessageBurst = 10 22 24 23 25 type Logger interface { -
trunk/upstream.go
r396 r398 158 158 } 159 159 160 options := connOptions{ 161 Logger: logger, 162 RateLimitDelay: upstreamMessageDelay, 163 RateLimitBurst: upstreamMessageBurst, 164 } 165 160 166 uc := &upstreamConn{ 161 conn: *newConn(network.user.srv, newNetIRCConn(netConn), logger),167 conn: *newConn(network.user.srv, newNetIRCConn(netConn), &options), 162 168 network: network, 163 169 user: network.user, -
trunk/user.go
r395 r398 121 121 } 122 122 123 if dur := time.Now().Sub(lastTry); dur < retryConnect MinDelay {124 delay := retryConnect MinDelay - dur123 if dur := time.Now().Sub(lastTry); dur < retryConnectDelay { 124 delay := retryConnectDelay - dur 125 125 net.user.srv.Logger.Printf("waiting %v before trying to reconnect to %q", delay.Truncate(time.Second), net.Addr) 126 126 time.Sleep(delay)
Note:
See TracChangeset
for help on using the changeset viewer.