Make order be decided first; Remove TMSP Commit/Rollback

This commit is contained in:
Jae Kwon
2016-01-06 17:14:20 -08:00
committed by Jae Kwon
parent 792759c414
commit 3e3c0083c7
17 changed files with 388 additions and 514 deletions

View File

@ -6,16 +6,15 @@ import (
type Callback func(tmsp.Request, tmsp.Response)
type AppContext interface {
type AppConn interface {
SetResponseCallback(Callback)
Error() error
EchoAsync(msg string)
FlushAsync()
AppendTxAsync(tx []byte)
CheckTxAsync(tx []byte)
GetHashAsync()
CommitAsync()
RollbackAsync()
SetOptionAsync(key string, value string)
AddListenerAsync(key string)
RemListenerAsync(key string)
@ -23,6 +22,4 @@ type AppContext interface {
InfoSync() (info []string, err error)
FlushSync() error
GetHashSync() (hash []byte, err error)
CommitSync() error
RollbackSync() error
}

128
proxy/local_app_conn.go Normal file
View File

@ -0,0 +1,128 @@
package proxy
import (
tmsp "github.com/tendermint/tmsp/types"
"sync"
)
type localAppConn struct {
mtx *sync.Mutex
tmsp.Application
Callback
}
func NewLocalAppConn(mtx *sync.Mutex, app tmsp.Application) *localAppConn {
return &localAppConn{
mtx: mtx,
Application: app,
}
}
func (app *localAppConn) SetResponseCallback(cb Callback) {
app.mtx.Lock()
defer app.mtx.Unlock()
app.Callback = cb
}
// TODO: change tmsp.Application to include Error()?
func (app *localAppConn) Error() error {
return nil
}
func (app *localAppConn) EchoAsync(msg string) {
app.mtx.Lock()
msg2 := app.Application.Echo(msg)
app.mtx.Unlock()
app.Callback(
tmsp.RequestEcho{msg},
tmsp.ResponseEcho{msg2},
)
}
func (app *localAppConn) FlushAsync() {
// Do nothing
}
func (app *localAppConn) SetOptionAsync(key string, value string) {
app.mtx.Lock()
retCode := app.Application.SetOption(key, value)
app.mtx.Unlock()
app.Callback(
tmsp.RequestSetOption{key, value},
tmsp.ResponseSetOption{retCode},
)
}
func (app *localAppConn) AppendTxAsync(tx []byte) {
app.mtx.Lock()
events, retCode := app.Application.AppendTx(tx)
app.mtx.Unlock()
app.Callback(
tmsp.RequestAppendTx{tx},
tmsp.ResponseAppendTx{retCode},
)
for _, event := range events {
app.Callback(
nil,
tmsp.ResponseEvent{event},
)
}
}
func (app *localAppConn) CheckTxAsync(tx []byte) {
app.mtx.Lock()
retCode := app.Application.CheckTx(tx)
app.mtx.Unlock()
app.Callback(
tmsp.RequestCheckTx{tx},
tmsp.ResponseCheckTx{retCode},
)
}
func (app *localAppConn) GetHashAsync() {
app.mtx.Lock()
hash, retCode := app.Application.GetHash()
app.mtx.Unlock()
app.Callback(
tmsp.RequestGetHash{},
tmsp.ResponseGetHash{retCode, hash},
)
}
func (app *localAppConn) AddListenerAsync(key string) {
app.mtx.Lock()
retCode := app.Application.AddListener(key)
app.mtx.Unlock()
app.Callback(
tmsp.RequestAddListener{key},
tmsp.ResponseAddListener{retCode},
)
}
func (app *localAppConn) RemListenerAsync(key string) {
app.mtx.Lock()
retCode := app.Application.RemListener(key)
app.mtx.Unlock()
app.Callback(
tmsp.RequestRemListener{key},
tmsp.ResponseRemListener{retCode},
)
}
func (app *localAppConn) InfoSync() (info []string, err error) {
app.mtx.Lock()
info = app.Application.Info()
app.mtx.Unlock()
return info, nil
}
func (app *localAppConn) FlushSync() error {
return nil
}
func (app *localAppConn) GetHashSync() (hash []byte, err error) {
app.mtx.Lock()
hash, retCode := app.Application.GetHash()
app.mtx.Unlock()
return hash, retCode.Error()
}

View File

@ -1,123 +0,0 @@
package proxy
import (
tmsp "github.com/tendermint/tmsp/types"
)
type localAppContext struct {
tmsp.AppContext
Callback
}
func NewLocalAppContext(app tmsp.AppContext) *localAppContext {
return &localAppContext{
AppContext: app,
}
}
func (app *localAppContext) SetResponseCallback(cb Callback) {
app.Callback = cb
}
// TODO: change tmsp.AppContext to include Error()?
func (app *localAppContext) Error() error {
return nil
}
func (app *localAppContext) EchoAsync(msg string) {
msg2 := app.AppContext.Echo(msg)
app.Callback(
tmsp.RequestEcho{msg},
tmsp.ResponseEcho{msg2},
)
}
func (app *localAppContext) FlushAsync() {
// Do nothing
}
func (app *localAppContext) SetOptionAsync(key string, value string) {
retCode := app.AppContext.SetOption(key, value)
app.Callback(
tmsp.RequestSetOption{key, value},
tmsp.ResponseSetOption{retCode},
)
}
func (app *localAppContext) AppendTxAsync(tx []byte) {
events, retCode := app.AppContext.AppendTx(tx)
app.Callback(
tmsp.RequestAppendTx{tx},
tmsp.ResponseAppendTx{retCode},
)
for _, event := range events {
app.Callback(
nil,
tmsp.ResponseEvent{event},
)
}
}
func (app *localAppContext) GetHashAsync() {
hash, retCode := app.AppContext.GetHash()
app.Callback(
tmsp.RequestGetHash{},
tmsp.ResponseGetHash{retCode, hash},
)
}
func (app *localAppContext) CommitAsync() {
retCode := app.AppContext.Commit()
app.Callback(
tmsp.RequestCommit{},
tmsp.ResponseCommit{retCode},
)
}
func (app *localAppContext) RollbackAsync() {
retCode := app.AppContext.Rollback()
app.Callback(
tmsp.RequestRollback{},
tmsp.ResponseRollback{retCode},
)
}
func (app *localAppContext) AddListenerAsync(key string) {
retCode := app.AppContext.AddListener(key)
app.Callback(
tmsp.RequestAddListener{key},
tmsp.ResponseAddListener{retCode},
)
}
func (app *localAppContext) RemListenerAsync(key string) {
retCode := app.AppContext.RemListener(key)
app.Callback(
tmsp.RequestRemListener{key},
tmsp.ResponseRemListener{retCode},
)
}
func (app *localAppContext) InfoSync() (info []string, err error) {
info = app.AppContext.Info()
return info, nil
}
func (app *localAppContext) FlushSync() error {
return nil
}
func (app *localAppContext) GetHashSync() (hash []byte, err error) {
hash, retCode := app.AppContext.GetHash()
return hash, retCode.Error()
}
func (app *localAppContext) CommitSync() (err error) {
retCode := app.AppContext.Commit()
return retCode.Error()
}
func (app *localAppContext) RollbackSync() (err error) {
retCode := app.AppContext.Rollback()
return retCode.Error()
}

View File

@ -19,7 +19,7 @@ const maxResponseSize = 1048576 // 1MB
// This is goroutine-safe, but users should beware that
// the application in general is not meant to be interfaced
// with concurrent callers.
type remoteAppContext struct {
type remoteAppConn struct {
QuitService
sync.Mutex // [EB]: is this even used?
@ -33,39 +33,39 @@ type remoteAppContext struct {
resCb func(tmsp.Request, tmsp.Response)
}
func NewRemoteAppContext(conn net.Conn, bufferSize int) *remoteAppContext {
app := &remoteAppContext{
func NewRemoteAppConn(conn net.Conn, bufferSize int) *remoteAppConn {
app := &remoteAppConn{
reqQueue: make(chan *reqRes, bufferSize),
conn: conn,
bufWriter: bufio.NewWriter(conn),
reqSent: list.New(),
resCb: nil,
}
app.QuitService = *NewQuitService(nil, "remoteAppContext", app)
app.QuitService = *NewQuitService(nil, "remoteAppConn", app)
return app
}
func (app *remoteAppContext) OnStart() error {
func (app *remoteAppConn) OnStart() error {
app.QuitService.OnStart()
go app.sendRequestsRoutine()
go app.recvResponseRoutine()
return nil
}
func (app *remoteAppContext) OnStop() {
func (app *remoteAppConn) OnStop() {
app.QuitService.OnStop()
app.conn.Close()
}
func (app *remoteAppContext) SetResponseCallback(resCb Callback) {
func (app *remoteAppConn) SetResponseCallback(resCb Callback) {
app.mtx.Lock()
defer app.mtx.Unlock()
app.resCb = resCb
}
func (app *remoteAppContext) StopForError(err error) {
func (app *remoteAppConn) StopForError(err error) {
app.mtx.Lock()
log.Error("Stopping remoteAppContext for error.", "error", err)
log.Error("Stopping remoteAppConn for error.", "error", err)
if app.err == nil {
app.err = err
}
@ -73,7 +73,7 @@ func (app *remoteAppContext) StopForError(err error) {
app.Stop()
}
func (app *remoteAppContext) Error() error {
func (app *remoteAppConn) Error() error {
app.mtx.Lock()
defer app.mtx.Unlock()
return app.err
@ -81,7 +81,7 @@ func (app *remoteAppContext) Error() error {
//----------------------------------------
func (app *remoteAppContext) sendRequestsRoutine() {
func (app *remoteAppConn) sendRequestsRoutine() {
for {
var n int
var err error
@ -109,7 +109,7 @@ func (app *remoteAppContext) sendRequestsRoutine() {
}
}
func (app *remoteAppContext) recvResponseRoutine() {
func (app *remoteAppConn) recvResponseRoutine() {
r := bufio.NewReader(app.conn) // Buffer reads
for {
var res tmsp.Response
@ -133,13 +133,13 @@ func (app *remoteAppContext) recvResponseRoutine() {
}
}
func (app *remoteAppContext) willSendReq(reqres *reqRes) {
func (app *remoteAppConn) willSendReq(reqres *reqRes) {
app.mtx.Lock()
defer app.mtx.Unlock()
app.reqSent.PushBack(reqres)
}
func (app *remoteAppContext) didRecvResponse(res tmsp.Response) error {
func (app *remoteAppConn) didRecvResponse(res tmsp.Response) error {
app.mtx.Lock()
defer app.mtx.Unlock()
@ -174,45 +174,41 @@ func (app *remoteAppContext) didRecvResponse(res tmsp.Response) error {
//----------------------------------------
func (app *remoteAppContext) EchoAsync(msg string) {
func (app *remoteAppConn) EchoAsync(msg string) {
app.queueRequest(tmsp.RequestEcho{msg})
}
func (app *remoteAppContext) FlushAsync() {
func (app *remoteAppConn) FlushAsync() {
app.queueRequest(tmsp.RequestFlush{})
}
func (app *remoteAppContext) SetOptionAsync(key string, value string) {
func (app *remoteAppConn) SetOptionAsync(key string, value string) {
app.queueRequest(tmsp.RequestSetOption{key, value})
}
func (app *remoteAppContext) AppendTxAsync(tx []byte) {
func (app *remoteAppConn) AppendTxAsync(tx []byte) {
app.queueRequest(tmsp.RequestAppendTx{tx})
}
func (app *remoteAppContext) GetHashAsync() {
func (app *remoteAppConn) CheckTxAsync(tx []byte) {
app.queueRequest(tmsp.RequestCheckTx{tx})
}
func (app *remoteAppConn) GetHashAsync() {
app.queueRequest(tmsp.RequestGetHash{})
}
func (app *remoteAppContext) CommitAsync() {
app.queueRequest(tmsp.RequestCommit{})
}
func (app *remoteAppContext) RollbackAsync() {
app.queueRequest(tmsp.RequestRollback{})
}
func (app *remoteAppContext) AddListenerAsync(key string) {
func (app *remoteAppConn) AddListenerAsync(key string) {
app.queueRequest(tmsp.RequestAddListener{key})
}
func (app *remoteAppContext) RemListenerAsync(key string) {
func (app *remoteAppConn) RemListenerAsync(key string) {
app.queueRequest(tmsp.RequestRemListener{key})
}
//----------------------------------------
func (app *remoteAppContext) InfoSync() (info []string, err error) {
func (app *remoteAppConn) InfoSync() (info []string, err error) {
reqres := app.queueRequest(tmsp.RequestInfo{})
app.FlushSync()
if app.err != nil {
@ -221,12 +217,12 @@ func (app *remoteAppContext) InfoSync() (info []string, err error) {
return reqres.Response.(tmsp.ResponseInfo).Data, nil
}
func (app *remoteAppContext) FlushSync() error {
func (app *remoteAppConn) FlushSync() error {
app.queueRequest(tmsp.RequestFlush{}).Wait()
return app.err
}
func (app *remoteAppContext) GetHashSync() (hash []byte, err error) {
func (app *remoteAppConn) GetHashSync() (hash []byte, err error) {
reqres := app.queueRequest(tmsp.RequestGetHash{})
app.FlushSync()
if app.err != nil {
@ -235,24 +231,9 @@ func (app *remoteAppContext) GetHashSync() (hash []byte, err error) {
return reqres.Response.(tmsp.ResponseGetHash).Hash, nil
}
// Commits or error
func (app *remoteAppContext) CommitSync() (err error) {
app.queueRequest(tmsp.RequestCommit{})
app.FlushSync()
return app.err
}
// Rollback or error
// Clears internal buffers
func (app *remoteAppContext) RollbackSync() (err error) {
app.queueRequest(tmsp.RequestRollback{})
app.FlushSync()
return app.err
}
//----------------------------------------
func (app *remoteAppContext) queueRequest(req tmsp.Request) *reqRes {
func (app *remoteAppConn) queueRequest(req tmsp.Request) *reqRes {
reqres := NewreqRes(req)
// TODO: set app.err if reqQueue times out
app.reqQueue <- reqres
@ -273,12 +254,10 @@ func resMatchesReq(req tmsp.Request, res tmsp.Response) (ok bool) {
_, ok = res.(tmsp.ResponseSetOption)
case tmsp.RequestAppendTx:
_, ok = res.(tmsp.ResponseAppendTx)
case tmsp.RequestCheckTx:
_, ok = res.(tmsp.ResponseCheckTx)
case tmsp.RequestGetHash:
_, ok = res.(tmsp.ResponseGetHash)
case tmsp.RequestCommit:
_, ok = res.(tmsp.ResponseCommit)
case tmsp.RequestRollback:
_, ok = res.(tmsp.ResponseRollback)
case tmsp.RequestAddListener:
_, ok = res.(tmsp.ResponseAddListener)
case tmsp.RequestRemListener:

View File

@ -26,7 +26,7 @@ func TestEcho(t *testing.T) {
logBuffer := bytes.NewBuffer(nil)
logConn := logio.NewLoggedConn(conn, logBuffer)
proxy := NewRemoteAppContext(logConn, 10)
proxy := NewRemoteAppConn(logConn, 10)
proxy.SetResponseCallback(nil)
proxy.Start()
@ -56,7 +56,7 @@ func BenchmarkEcho(b *testing.B) {
b.Log("Connected")
}
proxy := NewRemoteAppContext(conn, 10)
proxy := NewRemoteAppConn(conn, 10)
proxy.Start()
echoString := strings.Repeat(" ", 200)
b.StartTimer() // Start benchmarking tests
@ -86,7 +86,7 @@ func TestInfo(t *testing.T) {
logBuffer := bytes.NewBuffer(nil)
logConn := logio.NewLoggedConn(conn, logBuffer)
proxy := NewRemoteAppContext(logConn, 10)
proxy := NewRemoteAppConn(logConn, 10)
proxy.Start()
data, err := proxy.InfoSync()
if err != nil {