module daemon import time import sync.stdatomic import build import os const ( build_empty = 0 build_running = 1 build_done = 2 ) // clean_finished_builds removes finished builds from the build slots & returns // them. fn (mut d Daemon) clean_finished_builds() []ScheduledBuild { mut out := []ScheduledBuild{} for i in 0 .. d.atomics.len { if stdatomic.load_u64(&d.atomics[i]) == daemon.build_done { stdatomic.store_u64(&d.atomics[i], daemon.build_empty) out << d.builds[i] } } return out } // update_builds starts as many builds as possible. fn (mut d Daemon) start_new_builds() { now := time.now() for d.queue.len() > 0 { elem := d.queue.peek() or { d.lerror("queue.peek() unexpectedly returned an error. This shouldn't happen.") break } if elem.timestamp < now { sb := d.queue.pop() or { d.lerror("queue.pop() unexpectedly returned an error. This shouldn't happen.") break } // If this build couldn't be scheduled, no more will be possible. if !d.start_build(sb) { d.queue.insert(sb) break } } else { break } } } // start_build starts a build for the given ScheduledBuild object. fn (mut d Daemon) start_build(sb ScheduledBuild) bool { for i in 0 .. d.atomics.len { if stdatomic.load_u64(&d.atomics[i]) == daemon.build_empty { stdatomic.store_u64(&d.atomics[i], daemon.build_running) d.builds[i] = sb go d.run_build(i, sb) return true } } return false } // run_build actually starts the build process for a given target. fn (mut d Daemon) run_build(build_index int, sb ScheduledBuild) { d.linfo('started build: $sb.target.url -> $sb.target.repo') // 0 means success, 1 means failure mut status := 0 res := build.build_target(d.client.address, d.client.api_key, d.builder_images.last(), &sb.target, false) or { d.ldebug('build_target error: $err.msg()') status = 1 build.BuildResult{} } if status == 0 { d.linfo('finished build: $sb.target.url -> $sb.target.repo; uploading logs...') build_arch := os.uname().machine d.client.add_build_log(sb.target.id, res.start_time, res.end_time, build_arch, res.exit_code, res.logs) or { d.lerror('Failed to upload logs for build: $sb.target.url -> $sb.target.repo') } } else { d.linfo('an error occured during build: $sb.target.url -> $sb.target.repo') } stdatomic.store_u64(&d.atomics[build_index], daemon.build_done) } // current_build_count returns how many builds are currently running. fn (mut d Daemon) current_build_count() int { mut res := 0 for i in 0 .. d.atomics.len { if stdatomic.load_u64(&d.atomics[i]) == daemon.build_running { res += 1 } } return res }