GetContextWithCancel creates a new context with cancellation capabilities. It embeds the Gin context and the API handler into the new context for later use. The returned cancel function also handles logging the API response if request logging is enabled. Parameters: - handler: The API handler assoc
(handler interfaces.APIHandler, c *gin.Context, ctx context.Context)
| 520 | // - context.Context: The new context with cancellation and embedded values. |
| 521 | // - APIHandlerCancelFunc: A function to cancel the context and log the response. |
| 522 | func (h *BaseAPIHandler) GetContextWithCancel(handler interfaces.APIHandler, c *gin.Context, ctx context.Context) (context.Context, APIHandlerCancelFunc) { |
| 523 | parentCtx := ctx |
| 524 | if parentCtx == nil { |
| 525 | parentCtx = context.Background() |
| 526 | } |
| 527 | |
| 528 | var requestCtx context.Context |
| 529 | if c != nil && c.Request != nil { |
| 530 | requestCtx = c.Request.Context() |
| 531 | } |
| 532 | |
| 533 | if requestCtx != nil && logging.GetRequestID(parentCtx) == "" { |
| 534 | if requestID := logging.GetRequestID(requestCtx); requestID != "" { |
| 535 | parentCtx = logging.WithRequestID(parentCtx, requestID) |
| 536 | } else if requestID = logging.GetGinRequestID(c); requestID != "" { |
| 537 | parentCtx = logging.WithRequestID(parentCtx, requestID) |
| 538 | } |
| 539 | } |
| 540 | newCtx, cancel := context.WithCancel(parentCtx) |
| 541 | |
| 542 | endpoint := "" |
| 543 | if c != nil && c.Request != nil { |
| 544 | path := strings.TrimSpace(c.FullPath()) |
| 545 | if path == "" && c.Request.URL != nil { |
| 546 | path = strings.TrimSpace(c.Request.URL.Path) |
| 547 | } |
| 548 | if path != "" { |
| 549 | method := strings.TrimSpace(c.Request.Method) |
| 550 | if method != "" { |
| 551 | endpoint = method + " " + path |
| 552 | } else { |
| 553 | endpoint = path |
| 554 | } |
| 555 | } |
| 556 | } |
| 557 | if endpoint != "" { |
| 558 | newCtx = logging.WithEndpoint(newCtx, endpoint) |
| 559 | } |
| 560 | newCtx = logging.WithResponseStatusHolder(newCtx) |
| 561 | newCtx = logging.WithResponseHeadersHolder(newCtx) |
| 562 | |
| 563 | cancelCtx := newCtx |
| 564 | if requestCtx != nil && requestCtx != parentCtx { |
| 565 | go func() { |
| 566 | select { |
| 567 | case <-requestCtx.Done(): |
| 568 | cancel() |
| 569 | case <-cancelCtx.Done(): |
| 570 | } |
| 571 | }() |
| 572 | } |
| 573 | newCtx = context.WithValue(newCtx, "gin", c) |
| 574 | newCtx = context.WithValue(newCtx, "handler", handler) |
| 575 | return newCtx, func(params ...interface{}) { |
| 576 | if c != nil { |
| 577 | logging.SetResponseStatus(cancelCtx, c.Writer.Status()) |
| 578 | } |
| 579 | if h.Cfg.RequestLog && len(params) == 1 { |
no test coverage detected