pt/src/em.v
2024-10-20 09:00:19 +03:00

110 lines
2.7 KiB
V

module main
import arrays
import os
import log
struct EntryManager {
config Config
}
fn EntryManager.new(config Config) EntryManager {
return EntryManager{
config: config
}
}
fn (em EntryManager) labels() []string {
mut labels := []string{}
for _, val in em.config.entries {
labels << val.labels
}
return arrays.uniq(labels.sorted())
}
fn (em EntryManager) by_labels(labels []string) []Entry {
log.debug('Lookup entries by labels: ${labels}')
mut entries := []Entry{}
for _, val in em.config.entries {
mut found := true
for label in labels {
if label !in val.labels {
found = false
}
}
if found == true {
entries << val
}
}
return entries
}
fn (em EntryManager) by_name(name string) !Entry {
log.debug('Lookup entry: ${name}')
return em.config.entries[name] or { error('No such entry named ${name}') }
}
fn (em EntryManager) run(entry Entry) ! {
is_running := em.is_running(entry.name) or { false }
if is_running {
log.warn("Entry '${entry.name}' is already running")
return
}
log.debug('Starting up entry: ${entry.name}')
log.debug('${entry}')
mut process := os.new_process(entry.exec[0])
process.set_args(entry.exec[1..])
process.set_environment(entry.env)
process.set_work_folder(if entry.workdir == '' { os.getwd() } else { os.abs_path(entry.workdir) })
process.run()
pidfile := get_pidfile_path(rundir: em.config.rundir, entry: entry.name, path: entry.pidfile)
write_pidfile(pidfile, process.pid)
}
fn (em EntryManager) signal(name string, signal os.Signal) ! {
entry := em.by_name(name) or { return err }
pidfile := get_pidfile_path(rundir: em.config.rundir, entry: entry.name, path: entry.pidfile)
pid := read_pidfile(pidfile)
send_signal(pid, signal)
}
fn (em EntryManager) processes() []Entry {
mut pidfiles := get_pidfiles(em.config.rundir)
for _, entry in em.config.entries {
if entry.pidfile != '' && entry.pidfile !in pidfiles {
pidfiles << entry.pidfile
}
}
mut running_entries := []Entry{}
for pidfile in pidfiles {
pid := read_pidfile(pidfile)
if os.exists(os.join_path_single('/proc', pid.str())) {
entry_name := os.file_name(pidfile).split('.')[0]
mut entry := em.by_name(entry_name) or { Entry{} }
if entry.name != '' {
entry.pid = pid
running_entries << entry
}
} else {
os.rm(pidfile) or {} // FIXME
}
}
return running_entries
}
fn (em EntryManager) is_running(name string) !bool {
entry := em.by_name(name) or { return err }
pidfile := get_pidfile_path(rundir: em.config.rundir, entry: entry.name, path: entry.pidfile)
if os.exists(pidfile) {
pid := read_pidfile(pidfile)
if os.exists(os.join_path_single('/proc', pid.str())) {
return true
} else {
os.rm(pidfile) or { return err }
return false
}
} else {
return false
}
}