mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-14 07:53:47 +00:00
Allow parallel state processor to be interrupted by caller
This commit is contained in:
parent
d76fc157aa
commit
48c1f9078d
3 changed files with 22 additions and 14 deletions
|
|
@ -2,6 +2,7 @@ package blockstm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -369,13 +370,14 @@ func (pe *ParallelExecutor) Prepare() {
|
||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
pe.settleWg.Add(len(pe.tasks))
|
pe.settleWg.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for t := range pe.chSettle {
|
for t := range pe.chSettle {
|
||||||
pe.tasks[t].Settle()
|
pe.tasks[t].Settle()
|
||||||
pe.settleWg.Done()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pe.settleWg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// bootstrap first execution
|
// bootstrap first execution
|
||||||
|
|
@ -390,18 +392,15 @@ func (pe *ParallelExecutor) Prepare() {
|
||||||
func (pe *ParallelExecutor) Close(wait bool) {
|
func (pe *ParallelExecutor) Close(wait bool) {
|
||||||
close(pe.chTasks)
|
close(pe.chTasks)
|
||||||
close(pe.chSpeculativeTasks)
|
close(pe.chSpeculativeTasks)
|
||||||
|
close(pe.chSettle)
|
||||||
|
|
||||||
if wait {
|
if wait {
|
||||||
pe.workerWg.Wait()
|
pe.workerWg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
close(pe.chResults)
|
|
||||||
|
|
||||||
if wait {
|
if wait {
|
||||||
pe.settleWg.Wait()
|
pe.settleWg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
close(pe.chSettle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: gocognit
|
// nolint: gocognit
|
||||||
|
|
@ -412,7 +411,7 @@ func (pe *ParallelExecutor) Step(res *ExecResult) (result ParallelExecutionResul
|
||||||
// If the transaction failed when we know it should not fail, this means the transaction itself is
|
// If the transaction failed when we know it should not fail, this means the transaction itself is
|
||||||
// bad (e.g. wrong nonce), and we should exit the execution immediately
|
// bad (e.g. wrong nonce), and we should exit the execution immediately
|
||||||
err = fmt.Errorf("could not apply tx %d [%v]: %w", tx, pe.tasks[tx].Hash(), abortErr.OriginError)
|
err = fmt.Errorf("could not apply tx %d [%v]: %w", tx, pe.tasks[tx].Hash(), abortErr.OriginError)
|
||||||
pe.Close(false)
|
pe.Close(true)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -582,7 +581,7 @@ func (pe *ParallelExecutor) Step(res *ExecResult) (result ParallelExecutionResul
|
||||||
|
|
||||||
type PropertyCheck func(*ParallelExecutor) error
|
type PropertyCheck func(*ParallelExecutor) error
|
||||||
|
|
||||||
func executeParallelWithCheck(tasks []ExecTask, profile bool, check PropertyCheck, metadata bool) (result ParallelExecutionResult, err error) {
|
func executeParallelWithCheck(tasks []ExecTask, profile bool, check PropertyCheck, metadata bool, interruptCtx context.Context) (result ParallelExecutionResult, err error) {
|
||||||
if len(tasks) == 0 {
|
if len(tasks) == 0 {
|
||||||
return ParallelExecutionResult{MakeTxnInputOutput(len(tasks)), nil, nil, nil}, nil
|
return ParallelExecutionResult{MakeTxnInputOutput(len(tasks)), nil, nil, nil}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -591,6 +590,15 @@ func executeParallelWithCheck(tasks []ExecTask, profile bool, check PropertyChec
|
||||||
pe.Prepare()
|
pe.Prepare()
|
||||||
|
|
||||||
for range pe.chResults {
|
for range pe.chResults {
|
||||||
|
if interruptCtx != nil {
|
||||||
|
select {
|
||||||
|
case <-interruptCtx.Done():
|
||||||
|
pe.Close(true)
|
||||||
|
return result, interruptCtx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
res := pe.resultQueue.Pop().(ExecResult)
|
res := pe.resultQueue.Pop().(ExecResult)
|
||||||
|
|
||||||
result, err = pe.Step(&res)
|
result, err = pe.Step(&res)
|
||||||
|
|
@ -611,6 +619,6 @@ func executeParallelWithCheck(tasks []ExecTask, profile bool, check PropertyChec
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExecuteParallel(tasks []ExecTask, profile bool, metadata bool) (result ParallelExecutionResult, err error) {
|
func ExecuteParallel(tasks []ExecTask, profile bool, metadata bool, interruptCtx context.Context) (result ParallelExecutionResult, err error) {
|
||||||
return executeParallelWithCheck(tasks, profile, nil, metadata)
|
return executeParallelWithCheck(tasks, profile, nil, metadata, interruptCtx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ func runParallel(t *testing.T, tasks []ExecTask, validation PropertyCheck, metad
|
||||||
profile := false
|
profile := false
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
result, err := executeParallelWithCheck(tasks, false, validation, metadata)
|
result, err := executeParallelWithCheck(tasks, false, validation, metadata, nil)
|
||||||
|
|
||||||
if result.Deps != nil && profile {
|
if result.Deps != nil && profile {
|
||||||
result.Deps.Report(*result.Stats, func(str string) { fmt.Println(str) })
|
result.Deps.Report(*result.Stats, func(str string) { fmt.Println(str) })
|
||||||
|
|
@ -458,7 +458,7 @@ func runParallelGetMetadata(t *testing.T, tasks []ExecTask, validation PropertyC
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
// fmt.Println("len(tasks)", len(tasks))
|
// fmt.Println("len(tasks)", len(tasks))
|
||||||
res, err := executeParallelWithCheck(tasks, true, validation, false)
|
res, err := executeParallelWithCheck(tasks, true, validation, false, nil)
|
||||||
|
|
||||||
assert.NoError(t, err, "error occur during parallel execution")
|
assert.NoError(t, err, "error occur during parallel execution")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
|
||||||
backupStateDB := statedb.Copy()
|
backupStateDB := statedb.Copy()
|
||||||
|
|
||||||
profile := false
|
profile := false
|
||||||
result, err := blockstm.ExecuteParallel(tasks, false, metadata)
|
result, err := blockstm.ExecuteParallel(tasks, false, metadata, interruptCtx)
|
||||||
|
|
||||||
if err == nil && profile {
|
if err == nil && profile {
|
||||||
_, weight := result.Deps.LongestPath(*result.Stats)
|
_, weight := result.Deps.LongestPath(*result.Stats)
|
||||||
|
|
@ -412,7 +412,7 @@ func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.Stat
|
||||||
t.totalUsedGas = usedGas
|
t.totalUsedGas = usedGas
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = blockstm.ExecuteParallel(tasks, false, metadata)
|
_, err = blockstm.ExecuteParallel(tasks, false, metadata, interruptCtx)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue