corol-server / coral_wrapper.py
NitinBot002's picture
Rename corol_wrapper.py to coral_wrapper.py
f7aebfd verified
#!/usr/bin/env python3
"""
Coral Server Python Wrapper
Starts and manages the coral-server on port 5555
"""
import os
import sys
import subprocess
import signal
import time
import logging
from threading import Thread
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('coral-wrapper')
class CoralServerWrapper:
def __init__(self, port=5555, jar_path='coral-server.jar'):
self.port = int(os.environ.get('CORAL_PORT', port))
self.jar_path = jar_path
self.process = None
self.running = False
def check_java_version(self):
"""Verify Java version is > 17"""
try:
result = subprocess.run(
['java', '-version'],
capture_output=True,
text=True
)
version_info = result.stderr or result.stdout
logger.info(f"Java version: {version_info.split()[2].strip('\"')}")
# Extract major version
version_str = version_info.split()[2].strip('"')
major_version = int(version_str.split('.')[0])
if major_version < 17:
logger.error(f"Java version {major_version} is < 17. Please upgrade.")
return False
return True
except Exception as e:
logger.error(f"Error checking Java version: {e}")
return False
def start_server(self):
"""Start the coral-server"""
if not self.check_java_version():
sys.exit(1)
try:
# Java command to run coral-server
java_cmd = [
'java',
'-Xmx512m',
'-Xms256m',
'-XX:+UseContainerSupport',
'-XX:MaxRAMPercentage=75.0',
'-jar',
self.jar_path,
'--sse-server-ktor',
str(self.port)
]
logger.info(f"Starting coral-server on port {self.port}...")
logger.info(f"Command: {' '.join(java_cmd)}")
# Start the process
self.process = subprocess.Popen(
java_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
bufsize=1
)
self.running = True
# Start thread to monitor output
output_thread = Thread(target=self.monitor_output)
output_thread.daemon = True
output_thread.start()
# Wait a moment to ensure server starts
time.sleep(3)
if self.process.poll() is None:
logger.info(f"βœ“ Coral-server started successfully on port {self.port}")
logger.info(f" Server URL: http://localhost:{self.port}")
else:
logger.error("Server failed to start")
self.running = False
sys.exit(1)
except FileNotFoundError:
logger.error(f"JAR file not found: {self.jar_path}")
sys.exit(1)
except Exception as e:
logger.error(f"Error starting server: {e}")
sys.exit(1)
def monitor_output(self):
"""Monitor and log server output"""
try:
for line in iter(self.process.stdout.readline, ''):
if line:
logger.info(f"[coral-server] {line.strip()}")
if not self.running:
break
except Exception as e:
logger.error(f"Error monitoring output: {e}")
def stop_server(self):
"""Stop the coral-server gracefully"""
if self.process and self.running:
logger.info("Stopping coral-server...")
self.running = False
# Send SIGTERM for graceful shutdown
self.process.terminate()
# Wait for process to end (max 10 seconds)
try:
self.process.wait(timeout=10)
logger.info("βœ“ Coral-server stopped gracefully")
except subprocess.TimeoutExpired:
logger.warning("Force killing coral-server...")
self.process.kill()
self.process.wait()
logger.info("βœ“ Coral-server force stopped")
def restart_server(self):
"""Restart the coral-server"""
logger.info("Restarting coral-server...")
self.stop_server()
time.sleep(2)
self.start_server()
def health_check(self):
"""Check if server is healthy"""
if self.process and self.process.poll() is None:
return True
return False
def run(self):
"""Main run method - starts server and handles signals"""
# Setup signal handlers
signal.signal(signal.SIGTERM, self.signal_handler)
signal.signal(signal.SIGINT, self.signal_handler)
# Start the server
self.start_server()
# Keep running and monitor health
try:
while self.running:
time.sleep(5)
if not self.health_check():
logger.error("Server health check failed!")
logger.info("Attempting restart...")
self.restart_server()
except KeyboardInterrupt:
logger.info("Received interrupt signal")
finally:
self.stop_server()
def signal_handler(self, signum, frame):
"""Handle shutdown signals"""
logger.info(f"Received signal {signum}")
self.running = False
def main():
"""Main entry point"""
logger.info("="*50)
logger.info("Coral Server Python Wrapper")
logger.info("="*50)
# Get configuration from environment
port = os.environ.get('CORAL_PORT', 5555)
jar_path = os.environ.get('CORAL_JAR_PATH', 'coral-server.jar')
# Create and run wrapper
wrapper = CoralServerWrapper(port=port, jar_path=jar_path)
wrapper.run()
if __name__ == "__main__":
main()