Skip to content

Commit 7ff4b0e

Browse files
committed
feat: config hot-reload - fix merge conflicts
1 parent f3e73d3 commit 7ff4b0e

File tree

4 files changed

+34
-64
lines changed

4 files changed

+34
-64
lines changed

proxy/helpers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func getTestSimpleResponderConfigPort(expectedMessage string, port int) ModelCon
6363

6464
// Create a process configuration
6565
return ModelConfig{
66-
Cmd: fmt.Sprintf("%s --port %d --silent --respond %s", binaryPath, port, expectedMessage), // Re-added --silent
66+
Cmd: fmt.Sprintf("%s --port %d --respond %s", binaryPath, port, expectedMessage),
6767
Proxy: fmt.Sprintf("http://127.0.0.1:%d", port),
6868
CheckEndpoint: "/health",
6969
}

proxy/logMonitor_test.go

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,40 +21,27 @@ func TestLogMonitor(t *testing.T) {
2121
client2Messages := make([]byte, 0)
2222

2323
var wg sync.WaitGroup
24-
wg.Add(2) // One for each client (goroutine)
24+
wg.Add(1)
2525

26-
// Write messages first
27-
if _, err := logMonitor.Write([]byte("1")); err != nil {
28-
t.Fatalf("Failed to write log message: %v", err)
29-
}
30-
if _, err := logMonitor.Write([]byte("2")); err != nil {
31-
t.Fatalf("Failed to write log message: %v", err)
32-
}
33-
if _, err := logMonitor.Write([]byte("3")); err != nil {
34-
t.Fatalf("Failed to write log message: %v", err)
35-
}
36-
37-
// Start goroutines to collect messages
3826
go func() {
3927
defer wg.Done()
40-
messageCount := 0
41-
for messageCount < 3 {
42-
data := <-client1
43-
client1Messages = append(client1Messages, data...)
44-
messageCount++
28+
for {
29+
select {
30+
case data := <-client1:
31+
client1Messages = append(client1Messages, data...)
32+
case data := <-client2:
33+
client2Messages = append(client2Messages, data...)
34+
default:
35+
return
36+
}
4537
}
4638
}()
4739

48-
go func() {
49-
defer wg.Done()
50-
messageCount := 0
51-
for messageCount < 3 {
52-
data := <-client2
53-
client2Messages = append(client2Messages, data...)
54-
messageCount++
55-
}
56-
}()
57-
// Wait for both goroutines to finish
40+
logMonitor.Write([]byte("1"))
41+
logMonitor.Write([]byte("2"))
42+
logMonitor.Write([]byte("3"))
43+
44+
// Wait for the goroutine to finish
5845
wg.Wait()
5946

6047
// Check the buffer

proxy/process.go

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,8 @@ func isValidTransition(from, to ProcessState) bool {
119119
return to == StateStopping
120120
case StateStopping:
121121
return to == StateStopped || to == StateShutdown
122-
case StateFailed:
123-
return to == StateStopped // Allow resetting a failed process
124-
case StateShutdown:
125-
return false // No transitions from shutdown
122+
case StateFailed, StateShutdown:
123+
return false // No transitions allowed from these states
126124
}
127125
return false
128126
}
@@ -187,7 +185,7 @@ func (p *Process) start() error {
187185
return fmt.Errorf("start() failed: %v", err)
188186
}
189187

190-
// Capture the exit error for later signaling
188+
// Capture the exit error for later signalling
191189
go func() {
192190
exitErr := p.cmd.Wait()
193191
p.proxyLogger.Debugf("<%s> cmd.Wait() returned error: %v", p.ID, exitErr)
@@ -414,20 +412,7 @@ func (p *Process) ProxyRequest(w http.ResponseWriter, r *http.Request) {
414412

415413
// prevent new requests from being made while stopping or irrecoverable
416414
currentState := p.CurrentState()
417-
418-
if currentState == StateFailed {
419-
p.proxyLogger.Infof("<%s> Attempting to recover from failed state.", p.ID)
420-
// Attempt to reset the state to stopped so it can be restarted
421-
if _, err := p.swapState(StateFailed, StateStopped); err != nil {
422-
p.proxyLogger.Errorf("<%s> Failed to reset state from Failed to Stopped: %v. Current state: %s", p.ID, err, p.CurrentState())
423-
http.Error(w, fmt.Sprintf("Process failed and could not be reset, state is %s", p.CurrentState()), http.StatusServiceUnavailable)
424-
return
425-
}
426-
p.proxyLogger.Infof("<%s> Process state reset to Stopped from Failed.", p.ID)
427-
currentState = p.CurrentState() // Re-fetch current state, should now be StateStopped
428-
}
429-
430-
if currentState == StateShutdown || currentState == StateStopping {
415+
if currentState == StateFailed || currentState == StateShutdown || currentState == StateStopping {
431416
http.Error(w, fmt.Sprintf("Process can not ProxyRequest, state is %s", currentState), http.StatusServiceUnavailable)
432417
return
433418
}

proxy/process_test.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"net/http"
66
"net/http/httptest"
77
"os"
8+
"strings"
89
"sync"
910
"testing"
1011
"time"
@@ -18,10 +19,10 @@ var (
1819

1920
func init() {
2021
// flip to help with debugging tests
21-
if false { // Reverted to false
22+
if false {
2223
debugLogger.SetLogLevel(LevelDebug)
2324
} else {
24-
debugLogger.SetLogLevel(LevelError) // This will now be active
25+
debugLogger.SetLogLevel(LevelError)
2526
}
2627
}
2728

@@ -38,13 +39,14 @@ func TestProcess_AutomaticallyStartsUpstream(t *testing.T) {
3839
req := httptest.NewRequest("GET", "/test", nil)
3940
w := httptest.NewRecorder()
4041

41-
// process is automatically started
42-
assert.Equal(t, StateStopped, process.CurrentState())
4342
process.ProxyRequest(w, req)
44-
assert.Equal(t, StateReady, process.CurrentState())
4543

46-
assert.Equal(t, http.StatusOK, w.Code, "Expected status code %d, got %d", http.StatusOK, w.Code)
47-
assert.Contains(t, w.Body.String(), expectedMessage)
44+
if w.Code != http.StatusOK {
45+
t.Errorf("Expected status code %d, got %d", http.StatusOK, w.Code)
46+
}
47+
if !strings.Contains(w.Body.String(), expectedMessage) {
48+
t.Errorf("Expected body to contain '%s', got '%s'", expectedMessage, w.Body.String())
49+
}
4850

4951
// Stop the process
5052
process.Stop()
@@ -59,7 +61,6 @@ func TestProcess_AutomaticallyStartsUpstream(t *testing.T) {
5961
req = httptest.NewRequest("GET", "/", nil)
6062
w = httptest.NewRecorder()
6163

62-
// Proxy the request
6364
process.ProxyRequest(w, req)
6465

6566
// should have automatically started the process again
@@ -109,16 +110,13 @@ func TestProcess_BrokenModelConfig(t *testing.T) {
109110
req := httptest.NewRequest("GET", "/", nil)
110111
w := httptest.NewRecorder()
111112
process.ProxyRequest(w, req)
112-
assert.Equal(t, http.StatusBadGateway, w.Code) // First attempt fails to start
113-
assert.Contains(t, w.Body.String(), "unable to start process: start() failed: exec: \"nonexistent-command\": executable file not found in $PATH")
114-
assert.Equal(t, StateFailed, process.CurrentState()) // Should be in failed state after first attempt
113+
assert.Equal(t, http.StatusBadGateway, w.Code)
114+
assert.Contains(t, w.Body.String(), "unable to start process")
115115

116-
// Second request should also attempt to start and fail similarly due to recovery logic
117116
w = httptest.NewRecorder()
118117
process.ProxyRequest(w, req)
119-
assert.Equal(t, http.StatusBadGateway, w.Code) // Second attempt also fails to start
120-
assert.Contains(t, w.Body.String(), "unable to start process: start() failed: exec: \"nonexistent-command\": executable file not found in $PATH")
121-
assert.Equal(t, StateFailed, process.CurrentState()) // Should end up in failed state again
118+
assert.Equal(t, http.StatusServiceUnavailable, w.Code)
119+
assert.Contains(t, w.Body.String(), "Process can not ProxyRequest, state is failed")
122120
}
123121

124122
func TestProcess_UnloadAfterTTL(t *testing.T) {
@@ -269,7 +267,7 @@ func TestProcess_SwapState(t *testing.T) {
269267
{"Ready to Starting", StateReady, StateReady, StateStarting, ErrInvalidStateTransition, StateReady},
270268
{"Ready to Failed", StateReady, StateReady, StateFailed, ErrInvalidStateTransition, StateReady},
271269
{"Stopping to Ready", StateStopping, StateStopping, StateReady, ErrInvalidStateTransition, StateStopping},
272-
{"Failed to Stopped", StateFailed, StateFailed, StateStopped, nil, StateStopped},
270+
{"Failed to Stopped", StateFailed, StateFailed, StateStopped, ErrInvalidStateTransition, StateFailed},
273271
{"Failed to Starting", StateFailed, StateFailed, StateStarting, ErrInvalidStateTransition, StateFailed},
274272
{"Shutdown to Stopped", StateShutdown, StateShutdown, StateStopped, ErrInvalidStateTransition, StateShutdown},
275273
{"Shutdown to Starting", StateShutdown, StateShutdown, StateStarting, ErrInvalidStateTransition, StateShutdown},

0 commit comments

Comments
 (0)