From b4cf837d8adc447233bac47e3425d5a3bcda87a5 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 2 Mar 2021 15:21:32 -0800 Subject: [PATCH] logtail: use link monitor to determine when to retry after upload failure Signed-off-by: Brad Fitzpatrick --- logtail/logtail.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/logtail/logtail.go b/logtail/logtail.go index e0e9f93be..d9ed73532 100644 --- a/logtail/logtail.go +++ b/logtail/logtail.go @@ -18,6 +18,7 @@ import ( "time" "tailscale.com/logtail/backoff" + "tailscale.com/net/interfaces" tslogger "tailscale.com/types/logger" "tailscale.com/wgengine/monitor" ) @@ -287,6 +288,11 @@ func (l *Logger) uploading(ctx context.Context) { } uploaded, err := l.upload(ctx, body, origlen) if err != nil { + if !l.internetUp() { + fmt.Fprintf(l.stderr, "logtail: internet down; waiting\n") + l.awaitInternetUp(ctx) + continue + } fmt.Fprintf(l.stderr, "logtail: upload: %v\n", err) } l.bo.BackOff(ctx, err) @@ -303,6 +309,34 @@ func (l *Logger) uploading(ctx context.Context) { } } +func (l *Logger) internetUp() bool { + if l.linkMonitor == nil { + // No way to tell, so assume it is. + return true + } + return l.linkMonitor.InterfaceState().AnyInterfaceUp() +} + +func (l *Logger) awaitInternetUp(ctx context.Context) { + upc := make(chan bool, 1) + defer l.linkMonitor.RegisterChangeCallback(func(changed bool, st *interfaces.State) { + if st.AnyInterfaceUp() { + select { + case upc <- true: + default: + } + } + })() + if l.internetUp() { + return + } + select { + case <-upc: + fmt.Fprintf(l.stderr, "logtail: internet back up\n") + case <-ctx.Done(): + } +} + // upload uploads body to the log server. // origlen indicates the pre-compression body length. // origlen of -1 indicates that the body is not compressed.