Skip to content

Commit b7efbf7

Browse files
committed
merge start.sh and start.py
1 parent 5dfd873 commit b7efbf7

File tree

3 files changed

+107
-151
lines changed

3 files changed

+107
-151
lines changed

scripts/create_binary.sh

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,6 @@ rm -rf binary/start.build
3232
rm -rf binary/start.dist
3333
rm -rf binary/start.onefile-build
3434

35-
# copy start.sh to binary directory
36-
37-
cp ../start.sh binary/start.sh
38-
39-
# change start.sh to run binary instead of python and to use separate rpc server
40-
41-
sed -i 's/run_bin=false/run_bin=true/g' binary/start.sh
42-
sed -i 's/separate_rpc_server=false/separate_rpc_server=true/g' binary/start.sh
43-
4435
# copy start to binary directory
4536

4637
cp start binary/start

start.py

Lines changed: 97 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,40 @@
44
import threading
55
import logging
66
import argparse
7-
import check_requirements
87
from utils.logger_utils import setup_logger
98
import datetime
109
import multiprocessing
1110
from server import main
1211
import random
12+
import select
13+
1314

1415
# Set up logging
1516
log_dir = None
1617
start_team_logger = None
1718

1819
def run_server_script(args):
20+
rpc_port = args.rpc_port
21+
if args.use_random_port or args.use_different_port:
22+
import socket
23+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
24+
s.bind(('localhost', 0))
25+
rpc_port = str(s.getsockname()[1])
26+
start_team_logger.debug(f"Using random port: {rpc_port}")
1927
# Define a wrapper function to pass the arguments to the main function
2028
def server_main():
2129
import sys
22-
sys.argv = ['server.py', '--rpc-port', str(args.rpc_port), '--log-dir', log_dir]
30+
sys.argv = ['server.py', '--rpc-port', str(rpc_port), '--log-dir', log_dir]
2331
if args.disable_log_file:
2432
sys.argv += ['--disable-log-file']
2533
main()
2634

2735
# Start the main function as a new process
2836
process = multiprocessing.Process(target=server_main)
2937
process.start()
30-
return process
38+
return process, rpc_port
3139

32-
def run_start_script(args):
40+
def run_start_script(args, rpc_port):
3341
# Start the start.sh script in its own directory as a new process group
3442
arguments = ['bash']
3543
if args.player or args.coach or args.goalie:
@@ -38,7 +46,7 @@ def run_start_script(args):
3846
arguments += ['start.sh' if not args.debug else 'start-debug.sh']
3947

4048
arguments += ['-t', args.team_name,
41-
'--rpc-port', args.rpc_port, '--rpc-type', 'grpc',
49+
'--rpc-port', rpc_port, '--rpc-type', 'grpc',
4250
'-p', args.server_port, '-h', args.server_host]
4351

4452
process = subprocess.Popen(
@@ -56,32 +64,39 @@ def stream_output_to_file(process, name, args):
5664
# Stream output from the process and log it to a file with the given name
5765
f = None if args.disable_log_file else open(f"{log_dir}/{name}.log", "a")
5866
while not stop_thread.is_set():
59-
output = process.stdout.readline()
60-
if output:
61-
if f:
62-
f.write(output.decode())
63-
f.flush()
67+
if select.select([process.stdout], [], [], 1)[0]:
68+
output = process.stdout.readline()
69+
if output:
70+
if f:
71+
f.write(output.decode())
72+
f.flush()
73+
else:
74+
print(output.decode())
6475
else:
65-
print(output.decode())
66-
else:
67-
break
76+
break
6877
process.stdout.close()
78+
if f:
79+
f.close()
6980

70-
def kill_process_group(process):
71-
try:
72-
start_team_logger.debug(f"Killing process group with PID: {process.pid}")
73-
os.killpg(os.getpgid(process.pid), signal.SIGTERM) # Send SIGTERM to the process group
74-
except ProcessLookupError:
75-
pass # The process might have already exited
81+
def kill_process_group(processes):
82+
for process in processes:
83+
try:
84+
start_team_logger.debug(f"Killing process group with PID: {process.pid}")
85+
os.killpg(os.getpgid(process.pid), signal.SIGTERM) # Send SIGTERM to the process group
86+
except ProcessLookupError:
87+
pass # The process might have already exited
7688

77-
def kill_rpc_server_process(process):
78-
try:
79-
start_team_logger.debug(f"Killing process with PID: {process.pid}")
80-
os.kill(process.pid, signal.SIGTERM) # Send SIGTERM to the specific process
81-
except ProcessLookupError:
82-
pass # The process might have already exited
89+
def kill_rpc_server_process(processes):
90+
for process in processes:
91+
try:
92+
start_team_logger.debug(f"Killing process with PID: {process.pid}")
93+
os.kill(process.pid, signal.SIGTERM) # Send SIGTERM to the specific process
94+
except ProcessLookupError:
95+
pass # The process might have already exited
96+
97+
def check_args(args):
98+
pass
8399

84-
85100
if __name__ == "__main__":
86101
# Set up argument parsing
87102
parser = argparse.ArgumentParser(description='Run server and team scripts.')
@@ -90,6 +105,7 @@ def kill_rpc_server_process(process):
90105
parser.add_argument('-d', '--debug', required=False, help='Enable debug mode', default=False, action='store_true')
91106
parser.add_argument('--use-random-port', required=False, help='Use a random port for the server', default=False, action='store_true')
92107
parser.add_argument('--use-random-name', required=False, help='Use a random team name', default=False, action='store_true')
108+
parser.add_argument('--use-different-port', required=False, help='Use a different port for the rpc server', default=False, action='store_true')
93109
parser.add_argument('--server-host', required=False, help='The host of the server', default='localhost')
94110
parser.add_argument('--server-port', required=False, help='The port of the server', default='6000')
95111
parser.add_argument('--close-server', required=False, help='Close the server', default=False, action='store_true')
@@ -110,47 +126,70 @@ def kill_rpc_server_process(process):
110126
start_team_logger.debug(f"Arguments: {args=}")
111127

112128
try:
113-
if args.use_random_port:
114-
import socket
115-
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
116-
s.bind(('localhost', 0))
117-
args.rpc_port = str(s.getsockname()[1])
118-
start_team_logger.debug(f"Using random port: {args.rpc_port}")
119-
120129
if args.use_random_name:
121130
import random
122131
import string
123132
args.team_name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=5))
124133

