-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.py
More file actions
148 lines (123 loc) · 4.93 KB
/
Copy pathmain.py
File metadata and controls
148 lines (123 loc) · 4.93 KB
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
#!/usr/bin/env python3
"""
RISNet v2.0 - Advanced RIS Network Simulator
Modular entry point with clean separation of concerns
Usage:
python main.py --web # Run web interface
python main.py --cli # Run CLI interface (default)
python main.py --topology FILE # Load topology on startup
"""
import sys
import argparse
def run_web(net, controller, host='127.0.0.1', port=5000):
"""Run WSGI web interface"""
from waitress import serve as waitress_serve
from app import create_app
from app.thread_safe_network import ThreadSafeNetwork, ThreadSafeController
from app.state_manager import WebStateManager
import signal
# Wrap with thread-safe versions for concurrent web access
net_safe = ThreadSafeNetwork(net)
controller_safe = ThreadSafeController(controller)
# Initialize state manager for persistence
state_mgr = WebStateManager()
state_mgr.load_network(net_safe)
app = create_app(net_safe, controller_safe, state_mgr)
print(f'Using Waitress WSGI server (production-ready)')
print(f'Server running on http://{host}:{port}')
print('Press Ctrl+C to quit')
# Handle graceful shutdown
def shutdown_handler(signum, frame):
print('\nShutting down gracefully...')
# Save network state before exit
if state_mgr:
state_mgr.save_network(net_safe)
print('✓ Network state saved')
print('Exiting RISNet web server')
sys.exit(0)
# Register signal handlers for graceful shutdown
signal.signal(signal.SIGINT, shutdown_handler)
signal.signal(signal.SIGTERM, shutdown_handler)
waitress_serve(app, host=host, port=port, threads=4)
def cleanup_cli(net, cli):
"""Clean up CLI resources"""
print('\nClearing topology...')
if net.nodes:
net.nodes.clear()
cli._save_network()
print('✓ Topology cleared')
print('Exiting RISNet CLI')
def main():
"""Main entry point"""
parser = argparse.ArgumentParser(
description='RISNet v2.0 Advanced RIS Network Simulator',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python main.py --web # Run web interface
python main.py --cli # Run CLI interface (default)
python main.py --cli --topology topology.json # Load topology on startup
python main.py testall --exec-only # Run testall and exit
"""
)
parser.add_argument('--web', action='store_true',
help='Run web interface')
parser.add_argument('--cli', action='store_true',
help='Run CLI interface (default)')
parser.add_argument('--topology', type=str,
help='Load topology from JSON file')
parser.add_argument('--host', type=str, default='127.0.0.1',
help='Web server host (default: 127.0.0.1)')
parser.add_argument('--port', type=int, default=5000,
help='Web server port (default: 5000)')
parser.add_argument('--exec-only', action='store_true',
help='Execute command(s) and exit without starting interactive CLI')
parser.add_argument('command', nargs='*',
help='CLI command to execute')
args = parser.parse_args()
# Lazy load core components only when needed
from core import RISNetwork
from controller.ris_controller import RISController
# Initialize core components
net = RISNetwork()
controller = RISController(net, net.environment)
net.set_controller(controller)
# Run web interface
if args.web:
print("\n" + "="*70)
print("RISNet v2.0 - Web Interface")
print("="*70 + "\n")
run_web(net, controller, host=args.host, port=args.port)
return
# Run CLI interface
print("\n" + "="*70)
print("RISNet v2.0 - CLI Interface")
print("="*70 + "\n")
from cli.main_shell import RISNetCLI
cli = RISNetCLI(net)
# Load topology if provided
if args.topology:
cli._load_network_from_file(args.topology)
print(f"✓ Topology loaded: {args.topology}\n")
try:
# Execute command if provided
if args.command:
command_str = ' '.join(args.command)
try:
exit_requested = bool(cli.onecmd(command_str))
except Exception as e:
print(f"Error: {e}")
exit_requested = True
# Continue to interactive CLI unless --exec-only or exit was requested
if not args.exec_only and not exit_requested:
print("\n" + "-" * 70)
print("Continuing in interactive CLI (type 'help' for commands, 'quit' to exit)")
print("-" * 70 + "\n")
cli.cmdloop()
else:
# Default to interactive CLI
cli.cmdloop()
except KeyboardInterrupt:
cleanup_cli(net, cli)
if __name__ == '__main__':
main()