File size: 2,521 Bytes
6a7089a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | package orchestrator
import (
"net"
"sort"
"strings"
"sync"
"time"
)
func instanceIsActive(inst *InstanceInternal) bool {
if inst == nil {
return false
}
if inst.cmd != nil {
return isProcessAlive(inst.cmd.PID())
}
return inst.Status == "starting" || inst.Status == "running" || inst.Status == "stopping"
}
func waitForProcessExit(pid int, timeout time.Duration) bool {
if pid <= 0 {
return true
}
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
if !isProcessAlive(pid) {
return true
}
time.Sleep(150 * time.Millisecond)
}
return !isProcessAlive(pid)
}
var processAliveFunc = processAlive
func isProcessAlive(pid int) bool {
return processAliveFunc(pid)
}
func isPortAvailable(port string) bool {
ln, err := net.Listen("tcp", ":"+port)
if err != nil {
return false
}
_ = ln.Close()
return true
}
func tailLogLine(logs string) string {
if logs == "" {
return ""
}
lines := strings.Split(strings.TrimSpace(logs), "\n")
for i := len(lines) - 1; i >= 0; i-- {
line := strings.TrimSpace(lines[i])
if line == "" {
continue
}
const max = 220
if len(line) > max {
return line[len(line)-max:]
}
return line
}
return ""
}
func mergeEnvWithOverrides(base []string, overrides map[string]string) []string {
out := make([]string, 0, len(base)+len(overrides))
for _, kv := range base {
key, _, ok := strings.Cut(kv, "=")
if !ok {
continue
}
if _, exists := overrides[key]; exists {
continue
}
out = append(out, kv)
}
keys := make([]string, 0, len(overrides))
for k := range overrides {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
out = append(out, k+"="+overrides[k])
}
return out
}
func filterEnvWithPrefixes(env []string, prefixes ...string) []string {
out := make([]string, 0, len(env))
for _, e := range env {
skip := false
for _, p := range prefixes {
if strings.HasPrefix(e, p) {
skip = true
break
}
}
if !skip {
out = append(out, e)
}
}
return out
}
type ringBuffer struct {
mu sync.Mutex
data []byte
max int
}
func newRingBuffer(max int) *ringBuffer {
return &ringBuffer{max: max, data: make([]byte, 0, max)}
}
func (rb *ringBuffer) Write(p []byte) (int, error) {
rb.mu.Lock()
defer rb.mu.Unlock()
rb.data = append(rb.data, p...)
if len(rb.data) > rb.max {
rb.data = rb.data[len(rb.data)-rb.max:]
}
return len(p), nil
}
func (rb *ringBuffer) String() string {
rb.mu.Lock()
defer rb.mu.Unlock()
return string(rb.data)
}
|