-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
42 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package utils | ||
|
||
import "context" | ||
import ( | ||
"context" | ||
) | ||
|
||
func IsCanceled(ctx context.Context) bool { | ||
select { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package utils | ||
|
||
import ( | ||
"context" | ||
"io" | ||
) | ||
|
||
// here is some syntaxic sugar inspired by the Tomas Senart's video, | ||
// it allows me to inline the Reader interface | ||
type readerFunc func(p []byte) (n int, err error) | ||
|
||
func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) } | ||
|
||
// CopyWithCtx slightly modified function signature: | ||
// - context has been added in order to propagate cancelation | ||
// - I do not return the number of bytes written, has it is not useful in my use case | ||
func CopyWithCtx(ctx context.Context, out io.Writer, in io.Reader) error { | ||
// Copy will call the Reader and Writer interface multiple time, in order | ||
// to copy by chunk (avoiding loading the whole file in memory). | ||
// I insert the ability to cancel before read time as it is the earliest | ||
// possible in the call process. | ||
_, err := io.Copy(out, readerFunc(func(p []byte) (int, error) { | ||
// golang non-blocking channel: https://gobyexample.com/non-blocking-channel-operations | ||
select { | ||
// if context has been canceled | ||
case <-ctx.Done(): | ||
// stop process and propagate "context canceled" error | ||
return 0, ctx.Err() | ||
default: | ||
// otherwise just run default io.Reader implementation | ||
return in.Read(p) | ||
} | ||
})) | ||
return err | ||
} |