github.com/blend/go-sdk@v1.20220411.3/web/timeout.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package web
     9  
    10  import (
    11  	"context"
    12  	"net/http"
    13  	"time"
    14  )
    15  
    16  // WithTimeout injects the context for a given action with a timeout context.
    17  func WithTimeout(d time.Duration) Middleware {
    18  	return func(action Action) Action {
    19  		return func(r *Ctx) Result {
    20  			ctx, cancel := context.WithTimeout(r.Context(), d)
    21  			defer cancel()
    22  
    23  			r.Request = r.Request.WithContext(ctx)
    24  
    25  			panicChan := make(chan interface{}, 1)
    26  			resultChan := make(chan Result, 1)
    27  
    28  			go func() {
    29  				defer func() {
    30  					if p := recover(); p != nil {
    31  						panicChan <- p
    32  					}
    33  				}()
    34  				resultChan <- action(r)
    35  			}()
    36  
    37  			select {
    38  			case p := <-panicChan:
    39  				panic(p)
    40  			case res := <-resultChan:
    41  				return res
    42  			case <-ctx.Done():
    43  				return r.DefaultProvider.Status(http.StatusServiceUnavailable, nil)
    44  			}
    45  		}
    46  	}
    47  }