48 lines
1.2 KiB
Go
48 lines
1.2 KiB
Go
// Package sandbox provides a registry of sandboxes
|
|
// for code execution.
|
|
package sandbox
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/nalgeon/codapi/engine"
|
|
)
|
|
|
|
var ErrUnknownSandbox = errors.New("unknown sandbox")
|
|
var ErrUnknownCommand = errors.New("unknown command")
|
|
var ErrEmptyRequest = errors.New("empty request")
|
|
|
|
// Validate checks if the code execution request is valid.
|
|
func Validate(in engine.Request) error {
|
|
box, ok := engines[in.Sandbox]
|
|
if !ok {
|
|
return ErrUnknownSandbox
|
|
}
|
|
_, ok = box[in.Command]
|
|
if !ok {
|
|
return ErrUnknownCommand
|
|
}
|
|
if len(in.Files) < 2 && strings.TrimSpace(in.Files.First()) == "" {
|
|
return ErrEmptyRequest
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Exec executes the code using the appropriate sandbox.
|
|
// Allows no more than pool.Size() concurrent workers at any given time.
|
|
// The request must already be validated by Validate().
|
|
func Exec(in engine.Request) engine.Execution {
|
|
err := semaphore.Acquire()
|
|
defer semaphore.Release()
|
|
if err == ErrBusy {
|
|
return engine.Fail(in.ID, engine.ErrBusy)
|
|
}
|
|
start := time.Now()
|
|
engine := engines[in.Sandbox][in.Command]
|
|
out := engine.Exec(in)
|
|
out.Duration = int(time.Since(start).Milliseconds())
|
|
return out
|
|
}
|