mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 01:06:59 +08:00
perf: reuse shared HTTP client in Hyperliquid trader
Previously each direct API call (orders, sync, account) created a new http.Client, preventing TCP/TLS connection reuse. Now all calls share a single client on the HyperliquidTrader struct (30s timeout).
This commit is contained in:
@@ -4,10 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"nofx/logger"
|
"nofx/logger"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/sonirico/go-hyperliquid"
|
"github.com/sonirico/go-hyperliquid"
|
||||||
@@ -17,6 +19,7 @@ import (
|
|||||||
type HyperliquidTrader struct {
|
type HyperliquidTrader struct {
|
||||||
exchange *hyperliquid.Exchange
|
exchange *hyperliquid.Exchange
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
httpClient *http.Client // Shared HTTP client for direct API calls (connection reuse)
|
||||||
walletAddr string
|
walletAddr string
|
||||||
meta *hyperliquid.Meta // Cache meta information (including precision)
|
meta *hyperliquid.Meta // Cache meta information (including precision)
|
||||||
metaMutex sync.RWMutex // Protect concurrent access to meta field
|
metaMutex sync.RWMutex // Protect concurrent access to meta field
|
||||||
@@ -220,6 +223,7 @@ func NewHyperliquidTrader(privateKeyHex string, walletAddr string, testnet bool,
|
|||||||
return &HyperliquidTrader{
|
return &HyperliquidTrader{
|
||||||
exchange: exchange,
|
exchange: exchange,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
httpClient: &http.Client{Timeout: 30 * time.Second},
|
||||||
walletAddr: walletAddr,
|
walletAddr: walletAddr,
|
||||||
meta: meta,
|
meta: meta,
|
||||||
isCrossMargin: true, // Use cross margin mode by default
|
isCrossMargin: true, // Use cross margin mode by default
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ func (t *HyperliquidTrader) getXYZDexBalance() (accountValue float64, unrealized
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, nil, fmt.Errorf("failed to execute request: %w", err)
|
return 0, 0, nil, fmt.Errorf("failed to execute request: %w", err)
|
||||||
@@ -308,7 +308,7 @@ func (t *HyperliquidTrader) getXyzMarketPrice(coin string) (float64, error) {
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to execute request: %w", err)
|
return 0, fmt.Errorf("failed to execute request: %w", err)
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ func (t *HyperliquidTrader) cancelXyzOrders(coin string) error {
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to execute request: %w", err)
|
return fmt.Errorf("failed to execute request: %w", err)
|
||||||
@@ -538,7 +538,7 @@ func (t *HyperliquidTrader) cancelXyzOrder(oid int64) error {
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("request failed: %w", err)
|
return fmt.Errorf("request failed: %w", err)
|
||||||
@@ -679,7 +679,7 @@ func (t *HyperliquidTrader) placeXyzOrder(coin string, isBuy bool, size float64,
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("request failed: %w", err)
|
return fmt.Errorf("request failed: %w", err)
|
||||||
@@ -843,7 +843,7 @@ func (t *HyperliquidTrader) placeXyzTriggerOrder(coin string, isBuy bool, size f
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("request failed: %w", err)
|
return fmt.Errorf("request failed: %w", err)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"nofx/logger"
|
"nofx/logger"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// refreshMetaIfNeeded refreshes meta information when invalid (triggered when Asset ID is 0)
|
// refreshMetaIfNeeded refreshes meta information when invalid (triggered when Asset ID is 0)
|
||||||
@@ -67,7 +66,7 @@ func (t *HyperliquidTrader) fetchXyzMeta() error {
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
client := &http.Client{Timeout: 30 * time.Second}
|
client := t.httpClient
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to execute request: %w", err)
|
return fmt.Errorf("failed to execute request: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user