Skip to content

Commit

Permalink
Allow setting final next on routers
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertWHurst committed Jan 17, 2024
1 parent db96ed8 commit 3af1c1b
Showing 1 changed file with 19 additions and 25 deletions.
44 changes: 19 additions & 25 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ type Context struct {
hasWrittenHeaders bool
hasWrittenBody bool

Error error
ErrorStack string
Error error
ErrorStack string
FinalError error
FinalErrorStack string

FinalNext func()

requestBodyUnmarshaller func(into any) error
responseBodyMarshaller func(from any) ([]byte, error)
Expand All @@ -44,11 +48,8 @@ type Context struct {
currentHandlerOrTransformerIndex int
currentHandlerOrTransformer any

deadline *time.Time
untilFinishedHandlers []func()

finalNext func()
finalError error
deadline *time.Time
doneHandlers []func()
}

var contextData = make(map[*Context]map[string]any)
Expand All @@ -74,9 +75,7 @@ func NewContext(responseWriter http.ResponseWriter, request *http.Request, first
next: firstHandlerNode,
},

deadline: nil,
untilFinishedHandlers: []func(){},
finalError: nil,
doneHandlers: []func(){},
}
}

Expand All @@ -95,7 +94,7 @@ func NewSubContext(ctx *Context, firstHandlerNode *handlerNode, finalNext func()
subContext.matchingHandlerNode = nil
subContext.currentHandlerOrTransformerIndex = 0
subContext.currentHandlerOrTransformer = nil
subContext.finalNext = finalNext
subContext.FinalNext = finalNext
return &subContext
}

Expand All @@ -110,7 +109,7 @@ func (c *Context) Next() {
defer func() {
c.tryUpdateParent()
if shouldRunFinalNext {
c.finalNext()
c.FinalNext()
}
}()

Expand Down Expand Up @@ -306,27 +305,21 @@ func (c *Context) Deadline() (time.Time, bool) {
return deadline, ok
}

// UntilFinish returns a channel that returns an empty struct once the request
// has been processed and the response has been sent.
func (c *Context) UntilFinish() <-chan struct{} {
// Done added for compatibility with go's context.Context. Alias for
// UntilFinish().
func (c *Context) Done() <-chan struct{} {
doneChan := make(chan struct{})
c.untilFinishedHandlers = append(c.untilFinishedHandlers, func() {
c.doneHandlers = append(c.doneHandlers, func() {
doneChan <- struct{}{}
})
return doneChan
}

// Done added for compatibility with go's context.Context. Alias for
// UntilFinish().
func (c *Context) Done() <-chan struct{} {
return c.UntilFinish()
}

// Err returns the final error of the request. Will be nil if the request
// is still being served even if an error has occurred. Populated once the
// request is done.
func (c *Context) Err() error {
return c.finalError
return c.FinalError
}

// Value is a noop for compatibility with go's context.Context.
Expand Down Expand Up @@ -440,8 +433,9 @@ func (c *Context) tryMatchHandlerNode(node *handlerNode) bool {
}

func (c *Context) markDone() {
c.finalError = c.Error
for _, doneHandler := range c.untilFinishedHandlers {
c.FinalError = c.Error
c.FinalErrorStack = c.ErrorStack
for _, doneHandler := range c.doneHandlers {
doneHandler()
}
}
Expand Down

0 comments on commit 3af1c1b

Please sign in to comment.