125134
# Run the server.py script first
126-
server_process = run_server_script(args)
127-
start_team_logger.debug(f"Started server.py process with PID: {server_process.pid}")
128-
129-
# Run the start.sh script after server.py with the given arguments
130-
start_process = run_start_script(args)
131-
start_team_logger.debug(f"Started start.sh process with PID: {start_process.pid} with team name {args=}")
135+
all_server_processes = []
136+
all_start_processes = []
137+
if args.use_different_port:
138+
for i in range(13):
139+
server_process, rpc_port = run_server_script(args)
140+
all_server_processes.append(server_process)
141+
start_team_logger.debug(f"Started server.py process with PID: {all_server_processes[-1].pid}")
142+
args.goalie, args.coach, args.player = False, False, False
143+
args.player = False
144+
if i == 0:
145+
args.goalie = True
146+
elif i == 12:
147+
args.coach = True
148+
else:
149+
args.player = True
150+
151+
# Run the start.sh script after server.py with the given arguments
152+
all_start_processes.append(run_start_script(args, rpc_port))
153+
start_team_logger.debug(f"Started start.sh process with PID: {all_start_processes[-1].pid} with team name {args=} and rpc port {rpc_port}")
154+
else:
155+
server_process, rpc_port = run_server_script(args)
156+
all_server_processes.append(server_process)
157+
start_team_logger.debug(f"Started server.py process with PID: {all_server_processes[-1].pid}")
158+
159+
# Run the start.sh script after server.py with the given arguments
160+
all_start_processes.append(run_start_script(args, rpc_port))
161+
start_team_logger.debug(f"Started start.sh process with PID: {all_start_processes[-1].pid} with team name {args=} and rpc port {rpc_port}")
132162

133163
# Monitor both processes and log their outputs
134164
start_team_logger.debug("Monitoring processes...")
135165

136-
start_thread = threading.Thread(target=stream_output_to_file, args=(start_process, 'proxy', args))
137-
start_thread.start()
166+
start_threads: list[threading.Thread] = []
167+
for i, start_process in enumerate(all_start_processes):
168+
start_threads.append(threading.Thread(target=stream_output_to_file, args=(start_process, 'proxy' if len(all_start_processes) == 1 else f'porxy_{i}', args)))
169+
start_threads[-1].start()
138170

139171
def signal_handler(sig, frame):
140172
start_team_logger.info('Received signal to terminate. Cleaning up...')
141-
kill_rpc_server_process(server_process)
142-
server_process.join()
143-
144-
start_team_logger.debug(f"server.py ended with PID: {server_process.pid}")
173+
kill_rpc_server_process(all_server_processes)
174+
for server_process in all_server_processes:
175+
server_process.join()
176+
start_team_logger.debug(f"server.py ended with PID: {server_process.pid}")
177+
178+
start_team_logger.debug("all_server_processes has finished.")
145179

146-
kill_process_group(start_process)
147-
start_process.wait()
180+
kill_process_group(all_start_processes)
181+
for start_process in all_start_processes:
182+
start_process.wait()
183+
start_team_logger.debug(f"start.sh ended with PID: {start_process.pid}")
148184

149-
start_team_logger.debug(f"start.sh ended with PID: {start_process.pid}")
185+
start_team_logger.debug("all_start_processes has finished.")
150186

151187
stop_thread.set()
152188

