-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update go-concert to 0.1.0 #23770
Update go-concert to 0.1.0 #23770
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,18 +18,19 @@ | |
package filestream | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"io" | ||
"os" | ||
"time" | ||
|
||
"github.com/elastic/go-concert/ctxtool" | ||
"github.com/elastic/go-concert/timed" | ||
"github.com/elastic/go-concert/unison" | ||
|
||
input "github.com/elastic/beats/v7/filebeat/input/v2" | ||
"github.com/elastic/beats/v7/libbeat/common/backoff" | ||
"github.com/elastic/beats/v7/libbeat/common/file" | ||
"github.com/elastic/beats/v7/libbeat/logp" | ||
"github.com/elastic/go-concert/ctxtool" | ||
"github.com/elastic/go-concert/unison" | ||
) | ||
|
||
var ( | ||
|
@@ -39,10 +40,9 @@ var ( | |
|
||
// logFile contains all log related data | ||
type logFile struct { | ||
file *os.File | ||
log *logp.Logger | ||
ctx context.Context | ||
cancelReading context.CancelFunc | ||
file *os.File | ||
log *logp.Logger | ||
readerCtx ctxtool.CancelContext | ||
|
||
closeAfterInterval time.Duration | ||
closeOnEOF bool | ||
|
@@ -55,7 +55,7 @@ type logFile struct { | |
offset int64 | ||
lastTimeRead time.Time | ||
backoff backoff.Backoff | ||
tg unison.TaskGroup | ||
tg *unison.TaskGroup | ||
} | ||
|
||
// newFileReader creates a new log instance to read log sources | ||
|
@@ -71,6 +71,9 @@ func newFileReader( | |
return nil, err | ||
} | ||
|
||
readerCtx := ctxtool.WithCancelContext(ctxtool.FromCanceller(canceler)) | ||
tg := unison.TaskGroupWithCancel(readerCtx) | ||
|
||
l := &logFile{ | ||
file: f, | ||
log: log, | ||
|
@@ -83,16 +86,10 @@ func newFileReader( | |
offset: offset, | ||
lastTimeRead: time.Now(), | ||
backoff: backoff.NewExpBackoff(canceler.Done(), config.Backoff.Init, config.Backoff.Max), | ||
tg: unison.TaskGroup{}, | ||
readerCtx: readerCtx, | ||
tg: tg, | ||
} | ||
|
||
l.ctx, l.cancelReading = ctxtool.WithFunc(ctxtool.FromCanceller(canceler), func() { | ||
err := l.tg.Stop() | ||
if err != nil { | ||
l.log.Errorf("Error while stopping filestream logFile reader: %v", err) | ||
} | ||
}) | ||
|
||
l.startFileMonitoringIfNeeded() | ||
|
||
return l, nil | ||
|
@@ -103,7 +100,7 @@ func newFileReader( | |
func (f *logFile) Read(buf []byte) (int, error) { | ||
totalN := 0 | ||
|
||
for f.ctx.Err() == nil { | ||
for f.readerCtx.Err() == nil { | ||
n, err := f.file.Read(buf) | ||
if n > 0 { | ||
f.offset += int64(n) | ||
|
@@ -154,35 +151,18 @@ func (f *logFile) startFileMonitoringIfNeeded() { | |
} | ||
|
||
func (f *logFile) closeIfTimeout(ctx unison.Canceler) { | ||
timer := time.NewTimer(f.closeAfterInterval) | ||
defer timer.Stop() | ||
|
||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
case <-timer.C: | ||
f.cancelReading() | ||
return | ||
} | ||
if err := timed.Wait(ctx, f.closeAfterInterval); err == nil { | ||
f.readerCtx.Cancel() | ||
} | ||
} | ||
|
||
func (f *logFile) periodicStateCheck(ctx unison.Canceler) { | ||
ticker := time.NewTicker(f.checkInterval) | ||
defer ticker.Stop() | ||
|
||
for { | ||
select { | ||
case <-ctx.Done(): | ||
return | ||
case <-ticker.C: | ||
if f.shouldBeClosed() { | ||
f.cancelReading() | ||
return | ||
} | ||
timed.Periodic(ctx, f.checkInterval, func() error { | ||
if f.shouldBeClosed() { | ||
f.readerCtx.Cancel() | ||
} | ||
} | ||
return nil | ||
}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replaced the for loop with |
||
} | ||
|
||
func (f *logFile) shouldBeClosed() bool { | ||
|
@@ -267,6 +247,8 @@ func (f *logFile) handleEOF() error { | |
|
||
// Close | ||
func (f *logFile) Close() error { | ||
f.cancelReading() | ||
return f.file.Close() | ||
f.readerCtx.Cancel() | ||
err := f.file.Close() | ||
f.tg.Stop() // Wait until all resources are released for sure. | ||
return err | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,26 +72,29 @@ func (l *Listener) Run(ctx context.Context) error { | |
l.log.Info("Started listening for " + l.family.String() + " connection") | ||
|
||
for ctx.Err() == nil { | ||
conn, err := l.listener() | ||
if err != nil { | ||
l.log.Debugw("Cannot connect", "error", err) | ||
continue | ||
} | ||
connCtx, connCancel := ctxtool.WithFunc(ctx, func() { | ||
conn.Close() | ||
}) | ||
|
||
err = l.run(connCtx, conn) | ||
if err != nil { | ||
l.log.Debugw("Error while processing input", "error", err) | ||
connCancel() | ||
continue | ||
} | ||
connCancel() | ||
l.doRun(ctx) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. moved the body into a separate method, so we can do TODO: shall we consider to recover from a panic here or only recover if the handler failed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the package I would only call recover to take care of panics from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
yeah, I did mean the handler. Added |
||
} | ||
return nil | ||
} | ||
|
||
func (l *Listener) doRun(ctx context.Context) { | ||
conn, err := l.listener() | ||
if err != nil { | ||
l.log.Debugw("Cannot connect", "error", err) | ||
return | ||
} | ||
|
||
connCtx, connCancel := ctxtool.WithFunc(ctx, func() { | ||
conn.Close() | ||
}) | ||
defer connCancel() | ||
|
||
err = l.connectAndRun(connCtx, conn) | ||
if err != nil { | ||
l.log.Debugw("Error while processing input", "error", err) | ||
} | ||
} | ||
|
||
func (l *Listener) Start() error { | ||
l.log.Info("Started listening for " + l.family.String() + " connection") | ||
|
||
|
@@ -106,12 +109,14 @@ func (l *Listener) Start() error { | |
}) | ||
defer connCancel() | ||
|
||
return l.run(ctxtool.FromCanceller(connCtx), conn) | ||
return l.connectAndRun(ctxtool.FromCanceller(connCtx), conn) | ||
}) | ||
return nil | ||
} | ||
|
||
func (l *Listener) run(ctx context.Context, conn net.PacketConn) error { | ||
func (l *Listener) connectAndRun(ctx context.Context, conn net.PacketConn) error { | ||
defer l.log.Recover("Panic handling datagram") | ||
|
||
handler := l.connect(*l.config) | ||
for ctx.Err() == nil { | ||
err := handler(ctx, conn) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The group now shuts down when the
readerCtx
gets cancelled. This is a slight change in semantics, as the reader context was closed in the past only after the taskgroup go-routines have finished (Stop used to wait).In order to make behavior and signal propagation a little more predictable, the change ensures that we have a clear chain of cancellation contexts:
canceler -> readerCtx -> (taskgroup ctx)
. Before we used to have something like: