1/*
2 * Copyright (c) 2016-2017, Randy Westlund. All rights reserved.
3 * This code is under the BSD-2-Clause license.
4 *
5 * This file contains the process management logic.
6 */
7
8package main
9
10import (
11	"log"
12	"time"
13)
14
15// Called whenever a child launches.
16func handleRunning(
17	procs map[string]*process,
18	runningChan, doneChan chan launchStatus,
19	status launchStatus,
20	runningProcesses *int,
21) {
22	log.Println("Process", status.Name, "\trunning as\t", status.Pid)
23	var proc *process = procs[status.Name]
24	proc.Running = true
25
26	// Check to see whether anything was waiting on this.
27	for i := range procs {
28		if contains(procs[i].Config.SoftDepends, proc.Config.Name) {
29			log.Println("Process", procs[i].Config.Name,
30				"\twas waiting for\t", status.Name)
31			var ready = true
32			for _, v := range procs[i].Config.SoftDepends {
33				if procs[v].Running == false {
34					ready = false
35				}
36			}
37			if ready {
38				go launchProcess(procs[i].Config, runningChan, doneChan)
39				*runningProcesses++
40			}
41		}
42	}
43}
44
45// Called whenever a child exits. Take appropriate action, such as restarting.
46func handleDone(
47	procs map[string]*process,
48	runningChan, doneChan chan launchStatus,
49	status launchStatus,
50	runningProcesses *int,
51	shutdown bool,
52) {
53	var proc *process = procs[status.Name]
54
55	// If there was an error and we should try to start it again.
56	if status.Err != nil && proc.Config.IgnoreFailure == false && !shutdown {
57		log.Println("Process", proc.Config.Name, "\tfailed after",
58			status.Duration.String())
59		// Give up if it failed too quickly.
60		if proc.Config.MinRuntime != 0 &&
61			time.Duration(proc.Config.MinRuntime)*time.Millisecond > status.Duration {
62			log.Println("Process", proc.Config.Name, "\tfailed too quickly. Giving up.")
63		} else {
64			// If it didn't fail too quickly, continue with restart. Wait the
65			// required time before restarting.
66			time.Sleep(time.Duration(proc.Config.RestartDelay) * time.Millisecond)
67
68			// Actually restart it.
69			go launchProcess(proc.Config, runningChan, doneChan)
70			*runningProcesses++
71		}
72	} else {
73		// If the process completed successfully or we don't care.
74		log.Println("Process", proc.Config.Name, "\tfinished after",
75			status.Duration.String())
76	}
77}
78