example/golang

This commit is contained in:
Ethan Buchman
2015-12-14 18:06:56 -05:00
parent af2a1a6fc1
commit 36b7045f5c
6 changed files with 6 additions and 3 deletions

112
example/golang/counter.go Normal file
View File

@ -0,0 +1,112 @@
package example
import (
"encoding/binary"
"sync"
. "github.com/tendermint/go-common"
"github.com/tendermint/tmsp/types"
)
type CounterApplication struct {
mtx sync.Mutex
hashCount int
txCount int
commitCount int
serial bool
}
func NewCounterApplication(serial bool) *CounterApplication {
return &CounterApplication{serial: serial}
}
func (app *CounterApplication) Open() types.AppContext {
return &CounterAppContext{
app: app,
hashCount: app.hashCount,
txCount: app.txCount,
commitCount: app.commitCount,
serial: app.serial,
}
}
//--------------------------------------------------------------------------------
type CounterAppContext struct {
app *CounterApplication
hashCount int
txCount int
commitCount int
serial bool
}
func (appC *CounterAppContext) Echo(message string) string {
return message
}
func (appC *CounterAppContext) Info() []string {
return []string{Fmt("hash, tx, commit counts:%d, %d, %d", appC.hashCount, appC.txCount, appC.commitCount)}
}
func (appC *CounterAppContext) SetOption(key string, value string) types.RetCode {
if key == "serial" && value == "on" {
appC.serial = true
}
return 0
}
func (appC *CounterAppContext) AppendTx(tx []byte) ([]types.Event, types.RetCode) {
if appC.serial {
tx8 := make([]byte, 8)
copy(tx8, tx)
txValue := binary.LittleEndian.Uint64(tx8)
if txValue != uint64(appC.txCount) {
return nil, types.RetCodeInternalError
}
}
appC.txCount += 1
return nil, 0
}
func (appC *CounterAppContext) GetHash() ([]byte, types.RetCode) {
appC.hashCount += 1
if appC.txCount == 0 {
return nil, 0
} else {
hash := make([]byte, 32)
binary.LittleEndian.PutUint64(hash, uint64(appC.txCount))
return hash, 0
}
}
func (appC *CounterAppContext) Commit() types.RetCode {
appC.commitCount += 1
appC.app.mtx.Lock()
appC.app.hashCount = appC.hashCount
appC.app.txCount = appC.txCount
appC.app.commitCount = appC.commitCount
appC.app.mtx.Unlock()
return 0
}
func (appC *CounterAppContext) Rollback() types.RetCode {
appC.app.mtx.Lock()
appC.hashCount = appC.app.hashCount
appC.txCount = appC.app.txCount
appC.commitCount = appC.app.commitCount
appC.app.mtx.Unlock()
return 0
}
func (appC *CounterAppContext) AddListener(key string) types.RetCode {
return 0
}
func (appC *CounterAppContext) RemListener(key string) types.RetCode {
return 0
}
func (appC *CounterAppContext) Close() error {
return nil
}

97
example/golang/dummy.go Normal file
View File

@ -0,0 +1,97 @@
package example
import (
"sync"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-merkle"
"github.com/tendermint/go-wire"
"github.com/tendermint/tmsp/types"
)
type DummyApplication struct {
mtx sync.Mutex
state merkle.Tree
}
func NewDummyApplication() *DummyApplication {
state := merkle.NewIAVLTree(
wire.BasicCodec,
wire.BasicCodec,
0,
nil,
)
return &DummyApplication{state: state}
}
func (dapp *DummyApplication) Open() types.AppContext {
dapp.mtx.Lock()
defer dapp.mtx.Unlock()
return &DummyAppContext{
app: dapp,
state: dapp.state.Copy(),
}
}
func (dapp *DummyApplication) commitState(state merkle.Tree) {
dapp.mtx.Lock()
defer dapp.mtx.Unlock()
dapp.state = state.Copy()
}
func (dapp *DummyApplication) getState() merkle.Tree {
dapp.mtx.Lock()
defer dapp.mtx.Unlock()
return dapp.state.Copy()
}
//--------------------------------------------------------------------------------
type DummyAppContext struct {
app *DummyApplication
state merkle.Tree
}
func (dac *DummyAppContext) Echo(message string) string {
return message
}
func (dac *DummyAppContext) Info() []string {
return []string{Fmt("size:%v", dac.state.Size())}
}
func (dac *DummyAppContext) SetOption(key string, value string) types.RetCode {
return 0
}
func (dac *DummyAppContext) AppendTx(tx []byte) ([]types.Event, types.RetCode) {
dac.state.Set(tx, tx)
return nil, 0
}
func (dac *DummyAppContext) GetHash() ([]byte, types.RetCode) {
hash := dac.state.Hash()
return hash, 0
}
func (dac *DummyAppContext) Commit() types.RetCode {
dac.app.commitState(dac.state)
return 0
}
func (dac *DummyAppContext) Rollback() types.RetCode {
dac.state = dac.app.getState()
return 0
}
func (dac *DummyAppContext) AddListener(key string) types.RetCode {
return 0
}
func (dac *DummyAppContext) RemListener(key string) types.RetCode {
return 0
}
func (dac *DummyAppContext) Close() error {
return nil
}

View File

@ -0,0 +1,97 @@
package example
import (
"reflect"
"testing"
"time"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-wire"
"github.com/tendermint/tmsp/server"
"github.com/tendermint/tmsp/types"
)
func TestStream(t *testing.T) {
numAppendTxs := 200000
// Start the listener
_, err := server.StartListener("tcp://127.0.0.1:46658", NewDummyApplication())
if err != nil {
Exit(err.Error())
}
// Connect to the socket
conn, err := Connect("tcp://127.0.0.1:46658")
if err != nil {
Exit(err.Error())
}
// Read response data
done := make(chan struct{})
go func() {
counter := 0
for {
var n int
var err error
var res types.Response
wire.ReadBinaryPtr(&res, conn, 0, &n, &err)
if err != nil {
Exit(err.Error())
}
// Process response
switch res := res.(type) {
case types.ResponseAppendTx:
counter += 1
if res.RetCode != types.RetCodeOK {
t.Error("AppendTx failed with ret_code", res.RetCode)
}
if counter > numAppendTxs {
t.Fatal("Too many AppendTx responses")
}
t.Log("response", counter)
if counter == numAppendTxs {
go func() {
time.Sleep(time.Second * 2) // Wait for a bit to allow counter overflow
close(done)
}()
}
case types.ResponseFlush:
// ignore
default:
t.Error("Unexpected response type", reflect.TypeOf(res))
}
}
}()
// Write requests
for counter := 0; counter < numAppendTxs; counter++ {
// Send request
var n int
var err error
var req types.Request = types.RequestAppendTx{TxBytes: []byte("test")}
wire.WriteBinary(req, conn, &n, &err)
if err != nil {
t.Fatal(err.Error())
}
// Sometimes send flush messages
if counter%123 == 0 {
t.Log("flush")
wire.WriteBinary(types.RequestFlush{}, conn, &n, &err)
if err != nil {
t.Fatal(err.Error())
}
}
}
// Send final flush message
var n int
wire.WriteBinary(types.RequestFlush{}, conn, &n, &err)
if err != nil {
t.Fatal(err.Error())
}
<-done
}