ms-runner/internal/runner/usecase/usecase.go
Vyacheslav1557 1fa11f66e3 feat:
2024-11-01 23:22:43 +05:00

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()
}