/
main.go
92 lines (72 loc) · 2.47 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package middleware
import (
"sync"
"github.com/jeroenrinzema/commander/internal/types"
)
// BeforeConsumeHandlerFunc represents the function method called and returned by a middleware client
type BeforeConsumeHandlerFunc = types.HandlerFunc
// BeforeProduceHandlerFunc represents the function method called and returned by a middleware client
type BeforeProduceHandlerFunc = func(*types.Message)
// ConsumeController middleware controller
type ConsumeController interface {
BeforeConsume(types.HandlerFunc) types.HandlerFunc
}
// ProduceController middleware controller
type ProduceController interface {
BeforeProduce(*types.Message) *types.Message
}
// Client middleware interface
type Client interface {
WrapBeforeConsume(BeforeConsumeHandlerFunc) BeforeConsumeHandlerFunc
WrapBeforeProduce(BeforeProduceHandlerFunc) BeforeProduceHandlerFunc
}
// UseImpl exposed usage interface.
// The interface could not be called Use due to type reference issues.
type UseImpl interface {
Use(interface{})
}
// NewClient constructs a new middleware client
func NewClient() UseImpl {
client := &client{
consume: []ConsumeController{},
produce: []ProduceController{},
}
return client
}
type client struct {
consume []ConsumeController
produce []ProduceController
mutex sync.RWMutex
}
// Use calles the given middleware controller to initialize the middleware
func (client *client) Use(value interface{}) {
client.mutex.Lock()
defer client.mutex.Unlock()
if controller, ok := value.(ConsumeController); ok {
client.consume = append(client.consume, controller)
}
if controller, ok := value.(ProduceController); ok {
client.produce = append(client.produce, controller)
}
}
// WrapBeforeConsume executes defined consume middleware in chronological order.
// A handle executable handler is returned once all middleware is wrapped.
func (client *client) WrapBeforeConsume(h types.HandlerFunc) types.HandlerFunc {
if len(client.consume) < 1 {
return h
}
wrapped := h
// loop in reverse to preserve middleware order
for i := len(client.consume) - 1; i >= 0; i-- {
wrapped = client.consume[i].BeforeConsume(wrapped)
}
return wrapped
}
// WrapBeforeProduce executes defined produce middleware in chronological order.
// A handle executable handler is returned once all middleware is wrapped.
func (client *client) WrapBeforeProduce(m *types.Message) {
// loop in reverse to preserve middleware order
for i := len(client.produce) - 1; i >= 0; i-- {
client.produce[i].BeforeProduce(m)
}
}