-
Notifications
You must be signed in to change notification settings - Fork 899
fix(cli): port-forward: update workspace last_used_at #12659
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
Changes from 1 commit
279f874
8f9b945
e8c842c
86704a1
c99327c
5876edd
e4e0311
958d1d1
a36aeb9
692f666
d794e00
45a0eef
8e40efd
591e1ab
0caaf3a
cc72868
f5f8d75
a2e716d
5b64f96
23ccf21
c9ac9d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
package workspaceusage | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"flag" | ||
"os" | ||
"sort" | ||
"strings" | ||
"sync" | ||
"time" | ||
|
||
|
@@ -84,16 +85,22 @@ func WithFlushInterval(d time.Duration) Option { | |
|
||
// WithFlushChannel allows passing a channel that receives | ||
// the number of marked workspaces every time Tracker flushes. | ||
// For testing only. | ||
// For testing only and will panic if used outside of tests. | ||
func WithFlushChannel(c chan int) Option { | ||
if flag.Lookup("test.v") == nil { | ||
panic("developer error: WithFlushChannel is not to be used outside of tests.") | ||
} | ||
return func(h *Tracker) { | ||
h.flushCh = c | ||
} | ||
} | ||
|
||
// WithTickChannel allows passing a channel to replace a ticker. | ||
// For testing only. | ||
// For testing only and will panic if used outside of tests. | ||
func WithTickChannel(c chan time.Time) Option { | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if flag.Lookup("test.v") == nil { | ||
panic("developer error: WithTickChannel is not to be used outside of tests.") | ||
} | ||
return func(h *Tracker) { | ||
h.tickCh = c | ||
h.stopTick = func() {} | ||
|
@@ -125,11 +132,6 @@ func (wut *Tracker) flush(now time.Time) { | |
return | ||
} | ||
|
||
// For ease of testing, sort the IDs lexically | ||
sort.Slice(ids, func(i, j int) bool { | ||
// For some unfathomable reason, byte arrays are not comparable? | ||
return strings.Compare(ids[i].String(), ids[j].String()) < 0 | ||
}) | ||
// Set a short-ish timeout for this. We don't want to hang forever. | ||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer cancel() | ||
|
@@ -147,7 +149,15 @@ func (wut *Tracker) flush(now time.Time) { | |
wut.log.Info(ctx, "updated workspaces last_used_at", slog.F("count", count), slog.F("now", now)) | ||
} | ||
|
||
// Loop periodically flushes every tick. | ||
// If Loop is called after Close, it will panic. Don't do this. | ||
func (wut *Tracker) Loop() { | ||
// Calling Loop after Close() is an error. | ||
select { | ||
case <-wut.doneCh: | ||
panic("developer error: Loop called after Close") | ||
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. If we need to do this instead of just returning, I'd prefer returning an error here, wouldn't want this to happen for a production instance after some changes to the code. Feels like this mostly exists for tests (otherwise could be launched 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. If we return an error, then we have two options:
I don't think 2) is a valid option. We're not guaranteed to catch it in tests especially because of the possibility of ignoring errors in There's an alternative possibility 1a) where we check the error and recreate the tracker if non-nil. WDYT? 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. I forgot about option c) - have |
||
default: | ||
} | ||
defer func() { | ||
wut.log.Debug(context.Background(), "workspace usage tracker loop exited") | ||
}() | ||
|
@@ -165,7 +175,8 @@ func (wut *Tracker) Loop() { | |
} | ||
} | ||
|
||
// Close stops Tracker and performs a final flush. | ||
// Close stops Tracker and returns once Loop has exited. | ||
// After calling Close(), Loop must not be called. | ||
func (wut *Tracker) Close() { | ||
wut.stopOnce.Do(func() { | ||
wut.stopCh <- struct{}{} | ||
|
@@ -202,6 +213,11 @@ func (s *uuidSet) UniqueAndClear() []uuid.UUID { | |
for k := range s.m { | ||
l = append(l, k) | ||
} | ||
// For ease of testing, sort the IDs lexically | ||
sort.Slice(l, func(i, j int) bool { | ||
// For some unfathomable reason, byte arrays are not comparable? | ||
return bytes.Compare(l[i][:], l[j][:]) < 0 | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) | ||
s.m = make(map[uuid.UUID]struct{}) | ||
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return l | ||
} |
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.
Nice strictness check! Feels like this could be a testutil func, even if obvious.