44package logstream
55
66import (
7- "bytes"
87 "context"
98 "fmt"
109 "net"
1110 "sync"
12- "time"
1311
1412 "github.com/golang/glog"
1513 "github.com/google/mtail/internal/logline"
@@ -55,8 +53,7 @@ func (ds *dgramStream) stream(ctx context.Context, wg *sync.WaitGroup, waker wak
5553 return err
5654 }
5755 glog .V (2 ).Infof ("stream(%s): opened new datagram socket %v" , ds .sourcename , c )
58- b := make ([]byte , datagramReadBufferSize )
59- partial := bytes .NewBufferString ("" )
56+ lr := NewLineReader (ds .sourcename , ds .lines , & dgramConn {c }, datagramReadBufferSize , ds .cancel )
6057 var total int
6158 wg .Add (1 )
6259 go func () {
@@ -70,6 +67,7 @@ func (ds *dgramStream) stream(ctx context.Context, wg *sync.WaitGroup, waker wak
7067 glog .Info (err )
7168 }
7269 logCloses .Add (ds .address , 1 )
70+ lr .Finish (ctx )
7371 close (ds .lines )
7472 ds .cancel ()
7573 }()
@@ -78,40 +76,27 @@ func (ds *dgramStream) stream(ctx context.Context, wg *sync.WaitGroup, waker wak
7876 SetReadDeadlineOnDone (ctx , c )
7977
8078 for {
81- n , _ , err := c . ReadFrom ( b )
79+ n , err := lr . ReadAndSend ( ctx )
8280 glog .V (2 ).Infof ("stream(%s): read %d bytes, err is %v" , ds .sourcename , n , err )
8381
84- if ds .staleTimer != nil {
85- ds .staleTimer .Stop ()
86- }
87-
8882 // This is a test-only trick that says if we've already put this
8983 // logstream in graceful shutdown, then a zero-byte read is
9084 // equivalent to an "EOF" in connection and file oriented streams.
9185 if n == 0 {
9286 if oneShot {
9387 glog .V (2 ).Infof ("stream(%s): exiting because zero byte read and one shot" , ds .sourcename )
94- if partial .Len () > 0 {
95- ds .sendLine (ctx , partial )
96- }
9788 return
9889 }
9990 select {
10091 case <- ctx .Done ():
10192 glog .V (2 ).Infof ("stream(%s): exiting because zero byte read after cancellation" , ds .sourcename )
102- if partial .Len () > 0 {
103- ds .sendLine (ctx , partial )
104- }
10593 return
10694 default :
10795 }
10896 }
10997
11098 if n > 0 {
11199 total += n
112- //nolint:contextcheck
113- ds .decodeAndSend (ctx , n , b [:n ], partial )
114- ds .staleTimer = time .AfterFunc (time .Hour * 24 , ds .cancel )
115100
116101 // No error implies more to read, so restart the loop.
117102 if err == nil && ctx .Err () == nil {
@@ -120,9 +105,6 @@ func (ds *dgramStream) stream(ctx context.Context, wg *sync.WaitGroup, waker wak
120105 }
121106
122107 if IsExitableError (err ) {
123- if partial .Len () > 0 {
124- ds .sendLine (ctx , partial )
125- }
126108 glog .V (2 ).Infof ("stream(%s): exiting, stream has error %s" , ds .sourcename , err )
127109 return
128110 }
@@ -146,3 +128,14 @@ func (ds *dgramStream) stream(ctx context.Context, wg *sync.WaitGroup, waker wak
146128 }()
147129 return nil
148130}
131+
132+ // dgramConn wraps a PacketConn to add a Read method.
133+ type dgramConn struct {
134+ net.PacketConn
135+ }
136+
137+ // Read satisfies io.Reader
138+ func (d * dgramConn ) Read (p []byte ) (count int , err error ) {
139+ count , _ , err = d .ReadFrom (p )
140+ return
141+ }
0 commit comments