-
Notifications
You must be signed in to change notification settings - Fork 70
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
progressutil: refactor to use channels #64
Conversation
By setting the value during the Read call, we potentially miss errors in the CopyProgressPrinter's main loop, because the copyReader might have not yet propagated them before it marks itself as done.
@s-urbaniak @alban @jonboulle PTAL |
select { | ||
case <-cpp.cancel: | ||
return | ||
case cpp.results <- err: |
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.
Nit, either return from both case statements or from neither (it is redundant, since go case statements do not fall through by default, but I'd accept that it helps clarify to keep them)
LGTM overall |
lgtm agreeing to the above review statements. |
errors []error | ||
results chan error | ||
cancel chan struct{} | ||
|
||
lock sync.Mutex |
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.
please document which fields are being protected.
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.
@s-urbaniak aiui this is communicated through the struct layout - the lock protects the members listed immediately after it, and if there are multiple locks the struct members are grouped into blocks separated by an empty line. Wdyt?
4168203
to
b950939
Compare
Rather than maintaining a list of results and individual synchronised booleans signifying goroutine completion, just use a single channel to propagate the result of each copyReader. This means we can use a for/select loop as His Lord and Holiness Rob Pike always intended. Notably, it is now explicitly prohibited to: i) add additional copy operations to a CopyProgressPrinter after it has been started (i.e. after PrintAndWait has been called) ii) call PrintAndWait more than once If either of these is attempted, ErrAlreadyStarted is returned. To achieve i), we would need to either change the interface of the CopyProgressPrinter to accept a pre-defined size (i.e. number of copy operations), or other sychronise the "shutting down" of the CopyProgressPrinter (i.e. to block further copies being added just before the CopyProgressPrinter is about to return - otherwise we can never be sure that another will not be added as we're finishing). Both of these seem overly complex for now and I suggest we only explore them if use cases arise. Similarly, ii) would require more delicate refactoring and it's hard to imagine a use case since this package is typically designed to be used with a single output stream (i.e. stdout). Adding the safety check in this PR helps to mitigate potential abuse of the package, though (e.g. appc/docker2aci#167)
b950939
to
b9db3b6
Compare
Rebased. |
lgtm, ship it |
Rather than maintaining a list of results and individual synchronised
booleans signifying goroutine completion, just use a single channel to
propagate the result of each copyReader
This is a rebased version of #62 and #63, and supercedes both.