fix: Fixes 100% CPU usage in the backend runtime

This makes the backend runtime not constantly search for messages to be
processed. Instead, it only wakes up when it needs to be woken up via
goroutines.
This commit is contained in:
Tera << 8 2025-03-21 13:17:08 -04:00
parent d56a8eb7bf
commit b93bf456b5
Signed by: imterah
GPG key ID: 8FA7DD57BA6CEA37
2 changed files with 21 additions and 5 deletions

View file

@ -15,6 +15,9 @@ import (
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
) )
// TODO TODO TODO(imterah):
// This code is a mess. This NEEDS to be rearchitected and refactored to work better. Or at the very least, this code needs to be documented heavily.
func handleCommand(command interface{}, sock net.Conn, rtcChan chan interface{}) error { func handleCommand(command interface{}, sock net.Conn, rtcChan chan interface{}) error {
bytes, err := commonbackend.Marshal(command) bytes, err := commonbackend.Marshal(command)
@ -160,6 +163,9 @@ func (runtime *Runtime) goRoutineHandler() error {
OuterLoop: OuterLoop:
for { for {
_ = <-runtime.startProcessingNotification
runtime.isRuntimeCurrentlyProcessing = true
for chanIndex, messageData := range runtime.messageBuffer { for chanIndex, messageData := range runtime.messageBuffer {
if messageData == nil { if messageData == nil {
continue continue
@ -177,6 +183,8 @@ func (runtime *Runtime) goRoutineHandler() error {
runtime.messageBuffer[chanIndex] = nil runtime.messageBuffer[chanIndex] = nil
} }
runtime.isRuntimeCurrentlyProcessing = false
} }
sock.Close() sock.Close()
@ -235,6 +243,7 @@ func (runtime *Runtime) Start() error {
runtime.messageBuffer = make([]*messageForBuf, 10) runtime.messageBuffer = make([]*messageForBuf, 10)
runtime.messageBufferLock = sync.Mutex{} runtime.messageBufferLock = sync.Mutex{}
runtime.startProcessingNotification = make(chan bool)
runtime.processRestartNotification = make(chan bool, 1) runtime.processRestartNotification = make(chan bool, 1)
runtime.logger = &writeLogger{ runtime.logger = &writeLogger{
@ -322,6 +331,10 @@ SchedulingLoop:
schedulingAttempts++ schedulingAttempts++
} }
if !runtime.isRuntimeCurrentlyProcessing {
runtime.startProcessingNotification <- true
}
// Fetch response and close Channel // Fetch response and close Channel
response, ok := <-commandChannel response, ok := <-commandChannel

View file

@ -16,15 +16,18 @@ type Backend struct {
type messageForBuf struct { type messageForBuf struct {
Channel chan interface{} Channel chan interface{}
// TODO(imterah): could this be refactored to just be a []byte instead? Look into this
Message interface{} Message interface{}
} }
type Runtime struct { type Runtime struct {
isRuntimeRunning bool isRuntimeRunning bool
logger *writeLogger isRuntimeCurrentlyProcessing bool
currentProcess *exec.Cmd startProcessingNotification chan bool
currentListener net.Listener logger *writeLogger
processRestartNotification chan bool currentProcess *exec.Cmd
currentListener net.Listener
processRestartNotification chan bool
messageBufferLock sync.Mutex messageBufferLock sync.Mutex
messageBuffer []*messageForBuf messageBuffer []*messageForBuf