mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-08 15:11:07 +00:00
Update request.go to fix concurrency nonce issues (#285)
* Updates nonce generation to adhere to fifo channel buffer before request executes by routine * removed unused variables, lns etc * Fix requested changes and added in timer that disengages lock if out of scope error occurs * Fixed woopsy daisy issue * Add benchmark, reduce time in force to unlock before stack insertion, add nil check for edge case * Remove unusued waitgroup field * use return nonce.Value and method, rm redundant nonce code, fix tests. * Fix linter issue: unnecessary conversion
This commit is contained in:
committed by
Adrian Gallagher
parent
1967507d40
commit
35b94268e0
@@ -2,18 +2,12 @@ package nonce
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Nonce struct holds the nonce value
|
||||
type Nonce struct {
|
||||
// Standard nonce
|
||||
n int64
|
||||
// Hash table exclusive exchange specific nonce values
|
||||
boundedCall map[string]int64
|
||||
boundedMtx sync.Mutex
|
||||
}
|
||||
|
||||
// Inc increments the nonce value
|
||||
@@ -22,12 +16,12 @@ func (n *Nonce) Inc() {
|
||||
}
|
||||
|
||||
// Get retrives the nonce value
|
||||
func (n *Nonce) Get() int64 {
|
||||
return atomic.LoadInt64(&n.n)
|
||||
func (n *Nonce) Get() Value {
|
||||
return Value(atomic.LoadInt64(&n.n))
|
||||
}
|
||||
|
||||
// GetInc increments and returns the value of the nonce
|
||||
func (n *Nonce) GetInc() int64 {
|
||||
func (n *Nonce) GetInc() Value {
|
||||
n.Inc()
|
||||
return n.Get()
|
||||
}
|
||||
@@ -39,34 +33,12 @@ func (n *Nonce) Set(val int64) {
|
||||
|
||||
// String returns a string version of the nonce
|
||||
func (n *Nonce) String() string {
|
||||
return strconv.FormatInt(n.Get(), 10)
|
||||
return n.Get().String()
|
||||
}
|
||||
|
||||
// Value is a return type for GetValue
|
||||
type Value int64
|
||||
|
||||
// GetValue returns a nonce value and can be set as a higher precision. Values
|
||||
// stored in an exchange specific hash table using a single locked call.
|
||||
func (n *Nonce) GetValue(exchName string, nanoPrecision bool) Value {
|
||||
n.boundedMtx.Lock()
|
||||
defer n.boundedMtx.Unlock()
|
||||
|
||||
if n.boundedCall == nil {
|
||||
n.boundedCall = make(map[string]int64)
|
||||
}
|
||||
|
||||
if n.boundedCall[exchName] == 0 {
|
||||
if nanoPrecision {
|
||||
n.boundedCall[exchName] = time.Now().UnixNano()
|
||||
return Value(n.boundedCall[exchName])
|
||||
}
|
||||
n.boundedCall[exchName] = time.Now().Unix()
|
||||
return Value(n.boundedCall[exchName])
|
||||
}
|
||||
n.boundedCall[exchName]++
|
||||
return Value(n.boundedCall[exchName])
|
||||
}
|
||||
|
||||
// String is a Value method that changes format to a string
|
||||
func (v Value) String() string {
|
||||
return strconv.FormatInt(int64(v), 10)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package nonce
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -10,7 +9,7 @@ func TestInc(t *testing.T) {
|
||||
var nonce Nonce
|
||||
nonce.Set(1)
|
||||
nonce.Inc()
|
||||
expected := int64(2)
|
||||
expected := Value(2)
|
||||
result := nonce.Get()
|
||||
if result != expected {
|
||||
t.Errorf("Test failed. Expected %d got %d", expected, result)
|
||||
@@ -20,7 +19,7 @@ func TestInc(t *testing.T) {
|
||||
func TestGet(t *testing.T) {
|
||||
var nonce Nonce
|
||||
nonce.Set(112321313)
|
||||
expected := int64(112321313)
|
||||
expected := Value(112321313)
|
||||
result := nonce.Get()
|
||||
if expected != result {
|
||||
t.Errorf("Test failed. Expected %d got %d", expected, result)
|
||||
@@ -30,7 +29,7 @@ func TestGet(t *testing.T) {
|
||||
func TestGetInc(t *testing.T) {
|
||||
var nonce Nonce
|
||||
nonce.Set(1)
|
||||
expected := int64(2)
|
||||
expected := Value(2)
|
||||
result := nonce.GetInc()
|
||||
if expected != result {
|
||||
t.Errorf("Test failed. Expected %d got %d", expected, result)
|
||||
@@ -40,7 +39,7 @@ func TestGetInc(t *testing.T) {
|
||||
func TestSet(t *testing.T) {
|
||||
var nonce Nonce
|
||||
nonce.Set(1)
|
||||
expected := int64(1)
|
||||
expected := Value(1)
|
||||
result := nonce.Get()
|
||||
if expected != result {
|
||||
t.Errorf("Test failed. Expected %d got %d", expected, result)
|
||||
@@ -55,30 +54,10 @@ func TestString(t *testing.T) {
|
||||
if expected != result {
|
||||
t.Errorf("Test failed. Expected %s got %s", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetValue(t *testing.T) {
|
||||
var nonce Nonce
|
||||
timeNowNano := strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
nValue := nonce.GetValue("dingdong", true).String()
|
||||
|
||||
if timeNowNano == nValue {
|
||||
t.Error("Test failed - GetValue() error, incorrect values")
|
||||
}
|
||||
|
||||
if len(nValue) != 19 {
|
||||
t.Error("Test failed - GetValue() error, incorrect values")
|
||||
}
|
||||
|
||||
timeNowUnix := nonce.GetValue("dongding", false)
|
||||
if len(timeNowUnix.String()) != 10 {
|
||||
t.Error("Test failed - GetValue() error, incorrect values")
|
||||
}
|
||||
|
||||
n := nonce.GetValue("dongding", false)
|
||||
if n != timeNowUnix+1 {
|
||||
t.Error("Test failed - GetValue() error, incorrect values")
|
||||
v := nonce.Get()
|
||||
if expected != v.String() {
|
||||
t.Errorf("Test failed. Expected %s got %s", expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +73,7 @@ func TestNonceConcurrency(t *testing.T) {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
result := nonce.Get()
|
||||
expected := int64(12312 + 1000)
|
||||
expected := Value(12312 + 1000)
|
||||
if expected != result {
|
||||
t.Errorf("Test failed. Expected %d got %d", expected, result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user