mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-03 23:06:36 +08:00
[优化] 确保所有管理的进程在停止时被正确取消和清理
This commit is contained in:
@@ -50,3 +50,4 @@ go.work.sum
|
|||||||
|
|
||||||
*-source
|
*-source
|
||||||
*-source.*
|
*-source.*
|
||||||
|
.codex*
|
||||||
@@ -31,6 +31,7 @@ func (r *Runner) Run(ctx context.Context) error {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
|
r.FrpcManager.Stop()
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,10 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
|||||||
_ = os.Remove(pidPath)
|
_ = os.Remove(pidPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
procCtx, cancel := context.WithCancel(context.Background())
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
procCtx, cancel := context.WithCancel(ctx)
|
||||||
proc := &Process{
|
proc := &Process{
|
||||||
RelayID: relayID,
|
RelayID: relayID,
|
||||||
Cancel: cancel,
|
Cancel: cancel,
|
||||||
@@ -223,6 +226,20 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) Stop() {
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
|
for relayID, proc := range m.processes {
|
||||||
|
if proc != nil && proc.Cancel != nil {
|
||||||
|
proc.Cancel()
|
||||||
|
}
|
||||||
|
pidPath := filepath.Join(m.cfg.DataDir, fmt.Sprintf("frpc_%s.pid", relayID))
|
||||||
|
_ = os.Remove(pidPath)
|
||||||
|
delete(m.processes, relayID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func buildFrpcToml(relay service.FlaredRelayInfo, proxies []service.FlaredProxyEntry) string {
|
func buildFrpcToml(relay service.FlaredRelayInfo, proxies []service.FlaredProxyEntry) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
|||||||
@@ -335,3 +335,53 @@ func TestUpdateConfigKillsOrphanProcessBeforeRestart(t *testing.T) {
|
|||||||
m.mu.RUnlock()
|
m.mu.RUnlock()
|
||||||
proc.Cancel()
|
proc.Cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStopCancelsRunningProcesses(t *testing.T) {
|
||||||
|
scriptPath, dir := setupDummyScript(t)
|
||||||
|
writeControl(t, dir, 0, 30)
|
||||||
|
|
||||||
|
cfg := &config.Config{
|
||||||
|
ServerURL: "http://localhost:8080",
|
||||||
|
TunnelToken: "test-token",
|
||||||
|
FrpcPath: scriptPath,
|
||||||
|
DataDir: dir,
|
||||||
|
StatePath: filepath.Join(dir, "flared-state.json"),
|
||||||
|
}
|
||||||
|
|
||||||
|
m := NewManager(cfg)
|
||||||
|
newConfig := &service.FlaredTunnelConfigResponse{
|
||||||
|
Version: "1",
|
||||||
|
Checksum: "sum1",
|
||||||
|
Relays: []service.FlaredRelayInfo{
|
||||||
|
{
|
||||||
|
RelayNodeID: "relay-1",
|
||||||
|
Address: "127.0.0.1:7000",
|
||||||
|
AuthToken: "auth-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := m.UpdateConfig(context.Background(), newConfig); err != nil {
|
||||||
|
t.Fatalf("failed to UpdateConfig: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertStatusEventually(t, m, "relay-1", "running", 4*time.Second)
|
||||||
|
|
||||||
|
m.mu.RLock()
|
||||||
|
proc := m.processes["relay-1"]
|
||||||
|
if proc == nil || proc.Cmd == nil {
|
||||||
|
m.mu.RUnlock()
|
||||||
|
t.Fatal("expected running process to have a command handle")
|
||||||
|
}
|
||||||
|
cmd := proc.Cmd
|
||||||
|
m.mu.RUnlock()
|
||||||
|
|
||||||
|
m.Stop()
|
||||||
|
assertCommandExitedEventually(t, cmd, 2*time.Second)
|
||||||
|
|
||||||
|
m.mu.RLock()
|
||||||
|
defer m.mu.RUnlock()
|
||||||
|
if len(m.processes) != 0 {
|
||||||
|
t.Fatalf("expected no managed processes after stop, got %d", len(m.processes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user