Use a generator goroutine and chan to create new JSON IDs

This commit is contained in:
Josh Rickmar 2013-10-14 18:45:48 -04:00
parent d44159b452
commit acbb9076cd
3 changed files with 37 additions and 60 deletions

37
cmd.go
View file

@ -215,11 +215,7 @@ func getCurHeight() (height int64) {
return height
}
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
m, err := btcjson.CreateMessageWithId("getblockcount",
fmt.Sprintf("btcwallet(%v)", n))
if err != nil {
@ -285,11 +281,7 @@ func (w *BtcWallet) CalculateBalance(confirmations int) float64 {
// each address stored in a wallet and sets up a new reply handler for
// these notifications.
func (w *BtcWallet) Track() {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
w.mtx.Lock()
w.NewBlockTxSeqN = n
w.mtx.Unlock()
@ -310,11 +302,7 @@ func (w *BtcWallet) Track() {
// blocks[0]. If len(blocks) is 2 or greater, the rescan will be
// performed for the block range blocks[0]...blocks[1] (inclusive).
func (w *BtcWallet) RescanForAddress(addr string, blocks ...int) {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
params := []interface{}{addr}
if len(blocks) > 0 {
params = append(params, blocks[0])
@ -493,6 +481,22 @@ func (w *BtcWallet) newBlockTxHandler(result interface{}, e *btcjson.Error) bool
return false
}
// NewJsonID is used to receive the next unique JSON ID for btcd
// requests, starting from zero and incrementing by one after each
// read.
var NewJsonID = make(chan uint64)
// JsonIDGenerator sends incremental integers across a channel. This
// is meant to provide a unique value for the JSON ID field for btcd
// messages.
func JsonIDGenerator(c chan uint64) {
var n uint64
for {
c <- n
n++
}
}
func main() {
tcfg, _, err := loadConfig()
if err != nil {
@ -523,6 +527,9 @@ func main() {
}
}()
// Begin generating new IDs for JSON calls.
go JsonIDGenerator(NewJsonID)
for {
replies := make(chan error)
done := make(chan int)

View file

@ -23,7 +23,6 @@ import (
"github.com/conformal/btcjson"
"github.com/conformal/btcwallet/wallet"
"github.com/conformal/btcwire"
"sync"
"time"
)
@ -127,25 +126,6 @@ var (
}
)
var (
// seq holds the btcwallet sequence number for frontend messages
// which must be sent to and received from btcd. A Mutex protects
// against concurrent access.
seq = struct {
sync.Mutex
n uint64
}{}
// replyRouter maps uint64 ids to reply channels, so btcd replies can
// be routed to the correct frontend.
replyRouter = struct {
sync.Mutex
m map[uint64]chan []byte
}{
m: make(map[uint64]chan []byte),
}
)
// ProcessFrontendMsg checks the message sent from a frontend. If the
// message method is one that must be handled by btcwallet, the request
// is processed here. Otherwise, the message is sent to btcd.
@ -190,11 +170,7 @@ func ProcessFrontendMsg(reply chan []byte, msg []byte) {
default:
// btcwallet does not understand method. Pass to btcd.
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
var id interface{} = fmt.Sprintf("btcwallet(%v)-%v", n,
jsonMsg.Id)
jsonMsg.Id = &id
@ -489,11 +465,7 @@ func SendFrom(reply chan []byte, msg *btcjson.Message) {
}
// Send rawtx off to btcd
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
var id interface{} = fmt.Sprintf("btcwallet(%v)-%v", n, msg.Id)
m, err := btcjson.CreateMessageWithId("sendrawtransaction", id,
hex.EncodeToString(rawtx))
@ -606,11 +578,7 @@ func SendMany(reply chan []byte, msg *btcjson.Message) {
}
// Send rawtx off to btcd
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
var id interface{} = fmt.Sprintf("btcwallet(%v)-%v", n, msg.Id)
m, err := btcjson.CreateMessageWithId("sendrawtransaction", id,
hex.EncodeToString(rawtx))
@ -734,11 +702,7 @@ func CreateEncryptedWallet(reply chan []byte, msg *btcjson.Message) {
}
// Grab a new unique sequence number for tx notifications in new blocks.
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
bw := &BtcWallet{
Wallet: w,
name: wname,

View file

@ -58,7 +58,7 @@ var (
// Messages sent to this channel are sent to each connected frontend.
frontendNotificationMaster = make(chan []byte, 100)
// replyHandlers maps between a sequence number (passed as part of
// replyHandlers maps between a unique number (passed as part of
// the JSON Id field) and a function to handle a reply or notification
// from btcd. As requests are received, this map is checked for a
// handler function to route the reply to. If the function returns
@ -69,6 +69,15 @@ var (
}{
m: make(map[uint64]func(interface{}, *btcjson.Error) bool),
}
// replyRouter maps unique uint64 ids to reply channels, so btcd
// replies can be routed to the correct frontend.
replyRouter = struct {
sync.Mutex
m map[uint64]chan []byte
}{
m: make(map[uint64]chan []byte),
}
)
// frontendListenerDuplicator listens for new wallet listener channels
@ -484,10 +493,7 @@ func BtcdConnect(reply chan error) {
// Bitcoin networks). If the sanity checks pass, all wallets are set to
// be tracked against chain notifications from this btcd connection.
func BtcdHandshake(ws *websocket.Conn) {
seq.Lock()
n := seq.n
seq.n++
seq.Unlock()
n := <-NewJsonID
msg := btcjson.Message{
Method: "getcurrentnet",
Id: fmt.Sprintf("btcwallet(%v)", n),