@@ -3,6 +3,7 @@ package eventsource
3
3
import (
4
4
"context"
5
5
"io"
6
+ "log"
6
7
"net/http"
7
8
"sync"
8
9
"time"
@@ -11,15 +12,14 @@ import (
11
12
// Client wraps an http connection and converts it to an
12
13
// event stream.
13
14
type Client struct {
14
- flush http.Flusher
15
- write io.Writer
16
- ctx context.Context
17
- events chan Event
18
- closed bool
19
- waiter sync.WaitGroup
20
- lock sync.Mutex
21
- lastFlush uint64
22
- lastWrite uint64
15
+ flusher http.Flusher
16
+ write io.Writer
17
+ ctx context.Context
18
+ events chan Event
19
+ closed bool
20
+ waiter sync.WaitGroup
21
+ lock sync.Mutex
22
+ flushing * time.Timer
23
23
}
24
24
25
25
// NewClient creates a client wrapping a response writer.
@@ -35,11 +35,11 @@ func NewClient(w http.ResponseWriter, req *http.Request) *Client {
35
35
}
36
36
37
37
// Check to ensure we support flushing
38
- flush , ok := w .(http.Flusher )
38
+ flusher , ok := w .(http.Flusher )
39
39
if ! ok {
40
40
return nil
41
41
}
42
- c .flush = flush
42
+ c .flusher = flusher
43
43
44
44
c .ctx = req .Context ()
45
45
@@ -49,12 +49,11 @@ func NewClient(w http.ResponseWriter, req *http.Request) *Client {
49
49
if req == nil || req .ProtoMajor < 2 {
50
50
w .Header ().Set ("Connection" , "keep-alive" )
51
51
}
52
- flush .Flush ()
52
+ flusher .Flush ()
53
53
54
54
// start the sending thread
55
- c .waiter .Add (2 )
55
+ c .waiter .Add (1 )
56
56
go c .run ()
57
- go c .flusher ()
58
57
return c
59
58
}
60
59
@@ -115,7 +114,9 @@ func (c *Client) run() {
115
114
// send the event
116
115
c .lock .Lock ()
117
116
io .Copy (c .write , & ev )
118
- c .lastWrite += 1
117
+ if c .flushing == nil {
118
+ c .flushing = time .AfterFunc (100 * time .Millisecond , c .flush )
119
+ }
119
120
c .lock .Unlock ()
120
121
121
122
case <- done :
@@ -128,19 +129,13 @@ func (c *Client) run() {
128
129
}
129
130
130
131
// flusher amortizes flushing costs for high activity SSE channels
131
- func (c * Client ) flusher () {
132
- for {
133
- time .Sleep (100 * time .Millisecond )
134
- c .lock .Lock ()
135
- if c .closed {
136
- break
137
- }
138
- if c .lastFlush < c .lastWrite {
139
- c .lastFlush = c .lastWrite
140
- c .flush .Flush ()
141
- }
142
- c .lock .Unlock ()
132
+ func (c * Client ) flush () {
133
+ c .lock .Lock ()
134
+ log .Println ("flushing!" )
135
+ defer c .lock .Unlock ()
136
+ if c .closed {
137
+ return
143
138
}
144
-
145
- c .waiter . Done ()
139
+ c . flushing = nil
140
+ c .flusher . Flush ()
146
141
}
0 commit comments