Skip to content

Commit 2756b08

Browse files
committed
Separate result to step and result
1 parent 32c1ce9 commit 2756b08

7 files changed

+158
-97
lines changed

benchmark.go

+33-23
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ var (
1616
ErrValidation failure.StringCode = "validation"
1717
)
1818

19-
type BenchmarkStep func(context.Context, *Result) error
20-
type BenchmarkErrorHook func(error, *Result)
19+
type BenchmarkStepFunc func(context.Context, *BenchmarkStep) error
20+
type BenchmarkErrorHook func(error, *BenchmarkStep)
2121

2222
type Benchmark struct {
2323
mu sync.Mutex
2424

25-
prepareSteps []BenchmarkStep
26-
loadSteps []BenchmarkStep
27-
validationSteps []BenchmarkStep
25+
prepareSteps []BenchmarkStepFunc
26+
loadSteps []BenchmarkStepFunc
27+
validationSteps []BenchmarkStepFunc
2828

2929
prepateTimeout time.Duration
3030
loadTimeout time.Duration
@@ -35,9 +35,9 @@ type Benchmark struct {
3535
func NewBenchmark(opts ...BenchmarkOption) (*Benchmark, error) {
3636
benchmark := &Benchmark{
3737
mu: sync.Mutex{},
38-
prepareSteps: []BenchmarkStep{},
39-
loadSteps: []BenchmarkStep{},
40-
validationSteps: []BenchmarkStep{},
38+
prepareSteps: []BenchmarkStepFunc{},
39+
loadSteps: []BenchmarkStepFunc{},
40+
validationSteps: []BenchmarkStepFunc{},
4141
prepateTimeout: time.Duration(0),
4242
loadTimeout: time.Duration(0),
4343
ignoreCodes: []failure.Code{},
@@ -53,15 +53,21 @@ func NewBenchmark(opts ...BenchmarkOption) (*Benchmark, error) {
5353
return benchmark, nil
5454
}
5555

56-
func (b *Benchmark) Start(parent context.Context) *Result {
56+
func (b *Benchmark) Start(parent context.Context) *BenchmarkResult {
5757
ctx, cancel := context.WithCancel(parent)
58-
result := newResult(ctx, cancel)
59-
defer result.Cancel()
58+
result := newBenchmarkResult(ctx)
59+
defer cancel()
60+
61+
step := &BenchmarkStep{
62+
mu: sync.RWMutex{},
63+
result: result,
64+
cancel: cancel,
65+
}
6066

6167
for _, hook := range b.errorHooks {
6268
func(hook BenchmarkErrorHook) {
6369
result.Errors.Hook(func(err error) {
64-
hook(err, result)
70+
hook(err, step)
6571
})
6672
}(hook)
6773
}
@@ -72,6 +78,7 @@ func (b *Benchmark) Start(parent context.Context) *Result {
7278
loadCancel context.CancelFunc
7379
)
7480

81+
step.setErrorCode(ErrPrepare)
7582
for _, prepare := range b.prepareSteps {
7683
var (
7784
prepareCtx context.Context
@@ -85,13 +92,13 @@ func (b *Benchmark) Start(parent context.Context) *Result {
8592
}
8693
defer prepareCancel()
8794

88-
if err := panicWrapper(func() error { return prepare(prepareCtx, result) }); err != nil {
95+
if err := panicWrapper(func() error { return prepare(prepareCtx, step) }); err != nil {
8996
for _, ignore := range b.ignoreCodes {
9097
if failure.IsCode(err, ignore) {
9198
goto Result
9299
}
93100
}
94-
result.Errors.Add(failure.NewError(ErrPrepare, err))
101+
step.AddError(err)
95102
goto Result
96103
}
97104
}
@@ -102,6 +109,7 @@ func (b *Benchmark) Start(parent context.Context) *Result {
102109
goto Result
103110
}
104111

112+
step.setErrorCode(ErrLoad)
105113
if b.loadTimeout > 0 {
106114
loadCtx, loadCancel = context.WithTimeout(ctx, b.loadTimeout)
107115
} else {
@@ -110,15 +118,15 @@ func (b *Benchmark) Start(parent context.Context) *Result {
110118
defer loadCancel()
111119

112120
for _, load := range b.loadSteps {
113-
func(f BenchmarkStep) {
121+
func(f BenchmarkStepFunc) {
114122
loadParallel.Do(loadCtx, func(c context.Context) {
115-
if err := panicWrapper(func() error { return f(c, result) }); err != nil {
123+
if err := panicWrapper(func() error { return f(c, step) }); err != nil {
116124
for _, ignore := range b.ignoreCodes {
117125
if failure.IsCode(err, ignore) {
118126
return
119127
}
120128
}
121-
result.Errors.Add(failure.NewError(ErrLoad, err))
129+
step.AddError(err)
122130
}
123131
})
124132
}(load)
@@ -131,21 +139,23 @@ func (b *Benchmark) Start(parent context.Context) *Result {
131139
goto Result
132140
}
133141

142+
step.setErrorCode(ErrValidation)
134143
for _, validation := range b.validationSteps {
135-
if err := panicWrapper(func() error { return validation(ctx, result) }); err != nil {
144+
if err := panicWrapper(func() error { return validation(ctx, step) }); err != nil {
136145
for _, ignore := range b.ignoreCodes {
137146
if failure.IsCode(err, ignore) {
138147
goto Result
139148
}
140149
}
141-
result.Errors.Add(failure.NewError(ErrValidation, err))
150+
step.AddError(err)
142151
goto Result
143152
}
144153
}
145154

146155
Result:
147156
cancel()
148-
result.wait()
157+
step.wait()
158+
step.setErrorCode(nil)
149159

150160
return result
151161
}
@@ -157,21 +167,21 @@ func (b *Benchmark) OnError(f BenchmarkErrorHook) {
157167
b.errorHooks = append(b.errorHooks, f)
158168
}
159169

160-
func (b *Benchmark) Prepare(f BenchmarkStep) {
170+
func (b *Benchmark) Prepare(f BenchmarkStepFunc) {
161171
b.mu.Lock()
162172
defer b.mu.Unlock()
163173

164174
b.prepareSteps = append(b.prepareSteps, f)
165175
}
166176

167-
func (b *Benchmark) Load(f BenchmarkStep) {
177+
func (b *Benchmark) Load(f BenchmarkStepFunc) {
168178
b.mu.Lock()
169179
defer b.mu.Unlock()
170180

171181
b.loadSteps = append(b.loadSteps, f)
172182
}
173183

174-
func (b *Benchmark) Validation(f BenchmarkStep) {
184+
func (b *Benchmark) Validation(f BenchmarkStepFunc) {
175185
b.mu.Lock()
176186
defer b.mu.Unlock()
177187

benchmark_result.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package isucandar
2+
3+
import (
4+
"context"
5+
"github.com/rosylilly/isucandar/failure"
6+
"github.com/rosylilly/isucandar/score"
7+
)
8+
9+
type BenchmarkResult struct {
10+
Score *score.Score
11+
Errors *failure.Errors
12+
}
13+
14+
func newBenchmarkResult(ctx context.Context) *BenchmarkResult {
15+
return &BenchmarkResult{
16+
Score: score.NewScore(ctx),
17+
Errors: failure.NewErrors(ctx),
18+
}
19+
}

scenario.go benchmark_scenario.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ var (
1010
)
1111

1212
type PrepareScenario interface {
13-
Prepare(context.Context, *Result) error
13+
Prepare(context.Context, *BenchmarkStep) error
1414
}
1515

1616
type LoadScenario interface {
17-
Load(context.Context, *Result) error
17+
Load(context.Context, *BenchmarkStep) error
1818
}
1919

2020
type ValidationScenario interface {
21-
Validation(context.Context, *Result) error
21+
Validation(context.Context, *BenchmarkStep) error
2222
}
2323

2424
func (b *Benchmark) AddScenario(scenario interface{}) {

scenario_test.go benchmark_scenario_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ type exampleScenario struct {
1212
validation uint32
1313
}
1414

15-
func (e *exampleScenario) Prepare(_ context.Context, r *Result) error {
15+
func (e *exampleScenario) Prepare(_ context.Context, _ *BenchmarkStep) error {
1616
atomic.StoreUint32(&e.prepare, 1)
1717
return nil
1818
}
1919

20-
func (e *exampleScenario) Load(_ context.Context, r *Result) error {
20+
func (e *exampleScenario) Load(_ context.Context, _ *BenchmarkStep) error {
2121
atomic.StoreUint32(&e.load, 1)
2222
return nil
2323
}
2424

25-
func (e *exampleScenario) Validation(_ context.Context, r *Result) error {
25+
func (e *exampleScenario) Validation(_ context.Context, _ *BenchmarkStep) error {
2626
atomic.StoreUint32(&e.validation, 1)
2727
return nil
2828
}

benchmark_step.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package isucandar
2+
3+
import (
4+
"context"
5+
"github.com/rosylilly/isucandar/failure"
6+
"github.com/rosylilly/isucandar/score"
7+
"sync"
8+
)
9+
10+
type BenchmarkStep struct {
11+
errorCode failure.Code
12+
mu sync.RWMutex
13+
result *BenchmarkResult
14+
cancel context.CancelFunc
15+
}
16+
17+
func (b *BenchmarkStep) setErrorCode(code failure.Code) {
18+
b.mu.Lock()
19+
defer b.mu.Unlock()
20+
21+
b.errorCode = code
22+
}
23+
24+
func (b *BenchmarkStep) AddError(err error) {
25+
b.mu.RLock()
26+
defer b.mu.RUnlock()
27+
28+
b.result.Errors.Add(failure.NewError(b.errorCode, err))
29+
}
30+
31+
func (b *BenchmarkStep) AddScore(tag score.ScoreTag) {
32+
b.result.Score.Add(tag)
33+
}
34+
35+
func (b *BenchmarkStep) Cancel() {
36+
b.cancel()
37+
}
38+
39+
func (b *BenchmarkStep) wait() {
40+
wg := sync.WaitGroup{}
41+
wg.Add(1)
42+
go func() {
43+
b.result.Score.Wait()
44+
wg.Done()
45+
}()
46+
wg.Add(1)
47+
go func() {
48+
b.result.Errors.Wait()
49+
wg.Done()
50+
}()
51+
wg.Wait()
52+
}

0 commit comments

Comments
 (0)