File size: 6,039 Bytes
700dd75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/bin/bash

# kill_decoupled_wbc_processors.sh
# Kill decoupled_wbc processes in current container to prevent message passing conflicts

# Note: Don't use 'set -e' as tmux/pgrep commands may return non-zero exit codes

# Configuration
DRY_RUN=false
FORCE=false
QUIET=false
declare -A FOUND_PROCESSES

# Default to verbose mode if no arguments
[[ $# -eq 0 ]] && { QUIET=false; DRY_RUN=false; }

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --dry-run) DRY_RUN=true ;;
        --force) FORCE=true ;;
        --verbose|-v) VERBOSE=true ;;
        --help|-h)
            echo "Usage: $0 [--dry-run] [--force] [--verbose] [--help]"
            echo "Kill decoupled_wbc processes to prevent message passing conflicts"
            exit 0 ;;
        *) echo "Unknown option: $1"; exit 1 ;;
    esac
    shift
done

# Colors (only if not quiet)
if [[ "$QUIET" != true ]]; then
    RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
else
    RED=''; GREEN=''; YELLOW=''; BLUE=''; NC=''
fi

# Show processes by pattern (for preview)
show_processes_by_pattern() {
    local pattern="$1" desc="$2"
    local pids=$(pgrep -f "$pattern" 2>/dev/null || true)
    
    [[ -z "$pids" ]] && return 0
    
    echo -e "${YELLOW}$desc processes:${NC}"
    
    for pid in $pids; do
        local cmd=$(ps -p $pid -o cmd= 2>/dev/null || echo "Process not found")
        echo "  PID $pid: $cmd"
    done
}

# Kill processes by pattern (silent killing)
kill_by_pattern() {
    local pattern="$1" desc="$2" signal="${3:-TERM}"
    local pids=$(pgrep -f "$pattern" 2>/dev/null || true)
    
    [[ -z "$pids" ]] && return 0
    
    for pid in $pids; do
        # Kill if not dry run
        [[ "$DRY_RUN" != true ]] && kill -$signal $pid 2>/dev/null
    done
}

# Show tmux sessions (for preview)
show_tmux() {
    local pattern="$1"
    local sessions=$(tmux list-sessions 2>/dev/null | grep "$pattern" | cut -d: -f1 || true)
    
    [[ -z "$sessions" ]] && return 0
    
    echo -e "${YELLOW}Tmux sessions:${NC}"
    
    for session in $sessions; do
        echo "  Session: $session"
    done
}

# Kill tmux sessions (silent killing)
kill_tmux() {
    local pattern="$1"
    local sessions=$(tmux list-sessions 2>/dev/null | grep "$pattern" | cut -d: -f1 || true)
    
    [[ -z "$sessions" ]] && return 0
    
    for session in $sessions; do
        [[ "$DRY_RUN" != true ]] && tmux kill-session -t "$session" 2>/dev/null
    done
}

# Show processes by port (for preview)
show_processes_by_port() {
    local port="$1" desc="$2"
    local pids=$(lsof -ti:$port 2>/dev/null || true)
    
    [[ -z "$pids" ]] && return 0
    
    echo -e "${YELLOW}$desc (port $port):${NC}"
    
    for pid in $pids; do
        local cmd=$(ps -p $pid -o cmd= 2>/dev/null || echo "Process not found")
        echo "  PID $pid: $cmd"
    done
}

# Kill processes by port (silent killing)
kill_by_port() {
    local port="$1" desc="$2"
    local pids=$(lsof -ti:$port 2>/dev/null || true)
    
    [[ -z "$pids" ]] && return 0
    
    for pid in $pids; do
        [[ "$DRY_RUN" != true ]] && kill -TERM $pid 2>/dev/null
    done
}

# Check if any processes exist
has_processes() {
    # Check for processes
    local has_tmux=$(tmux list-sessions 2>/dev/null | grep "g1_deployment" || true)
    local has_control=$(pgrep -f "run_g1_control_loop.py" 2>/dev/null || true)
    local has_teleop=$(pgrep -f "run_teleop_policy_loop.py" 2>/dev/null || true)
    local has_camera=$(pgrep -f "camera_forwarder.py" 2>/dev/null || true)
    local has_rqt=$(pgrep -f "rqt.*image_view" 2>/dev/null || true)
    local has_port=$(lsof -ti:5555 2>/dev/null || true)
    
    [[ -n "$has_tmux" || -n "$has_control" || -n "$has_teleop" || -n "$has_camera" || -n "$has_rqt" || -n "$has_port" ]]
}

# Main execution
main() {
    # Check if any processes exist first
    if ! has_processes; then
        # No processes to kill, exit silently
        exit 0
    fi
    
    # Show header and processes to be killed
    if [[ "$QUIET" != true ]]; then
        echo -e "${BLUE}=== decoupled_wbc Process Killer ===${NC}"
        [[ "$DRY_RUN" == true ]] && echo -e "${BLUE}=== DRY RUN MODE ===${NC}"
        
        # Show what will be killed
        show_tmux "g1_deployment"
        show_processes_by_pattern "run_g1_control_loop.py" "G1 control loop"
        show_processes_by_pattern "run_teleop_policy_loop.py" "Teleop policy"
        show_processes_by_pattern "camera_forwarder.py" "Camera forwarder"
        show_processes_by_pattern "rqt.*image_view" "RQT viewer"
        show_processes_by_port "5555" "Inference server"
        
        # Ask for confirmation
        if [[ "$FORCE" != true && "$DRY_RUN" != true ]]; then
            echo
            echo -e "${RED}WARNING: This will terminate the above decoupled_wbc processes!${NC}"
            read -p "Continue? [Y/n]: " -n 1 -r
            echo
            # Default to Y - only abort if user explicitly types 'n' or 'N'
            [[ $REPLY =~ ^[Nn]$ ]] && { echo "Aborted."; exit 0; }
        fi
        echo
    fi
    
    # Kill processes (silently)
    kill_tmux "g1_deployment"
    kill_by_pattern "run_g1_control_loop.py" "G1 control loop"
    kill_by_pattern "run_teleop_policy_loop.py" "Teleop policy"
    kill_by_pattern "camera_forwarder.py" "Camera forwarder"
    kill_by_pattern "rqt.*image_view" "RQT viewer"
    kill_by_port "5555" "Inference server"
    
    # Force kill remaining (SIGKILL)
    [[ "$DRY_RUN" != true ]] && {
        sleep 1
        kill_by_pattern "run_g1_control_loop.py" "G1 control loop" "KILL"
        kill_by_pattern "run_teleop_policy_loop.py" "Teleop policy" "KILL"
        kill_by_pattern "camera_forwarder.py" "Camera forwarder" "KILL"
    }
    
    # Summary (unless quiet)
    [[ "$QUIET" != true ]] && {
        if [[ "$DRY_RUN" == true ]]; then
            echo -e "${BLUE}=== DRY RUN COMPLETE ===${NC}"
        else
            echo -e "${GREEN}All decoupled_wbc processes terminated${NC}"
        fi
    }
}

main "$@"