From d307d127bff93294f8d05dc334c857cb7dc6aa58 Mon Sep 17 00:00:00 2001 From: Marc MacLeod Date: Sun, 14 Dec 2014 14:47:43 -0500 Subject: [PATCH 1/2] MiddlewareChain implements Middleware interface If, during ProcessRequest, a middleware returns a response or error, don't process the rest of the chain. --- middleware/chain.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/middleware/chain.go b/middleware/chain.go index fca387d..3e9ce5b 100644 --- a/middleware/chain.go +++ b/middleware/chain.go @@ -3,6 +3,7 @@ package middleware import ( "fmt" . "github.com/mailgun/vulcan/request" + "net/http" "sort" "sync" ) @@ -49,6 +50,25 @@ func (c *MiddlewareChain) GetIter() *MiddlewareIter { } } +func (c *MiddlewareChain) ProcessRequest(r Request) (*http.Response, error) { + it := c.chain.getIter() + for v := it.next(); v != nil; v = it.next() { + resp, err := v.(Middleware).ProcessRequest(r) + if resp != nil || err != nil { + break + return resp, err + } + } + return nil, nil +} + +func (c *MiddlewareChain) ProcessResponse(r Request, a Attempt) { + it := c.chain.getReverseIter() + for v := it.next(); v != nil; v = it.next() { + v.(Middleware).ProcessResponse(r, a) + } +} + type MiddlewareIter struct { iter *iter } From ba137ab61ae846273287e88f5ae9ff1f1847a716 Mon Sep 17 00:00:00 2001 From: Marc MacLeod Date: Sun, 14 Dec 2014 14:47:43 -0500 Subject: [PATCH 2/2] MiddlewareChain implements Middleware interface If, during ProcessRequest, a middleware returns a response or error, don't process the rest of the chain. During ProcessResponse, only call the middleware that was called in ProcessResponse. --- middleware/chain.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/middleware/chain.go b/middleware/chain.go index fca387d..9623dba 100644 --- a/middleware/chain.go +++ b/middleware/chain.go @@ -3,6 +3,7 @@ package middleware import ( "fmt" . "github.com/mailgun/vulcan/request" + "net/http" "sort" "sync" ) @@ -49,6 +50,32 @@ func (c *MiddlewareChain) GetIter() *MiddlewareIter { } } +func (c *MiddlewareChain) ProcessRequest(r Request) (*http.Response, error) { + it := c.chain.getIter() + for v := it.next(); v != nil; v = it.next() { + // Track how deep we've gotten in the middleware chain + c.chain.callDepth = it.index + 1 + resp, err := v.(Middleware).ProcessRequest(r) + if resp != nil || err != nil { + break + return resp, err + } + } + return nil, nil +} + +func (c *MiddlewareChain) ProcessResponse(r Request, a Attempt) { + it := c.chain.getReverseIter() + + // Set the iterator to start at the furthest spot we got in the chain during ProcessRequest + currentIndex := c.chain.callDepth + it.index = len(it.callbacks) - currentIndex + + for v := it.next(); v != nil; v = it.next() { + v.(Middleware).ProcessResponse(r, a) + } +} + type MiddlewareIter struct { iter *iter } @@ -122,6 +149,7 @@ func (c *ObserverChain) ObserveResponse(r Request, a Attempt) { type chain struct { mutex *sync.RWMutex callbacks []*callback + callDepth int // how deep into the chain we get on ProcessRequest / ObserveRequest. 1 based indexes map[string]int // Indexes for in place updates iter *iter //current version of iterator }