oracle: process requests concurrently

This commit is contained in:
Evgenii Stratonikov 2020-10-07 10:48:41 +03:00 committed by Evgeniy Stratonikov
parent 43e4d3af88
commit 25d734cbad
3 changed files with 46 additions and 7 deletions

View file

@ -4,10 +4,11 @@ import "time"
// OracleConfiguration is a config for the oracle module. // OracleConfiguration is a config for the oracle module.
type OracleConfiguration struct { type OracleConfiguration struct {
Enabled bool `yaml:"Enabled"` Enabled bool `yaml:"Enabled"`
AllowPrivateHost bool `yaml:"AllowPrivateHost"` AllowPrivateHost bool `yaml:"AllowPrivateHost"`
Nodes []string `yaml:"Nodes"` Nodes []string `yaml:"Nodes"`
RequestTimeout time.Duration `yaml:"RequestTimeout"` MaxConcurrentRequests int `yaml:"MaxConcurrentRequests"`
ResponseTimeout time.Duration `yaml:"ResponseTimeout"` RequestTimeout time.Duration `yaml:"RequestTimeout"`
UnlockWallet Wallet `yaml:"UnlockWallet"` ResponseTimeout time.Duration `yaml:"ResponseTimeout"`
UnlockWallet Wallet `yaml:"UnlockWallet"`
} }

View file

@ -34,6 +34,7 @@ type (
oracleSignContract []byte oracleSignContract []byte
close chan struct{} close chan struct{}
requestCh chan request
requestMap chan map[uint64]*state.OracleRequest requestMap chan map[uint64]*state.OracleRequest
// respMtx protects responses map. // respMtx protects responses map.
@ -93,6 +94,10 @@ func NewOracle(cfg Config) (*Oracle, error) {
if o.MainCfg.RequestTimeout == 0 { if o.MainCfg.RequestTimeout == 0 {
o.MainCfg.RequestTimeout = defaultRequestTimeout o.MainCfg.RequestTimeout = defaultRequestTimeout
} }
if o.MainCfg.MaxConcurrentRequests == 0 {
o.MainCfg.MaxConcurrentRequests = defaultMaxConcurrentRequests
}
o.requestCh = make(chan request, o.MainCfg.MaxConcurrentRequests)
var err error var err error
w := cfg.MainCfg.UnlockWallet w := cfg.MainCfg.UnlockWallet
@ -136,12 +141,20 @@ func (o *Oracle) Shutdown() {
// Run runs must be executed in a separate goroutine. // Run runs must be executed in a separate goroutine.
func (o *Oracle) Run() { func (o *Oracle) Run() {
for i := 0; i < o.MainCfg.MaxConcurrentRequests; i++ {
go o.runRequestWorker()
}
for { for {
select { select {
case <-o.close: case <-o.close:
return return
case reqs := <-o.requestMap: case reqs := <-o.requestMap:
o.ProcessRequestsInternal(reqs) for id, req := range reqs {
o.requestCh <- request{
ID: id,
Req: req,
}
}
} }
} }
} }

View file

@ -12,6 +12,31 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
const defaultMaxConcurrentRequests = 10
type request struct {
ID uint64
Req *state.OracleRequest
}
func (o *Oracle) runRequestWorker() {
for {
select {
case <-o.close:
return
case req := <-o.requestCh:
acc := o.getAccount()
if acc == nil {
continue
}
err := o.processRequest(acc.PrivateKey(), req.ID, req.Req)
if err != nil {
o.Log.Debug("can't process request", zap.Uint64("id", req.ID), zap.Error(err))
}
}
}
}
// RemoveRequests removes all data associated with requests // RemoveRequests removes all data associated with requests
// which have been processed by oracle contract. // which have been processed by oracle contract.
func (o *Oracle) RemoveRequests(ids []uint64) { func (o *Oracle) RemoveRequests(ids []uint64) {