Move middleware interface into stack, testable handlers

This commit is contained in:
Ethan Frey
2017-06-30 18:37:50 +02:00
parent 4d0db39fb9
commit 7b5e41adf6
6 changed files with 85 additions and 29 deletions
+53 -1
View File
@@ -1,12 +1,15 @@
package stack
import (
"github.com/pkg/errors"
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/types"
)
const (
NameVoid = "void"
NameVoid = "void"
NameFail = "fail"
NamePanic = "panic"
)
// voidHandler just used to return okay to everything
@@ -27,3 +30,52 @@ func (_ voidHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basec
func (_ voidHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
return
}
// failHandler always returns an error
type failHandler struct {
err error
}
var _ basecoin.Handler = failHandler{}
func (_ failHandler) Name() string {
return NameFail
}
// CheckTx always returns the given error
func (f failHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
return res, errors.WithStack(f.err)
}
// DeliverTx always returns the given error
func (f failHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
return res, errors.WithStack(f.err)
}
// panicHandler always panics, using the given error (first choice) or msg (fallback)
type panicHandler struct {
msg string
err error
}
var _ basecoin.Handler = panicHandler{}
func (_ panicHandler) Name() string {
return NamePanic
}
// CheckTx always panics
func (p panicHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
if p.err != nil {
panic(p.err)
}
panic(p.msg)
}
// DeliverTx always panics
func (p panicHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
if p.err != nil {
panic(p.err)
}
panic(p.msg)
}
+24
View File
@@ -0,0 +1,24 @@
package stack
import (
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/types"
)
type CheckerMiddle interface {
CheckTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Checker) (basecoin.Result, error)
}
type DeliverMiddle interface {
DeliverTx(ctx basecoin.Context, store types.KVStore, tx basecoin.Tx, next basecoin.Deliver) (basecoin.Result, error)
}
// Middleware is anything that wraps another handler to enhance functionality.
//
// You can use utilities in handlers to construct them, the interfaces
// are exposed in the top-level package to avoid import loops.
type Middleware interface {
CheckerMiddle
DeliverMiddle
basecoin.Named
}
+4 -4
View File
@@ -9,7 +9,7 @@ import (
//
// heavily inspired by negroni's design
type middleware struct {
middleware basecoin.Middleware
middleware Middleware
next basecoin.Handler
}
@@ -39,7 +39,7 @@ func (m *middleware) DeliverTx(ctx basecoin.Context, store types.KVStore, tx bas
// Stack is the entire application stack
type Stack struct {
middles []basecoin.Middleware
middles []Middleware
handler basecoin.Handler
basecoin.Handler // the compiled version, which we expose
}
@@ -48,7 +48,7 @@ var _ basecoin.Handler = &Stack{}
// NewStack prepares a middleware stack, you must `.Use()` a Handler
// before you can execute it.
func NewStack(middlewares ...basecoin.Middleware) *Stack {
func NewStack(middlewares ...Middleware) *Stack {
return &Stack{
middles: middlewares,
}
@@ -64,7 +64,7 @@ func (s *Stack) Use(handler basecoin.Handler) *Stack {
return s
}
func build(mid []basecoin.Middleware, end basecoin.Handler) basecoin.Handler {
func build(mid []Middleware, end basecoin.Handler) basecoin.Handler {
if len(mid) == 0 {
return end
}