Improve gRPC error handling, handle cancelling ffmpegReader
This commit is contained in:
parent
06697dc1b1
commit
1496473620
|
@ -33,6 +33,13 @@ func newFfmpegReader(ctx context.Context, input io.Reader, arg ...string) (*ffmp
|
|||
return &ffmpegReader{ReadCloser: r, cmd: cmd}, nil
|
||||
}
|
||||
|
||||
func (r *ffmpegReader) Cancel() error {
|
||||
if err := r.cmd.Process.Kill(); err != nil {
|
||||
return fmt.Errorf("error killing ffmpeg process: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *ffmpegReader) Close() error {
|
||||
state, err := r.cmd.Process.Wait()
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ func (s *MediaSetService) getAudioFromYoutube(ctx context.Context, mediaSet stor
|
|||
type getAudioFromYoutubeState struct {
|
||||
*fetchAudioProgressReader
|
||||
|
||||
ffmpegReader io.ReadCloser
|
||||
ffmpegReader *ffmpegReader
|
||||
uploader *multipartUploadWriter
|
||||
s3Bucket, s3Key string
|
||||
store Store
|
||||
|
@ -404,6 +404,12 @@ outer:
|
|||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if cancelErr := s.ffmpegReader.Cancel(); cancelErr != nil {
|
||||
log.Printf("error cancelling ffmpegreader: %v", cancelErr)
|
||||
}
|
||||
}
|
||||
|
||||
if readerErr := s.ffmpegReader.Close(); readerErr != nil {
|
||||
if err == nil {
|
||||
err = readerErr
|
||||
|
|
|
@ -17,25 +17,43 @@ import (
|
|||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
type ResponseError struct {
|
||||
error
|
||||
func init() {
|
||||
grpclog.SetLogger(log.New(os.Stdout, "server: ", log.LstdFlags))
|
||||
}
|
||||
|
||||
ResponseCode codes.Code
|
||||
const (
|
||||
// ts-proto generates code that automatically retries for a subset of gRPC
|
||||
// response codes. To avoid invoking this behaviour, default to returning a
|
||||
// Cancelled code. Later,
|
||||
// See https://github.com/stephenh/ts-proto/blob/459b94f5b2988d58d186461332e888c3e511603a/src/generate-grpc-web.ts#L293
|
||||
// and https://github.com/stephenh/ts-proto/pull/131.
|
||||
defaultResponseCode = codes.Canceled
|
||||
defaultResponseMessage = "An unexpected error occurred"
|
||||
)
|
||||
|
||||
type ResponseError struct {
|
||||
err error
|
||||
s string
|
||||
}
|
||||
|
||||
func (r *ResponseError) Error() string {
|
||||
return fmt.Sprintf("An unexpected error occurred: %v (error code = %d).", r.error.Error(), r.ResponseCode)
|
||||
return fmt.Sprintf("unexpected error: %v", r.err.Error())
|
||||
}
|
||||
|
||||
func (r *ResponseError) Unwrap() error {
|
||||
return r.error
|
||||
return r.err
|
||||
}
|
||||
|
||||
func newResponseError(err error, code codes.Code) *ResponseError {
|
||||
return &ResponseError{error: err, ResponseCode: code}
|
||||
func (r *ResponseError) GRPCStatus() *status.Status {
|
||||
return status.New(defaultResponseCode, r.s)
|
||||
}
|
||||
|
||||
func newResponseError(err error) *ResponseError {
|
||||
return &ResponseError{err: err, s: defaultResponseMessage}
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
|
@ -61,7 +79,7 @@ type mediaSetServiceController struct {
|
|||
func (c *mediaSetServiceController) Get(ctx context.Context, request *pbMediaSet.GetRequest) (*pbMediaSet.MediaSet, error) {
|
||||
mediaSet, err := c.mediaSetService.Get(ctx, request.GetYoutubeId())
|
||||
if err != nil {
|
||||
return nil, newResponseError(err, codes.Unknown)
|
||||
return nil, newResponseError(err)
|
||||
}
|
||||
|
||||
result := pbMediaSet.MediaSet{
|
||||
|
@ -88,12 +106,12 @@ func (c *mediaSetServiceController) GetAudio(request *pbMediaSet.GetAudioRequest
|
|||
|
||||
id, err := uuid.Parse(request.GetId())
|
||||
if err != nil {
|
||||
return newResponseError(err, codes.Unknown)
|
||||
return newResponseError(err)
|
||||
}
|
||||
|
||||
reader, err := c.mediaSetService.GetAudio(ctx, id, int(request.GetNumBins()))
|
||||
if err != nil {
|
||||
return newResponseError(err, codes.Unknown)
|
||||
return newResponseError(err)
|
||||
}
|
||||
|
||||
for {
|
||||
|
@ -102,7 +120,7 @@ func (c *mediaSetServiceController) GetAudio(request *pbMediaSet.GetAudioRequest
|
|||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return newResponseError(err, codes.Unknown)
|
||||
return newResponseError(err)
|
||||
}
|
||||
|
||||
// TODO: consider using int32 throughout the backend flow to avoid this.
|
||||
|
@ -128,7 +146,6 @@ func Start(options Options) error {
|
|||
fetchMediaSetService := media.NewMediaSetService(options.Store, options.YoutubeClient, options.S3Client)
|
||||
|
||||
pbMediaSet.RegisterMediaSetServiceServer(grpcServer, &mediaSetServiceController{mediaSetService: fetchMediaSetService})
|
||||
grpclog.SetLogger(log.New(os.Stdout, "server: ", log.LstdFlags))
|
||||
|
||||
// TODO: proper CORS support
|
||||
grpcWebServer := grpcweb.WrapServer(grpcServer, grpcweb.WithOriginFunc(func(string) bool { return true }))
|
||||
|
|
Loading…
Reference in New Issue