72 lines
1.5 KiB
Go
72 lines
1.5 KiB
Go
package workers
|
|
|
|
import (
|
|
"errors"
|
|
"sync/atomic"
|
|
|
|
luajit "git.sharkk.net/Sky/LuaJIT-to-Go"
|
|
)
|
|
|
|
// Common errors
|
|
var (
|
|
ErrPoolClosed = errors.New("worker pool is closed")
|
|
ErrNoWorkers = errors.New("no workers available")
|
|
ErrInitFailed = errors.New("worker initialization failed")
|
|
)
|
|
|
|
// worker represents a single Lua execution worker
|
|
type worker struct {
|
|
pool *Pool // Reference to the pool
|
|
state *luajit.State // Lua state
|
|
id uint32 // Worker ID
|
|
}
|
|
|
|
// run is the main worker function that processes jobs
|
|
func (w *worker) run() {
|
|
defer w.pool.wg.Done()
|
|
|
|
// Initialize Lua state
|
|
w.state = luajit.New()
|
|
if w.state == nil {
|
|
// Worker failed to initialize, decrement counter
|
|
atomic.AddUint32(&w.pool.workers, ^uint32(0))
|
|
return
|
|
}
|
|
defer w.state.Close()
|
|
|
|
// Set up sandbox environment
|
|
if err := w.setupSandbox(); err != nil {
|
|
// Worker failed to initialize sandbox, decrement counter
|
|
atomic.AddUint32(&w.pool.workers, ^uint32(0))
|
|
return
|
|
}
|
|
|
|
// Run init function if provided
|
|
if w.pool.stateInit != nil {
|
|
if err := w.pool.stateInit(w.state); err != nil {
|
|
// Worker failed to initialize with custom init function
|
|
atomic.AddUint32(&w.pool.workers, ^uint32(0))
|
|
return
|
|
}
|
|
}
|
|
|
|
// Main worker loop
|
|
for {
|
|
select {
|
|
case job, ok := <-w.pool.jobs:
|
|
if !ok {
|
|
// Jobs channel closed, exit
|
|
return
|
|
}
|
|
|
|
// Execute job
|
|
result := w.executeJobSandboxed(job)
|
|
job.Result <- result
|
|
|
|
case <-w.pool.quit:
|
|
// Quit signal received, exit
|
|
return
|
|
}
|
|
}
|
|
}
|