153-
start_thread.join()
189+
start_team_logger.debug("Waiting for start_thread to finish...")
190+
for start_thread in start_threads:
191+
start_thread.join()
192+
154193
start_team_logger.debug("start_thread has finished.")
155194

156195
start_team_logger.info('All processes have been killed.')
@@ -160,26 +199,28 @@ def signal_handler(sig, frame):
160199
signal.signal(signal.SIGINT, signal_handler)
161200

162201
# Wait for both threads to finish
163-
start_thread.join()
202+
for start_thread in start_threads:
203+
start_thread.join()
164204
start_team_logger.debug("agents has been exited.")
165205

166206
if args.close_server:
167207
start_team_logger.debug("Closing rpc server ...")
168-
kill_rpc_server_process(server_process)
208+
kill_rpc_server_process(all_server_processes)
169209
start_team_logger.debug("rpc Server has been closed.")
170210

171211
# wait for server process to finish
172-
server_process.join()
212+
for server_process in all_server_processes:
213+
server_process.join()
173214
start_team_logger.debug("server.py has finished.")
174215

175216
start_team_logger.info("Both processes have exited.")
176217
except KeyboardInterrupt:
177218
start_team_logger.debug("Interrupted! Killing all processes.")
178-
kill_rpc_server_process(server_process)
179-
kill_process_group(start_process)
219+
kill_rpc_server_process(all_server_processes)
220+
kill_process_group(all_start_processes)
180221

181222
finally:
182223
# Ensure all processes are killed on exit
183224
start_team_logger.debug("Final Cleaning up...")
184-
kill_rpc_server_process(server_process)
185-
kill_process_group(start_process)
225+
kill_rpc_server_process(all_server_processes)
226+
kill_process_group(all_start_processes)

start.sh

Lines changed: 10 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,27 @@
11
#!/bin/bash
22

33
python_env=.venv/bin/activate
4+
source $python_env
45

5-
server_host=127.0.0.1
6-
server_port=6000
7-
disable_log_file=false
8-
run_bin=false
9-
separate_rpc_server=false
6+
# Set the options, all the options are passed as environment variables
7+
options=$@
108

11-
while [ $# -gt 0 ]
12-
do
13-
case $1 in
14-
--server-host)
15-
server_host=$2
16-
shift
17-
;;
18-
--server-port)
19-
server_port=$2
20-
shift
21-
;;
22-
--disable_log_file)
23-
disable_log_file=true
24-
;;
25-
--run-bin)
26-
run_bin=true
27-
;;
28-
--separate-rpc-server)
29-
separate_rpc_server=true
30-
;;
31-
*)
32-
echo 1>&2
33-
echo "invalid option \"${1}\"." 1>&2
34-
echo 1>&2
35-
usage
36-
exit 1
37-
;;
38-
esac
39-
shift 1
40-
done
41-
42-
usage() {
43-
echo "Usage: $0 [--server-host <server_host>] [--server-port <server_port>] [--disable_log_file] [--run-bin]"
44-
}
9+
echo "Options: $options"
4510

4611
# Function to handle termination
4712
cleanup() {
4813
echo "Terminating all start_agent.py processes..."
49-
for pid in "${pids[@]}"; do
50-
kill $pid
51-
done
14+
kill $pid
5215
exit 0
5316
}
5417

5518
# Trap SIGTERM and SIGINT signals
5619
trap cleanup SIGTERM SIGINT
5720

58-
# Initialize an empty array to store PIDs
59-
pids=()
60-
61-
# Set options
62-
options="--server-host $server_host --server-port $server_port --use-random-port --close-server"
63-
if [ $disable_log_file = false ]; then
64-
# Init log directory
65-
log_dir="$(pwd)/logs/$(date +'%Y-%m-%d_%H-%M-%S')_$((RANDOM % 900000 + 100000))"
66-
mkdir -p $log_dir
67-
options="$options --log-dir $log_dir"
68-
else
69-
options="$options --disable-log-file"
70-
fi
71-
72-
# Run start.py or start.bin
73-
if [ $run_bin = true ]; then
74-
run_command="./start.bin"
75-
else
76-
# active .venv
77-
source $python_env
78-
run_command="python3 start.py"
79-
fi
80-
81-
if [ $separate_rpc_server = true ]; then
82-
# Run start_agent.py 11 times and store each PID in the array
83-
$run_command $options --goalie &
84-
pids+=($!)
85-
86-
sleep 2
87-
88-
for i in {2..11}; do
89-
$run_command $options --player &
90-
pids+=($!)
91-
done
21+
run_command="python3 start.py"
9222

93-
$run_command $options --coach &
94-
pids+=($!)
95-
else
96-
$run_command $options &
97-
pids+=($!)
98-
fi
23+
$run_command $options &
24+
pid=$!
9925

100-
# Wait for all background processes to finish
101-
for pid in "${pids[@]}"; do
102-
wait $pid
103-
done
26+
# Wait for the process to finish
27+
wait $pid

0 commit comments

Comments
 (0)