106 lines
1.9 KiB
Go
106 lines
1.9 KiB
Go
|
package usecase
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type BuildInstruction struct {
|
||
|
SolutionId int32
|
||
|
BindingKey string
|
||
|
Language int32
|
||
|
Solution string
|
||
|
}
|
||
|
|
||
|
type BuildResult struct {
|
||
|
SolutionId int32
|
||
|
BindingKey string
|
||
|
Status int32
|
||
|
}
|
||
|
|
||
|
type RunInstruction struct {
|
||
|
SolutionId int32
|
||
|
TestId int32
|
||
|
BindingKey string
|
||
|
}
|
||
|
|
||
|
type RunResult struct {
|
||
|
SolutionId int32
|
||
|
TestId int32
|
||
|
BindingKey string
|
||
|
Status int32
|
||
|
}
|
||
|
|
||
|
type RunnerUseCase struct {
|
||
|
freeProcesses int32
|
||
|
mtx sync.RWMutex
|
||
|
results chan interface{}
|
||
|
}
|
||
|
|
||
|
func NewRunnerUseCase(limit int32) *RunnerUseCase {
|
||
|
return &RunnerUseCase{
|
||
|
freeProcesses: limit,
|
||
|
results: make(chan interface{}),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (uc *RunnerUseCase) Process(i interface{}) error {
|
||
|
uc.mtx.Lock()
|
||
|
defer uc.mtx.Unlock()
|
||
|
if uc.freeProcesses == 0 {
|
||
|
return errors.New("no free processes")
|
||
|
}
|
||
|
uc.freeProcesses--
|
||
|
|
||
|
go func(i interface{}) {
|
||
|
defer func() {
|
||
|
uc.mtx.Lock()
|
||
|
uc.freeProcesses++
|
||
|
uc.mtx.Unlock()
|
||
|
}()
|
||
|
|
||
|
switch instruction := i.(type) {
|
||
|
case RunInstruction:
|
||
|
fmt.Println("running: ", instruction.SolutionId, instruction.TestId)
|
||
|
time.Sleep(time.Second)
|
||
|
uc.results <- RunResult{
|
||
|
SolutionId: instruction.SolutionId,
|
||
|
TestId: instruction.TestId,
|
||
|
BindingKey: instruction.BindingKey,
|
||
|
Status: 0,
|
||
|
}
|
||
|
case BuildInstruction:
|
||
|
fmt.Println("building:", instruction.Language, instruction.Solution)
|
||
|
time.Sleep(time.Second)
|
||
|
uc.results <- BuildResult{
|
||
|
SolutionId: instruction.SolutionId,
|
||
|
BindingKey: instruction.BindingKey,
|
||
|
Status: -1,
|
||
|
}
|
||
|
default:
|
||
|
fmt.Println("unknown instruction ignored")
|
||
|
}
|
||
|
}(i)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (uc *RunnerUseCase) Results() <-chan interface{} {
|
||
|
return uc.results
|
||
|
}
|
||
|
|
||
|
// Ready is not thread safe!
|
||
|
func (uc *RunnerUseCase) Ready() bool {
|
||
|
return uc.freeProcesses > 0
|
||
|
}
|
||
|
|
||
|
func (uc *RunnerUseCase) Lock() {
|
||
|
uc.mtx.Lock()
|
||
|
}
|
||
|
|
||
|
func (uc *RunnerUseCase) Unlock() {
|
||
|
uc.mtx.Unlock()
|
||
|
}
|