From e2fe5d084ef784800b6134d0c9c491ed1c89e4d7 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Fri, 16 Jun 2017 14:42:43 -0600 Subject: [PATCH] git/githistory/log: teach Durable() to Task --- git/githistory/log/log.go | 14 +++++++++++++- git/githistory/log/log_test.go | 30 ++++++++++++++++++++++++++++++ git/githistory/log/task.go | 12 ++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/git/githistory/log/log.go b/git/githistory/log/log.go index 5ff146c4..1f77d6e8 100644 --- a/git/githistory/log/log.go +++ b/git/githistory/log/log.go @@ -175,16 +175,28 @@ func (l *Logger) consume() { // logTask logs the set of updates from a given task to the sink, then logs a // "done" message, and then marks the task as done. +// +// By default, the *Logger throttles log entry updates to once per the duration +// of time specified by `l.throttle time.Duration`. +// +// If the duration if 0, or the task is "durable" (by implementing +// github.com/git-lfs/git-lfs/git/githistory/log#DurableTask), then all entries +// will be logged. func (l *Logger) logTask(task Task) { defer l.wg.Done() + var logAll bool + if durable, ok := task.(DurableTask); ok { + logAll = durable.Durable() + } + var last time.Time var msg string for msg = range task.Updates() { now := time.Now() - if l.throttle == 0 || now.After(last.Add(l.throttle)) { + if logAll || l.throttle == 0 || now.After(last.Add(l.throttle)) { l.logLine(msg) last = now } diff --git a/git/githistory/log/log_test.go b/git/githistory/log/log_test.go index 4ab34166..59b57260 100644 --- a/git/githistory/log/log_test.go +++ b/git/githistory/log/log_test.go @@ -13,6 +13,12 @@ type ChanTask chan string func (e ChanTask) Updates() <-chan string { return e } +type DurableChanTask chan string + +func (e DurableChanTask) Updates() <-chan string { return e } + +func (e DurableChanTask) Durable() bool { return true } + func TestLoggerLogsTasks(t *testing.T) { var buf bytes.Buffer @@ -140,3 +146,27 @@ func TestLoggerThrottlesLastWrite(t *testing.T) { "second, done\n", }, ""), buf.String()) } + +func TestLoggerLogsAllDurableUpdates(t *testing.T) { + var buf bytes.Buffer + + l := NewLogger(&buf) + l.widthFn = func() int { return 0 } + l.throttle = 15 * time.Minute + + t1 := make(chan string) + go func() { + t1 <- "first" // t = 0+ε ms, throttle is open + t1 <- "second" // t = 0+2ε ms, throttle is closed + close(t1) // t = 0+3ε ms, throttle is closed + }() + + l.enqueue(DurableChanTask(t1)) + l.Close() + + assert.Equal(t, strings.Join([]string{ + "first\r", + "second\r", + "second, done\n", + }, ""), buf.String()) +} diff --git a/git/githistory/log/task.go b/git/githistory/log/task.go index 22a8c475..83ca7efc 100644 --- a/git/githistory/log/task.go +++ b/git/githistory/log/task.go @@ -7,3 +7,15 @@ type Task interface { // complete. Updates() <-chan string } + +// DurableTask is a Task sub-interface which ensures that all activity is +// logged by disabling throttling behavior in the logger. +type DurableTask interface { + Task + + // Durable returns whether or not this task should be treated as + // Durable. + // + // It is expected to return the same value for a given Task instance. + Durable() bool +}