Last active
August 29, 2015 14:20
-
-
Save dadamssg/676772c41f992327fe54 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package CommandBus | |
import ( | |
"reflect" | |
"sort" | |
"sync" | |
) | |
type HandlerFunc func(cmd interface{}) | |
type middlewareFunc func(cmd interface{}, next HandlerFunc) | |
type middleware struct { | |
function middlewareFunc | |
priority int | |
} | |
type byPriority []middleware | |
func (slice byPriority) Len() int { | |
return len(slice) | |
} | |
func (slice byPriority) Less(i, j int) bool { | |
return slice[i].priority > slice[j].priority | |
} | |
func (slice byPriority) Swap(i, j int) { | |
slice[i], slice[j] = slice[j], slice[i] | |
} | |
type commandBus struct { | |
handlers map[reflect.Type]HandlerFunc | |
middlewares []middleware | |
lock sync.Mutex | |
} | |
func (bus *commandBus) RegisterHandler(cmd interface{}, handler HandlerFunc) { | |
bus.lock.Lock() | |
defer bus.lock.Unlock() | |
bus.handlers[reflect.TypeOf(cmd)] = handler | |
} | |
func (bus *commandBus) AddMiddleware(priority int, function middlewareFunc) { | |
bus.lock.Lock() | |
defer bus.lock.Unlock() | |
bus.middlewares = append(bus.middlewares, middleware{function: function, priority: priority}) | |
sort.Sort(byPriority(bus.middlewares)) | |
} | |
func (bus commandBus) Handle(cmd interface{}) { | |
bus.lock.Lock() | |
defer bus.lock.Unlock() | |
handler := bus.getNext(0) | |
handler(cmd) | |
} | |
func (bus commandBus) getNext(index int) HandlerFunc { | |
if len(bus.middlewares) >= (index + 1) { | |
middleware := bus.middlewares[index] | |
return func(cmd interface{}) { | |
middleware.function(cmd, bus.getNext(index+1)) | |
} | |
} | |
return func(cmd interface{}) { | |
handler := bus.getHandler(cmd) | |
if handler != nil { | |
handler(cmd) | |
} | |
} | |
} | |
func (bus commandBus) getHandler(cmd interface{}) HandlerFunc { | |
t := reflect.TypeOf(cmd) | |
for kind, handler := range bus.handlers { | |
if t == kind { | |
return handler | |
} | |
} | |
return nil | |
} | |
func New() *commandBus { | |
return &commandBus{ | |
handlers: make(map[reflect.Type]HandlerFunc), | |
middlewares: make([]middleware, 0), | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"github.com/dadamssg/CommandBus" | |
) | |
type RegisterUserCommand struct { | |
Username string | |
} | |
type ConfirmUserCommand struct { | |
Username string | |
} | |
func main() { | |
bus := CommandBus.New() | |
bus.RegisterHandler(&RegisterUserCommand{}, func(cmd interface{}) { | |
command, _ := cmd.(*RegisterUserCommand) | |
fmt.Println("Registered: ", command.Username) | |
}) | |
bus.AddMiddleware(0, func(cmd interface{}, next HandlerFunc) { | |
fmt.Println("Enter mock logging middleware") | |
next(cmd) | |
fmt.Println("Exit mock logging middleware") | |
}) | |
bus.AddMiddleware(0, func(cmd interface{}, next HandlerFunc) { | |
fmt.Println("Enter mock caching middleware") | |
next(cmd) | |
fmt.Println("Exit mock caching middleware") | |
}) | |
bus.Handle(&RegisterUserCommand{ | |
Username: "David", | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Enter mock logging middleware | |
Enter mock caching middleware | |
Registered: David | |
Exit mock caching middleware | |
Exit mock logging middleware |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment