ready to write UI
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@ -6,3 +6,10 @@
|
|||||||
/mbuild
|
/mbuild
|
||||||
/.clang-format
|
/.clang-format
|
||||||
/test/data
|
/test/data
|
||||||
|
|
||||||
|
# Ignore all .env files
|
||||||
|
**/.env
|
||||||
|
**/.env.*
|
||||||
|
|
||||||
|
# Ignore all __pycache__ directories
|
||||||
|
**/__pycache__/
|
66
UI/gunicorn.conf.py
Normal file
66
UI/gunicorn.conf.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import signal
|
||||||
|
import atexit
|
||||||
|
from flask import Flask, render_template
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import socket
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Get configuration from environment variables
|
||||||
|
backend_ip = os.getenv('BACKEND_IP')
|
||||||
|
backend_port = os.getenv('BACKEND_PORT')
|
||||||
|
backend_log_level = os.getenv('BACKEND_LOG_LEVEL')
|
||||||
|
backend_data_directory = os.getenv('BACKEND_DATA_DIRECTORY')
|
||||||
|
backend_log_file = os.getenv('BACKEND_LOG_FILE')
|
||||||
|
backend_path = os.getenv('BACKEND_PATH')
|
||||||
|
|
||||||
|
# Command to start the backend process
|
||||||
|
backend_command = [
|
||||||
|
backend_path,
|
||||||
|
"-d", backend_data_directory,
|
||||||
|
"-l", backend_log_file,
|
||||||
|
"--level", backend_log_level,
|
||||||
|
"server",
|
||||||
|
"--port", backend_port,
|
||||||
|
"--address", backend_ip
|
||||||
|
]
|
||||||
|
|
||||||
|
backend_process = None
|
||||||
|
|
||||||
|
def start_backend():
|
||||||
|
global backend_process
|
||||||
|
# Try to acquire the lock without blocking, timeout if another process holds the lock
|
||||||
|
print("Starting backend process...")
|
||||||
|
backend_process = subprocess.Popen(backend_command, preexec_fn = os.setsid)
|
||||||
|
print(f"Backend process started with PID: {backend_process.pid}")
|
||||||
|
def on_starting(server):
|
||||||
|
# 这里放置启动后台进程的逻辑
|
||||||
|
start_backend()
|
||||||
|
|
||||||
|
def when_ready(server):
|
||||||
|
print("Server is ready. Spawning workers")
|
||||||
|
def send_exit_command(ip, port):
|
||||||
|
try:
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||||
|
sock.connect((ip, int(port)))
|
||||||
|
sock.sendall(b'exit\n')
|
||||||
|
response = sock.recv(1024) # Optional: read response from server
|
||||||
|
print(f"Received response: {response.decode('utf-8')}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to send exit command: {e}")
|
||||||
|
|
||||||
|
def stop_backend():
|
||||||
|
global backend_process
|
||||||
|
if backend_process is not None:
|
||||||
|
print(f"Sending exit command to backend process at {backend_ip}:{backend_port}...")
|
||||||
|
send_exit_command(backend_ip, backend_port)
|
||||||
|
print(f"Waiting for backend process with PID: {backend_process.pid} to terminate...")
|
||||||
|
backend_process.wait()
|
||||||
|
print("Backend process stopped.")
|
||||||
|
backend_process = None
|
||||||
|
|
||||||
|
def on_exit(server):
|
||||||
|
stop_backend()
|
63
UI/main.py
63
UI/main.py
@ -0,0 +1,63 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import signal
|
||||||
|
import atexit
|
||||||
|
from flask import Flask, render_template
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Get configuration from environment variables
|
||||||
|
backend_ip = os.getenv('BACKEND_IP')
|
||||||
|
backend_port = os.getenv('BACKEND_PORT')
|
||||||
|
backend_log_level = os.getenv('BACKEND_LOG_LEVEL')
|
||||||
|
backend_data_directory = os.getenv('BACKEND_DATA_DIRECTORY')
|
||||||
|
backend_log_file = os.getenv('BACKEND_LOG_FILE')
|
||||||
|
backend_path = os.getenv('BACKEND_PATH')
|
||||||
|
|
||||||
|
# Command to start the backend process
|
||||||
|
backend_command = [
|
||||||
|
backend_path,
|
||||||
|
"-d", backend_data_directory,
|
||||||
|
"-l", backend_log_file,
|
||||||
|
"--level", backend_log_level,
|
||||||
|
"server",
|
||||||
|
"--port", backend_port,
|
||||||
|
"--address", backend_ip
|
||||||
|
]
|
||||||
|
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.connect((backend_ip, int(backend_port)))
|
||||||
|
def ExecCommand(command):
|
||||||
|
command=command+'\n'
|
||||||
|
sock.sendall(command.encode('utf-8'))
|
||||||
|
response = sock.recv(1024*1024)
|
||||||
|
response= response.decode('utf-8')
|
||||||
|
_, _, response = response.partition(" ")
|
||||||
|
return response
|
||||||
|
|
||||||
|
# Signal handler for graceful shutdown
|
||||||
|
def signal_handler(signum, frame):
|
||||||
|
# stop_backend()
|
||||||
|
time.sleep(10)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
# Register signal handlers
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def home():
|
||||||
|
return render_template('index.html')
|
||||||
|
|
||||||
|
@app.route('/about')
|
||||||
|
def about():
|
||||||
|
return render_template('about.html')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
||||||
|
8
UI/templates/about.html
Normal file
8
UI/templates/about.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block title %}About Us - Train Ticket Booking{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>About Us</h1>
|
||||||
|
<p>This is a demo site for booking train tickets.</p>
|
||||||
|
{% endblock %}
|
27
UI/templates/base.html
Normal file
27
UI/templates/base.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}Train Ticket Booking{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
|
<a class="navbar-brand" href="#">Train Tickets</a>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item {% if request.endpoint == 'home' %}active{% endif %}">
|
||||||
|
<a class="nav-link" href="/">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item {% if request.endpoint == 'about' %}active{% endif %}">
|
||||||
|
<a class="nav-link" href="/about">About</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container mt-5">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
8
UI/templates/index.html
Normal file
8
UI/templates/index.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block title %}Home - Train Ticket Booking{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Welcome to the Train Ticket Booking System</h1>
|
||||||
|
<p>Use this site to book your train tickets easily.</p>
|
||||||
|
{% endblock %}
|
61
src/main.cpp
61
src/main.cpp
@ -3,6 +3,7 @@
|
|||||||
#include "basic_defs.h"
|
#include "basic_defs.h"
|
||||||
#ifdef ENABLE_ADVANCED_FEATURE
|
#ifdef ENABLE_ADVANCED_FEATURE
|
||||||
#include <sockpp/tcp_acceptor.h>
|
#include <sockpp/tcp_acceptor.h>
|
||||||
|
#include <thread>
|
||||||
#include "dataguard/dataguard.h"
|
#include "dataguard/dataguard.h"
|
||||||
#endif
|
#endif
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
@ -20,6 +21,51 @@ const bool optimize_enabled = false;
|
|||||||
// #else
|
// #else
|
||||||
// const bool global_log_enabled = true;
|
// const bool global_log_enabled = true;
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_ADVANCED_FEATURE
|
||||||
|
|
||||||
|
// 处理每个连接的函数
|
||||||
|
void handle_client(sockpp::tcp_socket client, TicketSystemEngine &engine) {
|
||||||
|
try {
|
||||||
|
std::string line;
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
// 读取客户端发送的数据
|
||||||
|
while (true) {
|
||||||
|
char data[1024];
|
||||||
|
ssize_t n = client.read(data, sizeof(data));
|
||||||
|
if (n <= 0) {
|
||||||
|
break; // 连接关闭或出现错误
|
||||||
|
}
|
||||||
|
buffer.append(data, n);
|
||||||
|
|
||||||
|
// 检查是否收到完整的一行
|
||||||
|
size_t pos;
|
||||||
|
while ((pos = buffer.find('\n')) != std::string::npos) {
|
||||||
|
line = buffer.substr(0, pos);
|
||||||
|
buffer.erase(0, pos + 1);
|
||||||
|
line = "[0] " + line;
|
||||||
|
|
||||||
|
// 调用 TicketSystemEngine 的 Execute 方法处理命令
|
||||||
|
std::string response = engine.Execute(line);
|
||||||
|
|
||||||
|
// 发送响应给客户端
|
||||||
|
client.write(response);
|
||||||
|
|
||||||
|
// 检查是否需要退出
|
||||||
|
if (*engine.its_time_to_exit_ptr) {
|
||||||
|
exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LOG->error("Exception handling client: {}", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ENABLE_ADVANCED_FEATURE
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
argparse::ArgumentParser program("zts-core", main_version + "-" + build_version);
|
argparse::ArgumentParser program("zts-core", main_version + "-" + build_version);
|
||||||
argparse::ArgumentParser fsck_command("fsck");
|
argparse::ArgumentParser fsck_command("fsck");
|
||||||
@ -102,7 +148,20 @@ int main(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
LOG->info("successfully bind to address {} port {}", address, port);
|
LOG->info("successfully bind to address {} port {}", address, port);
|
||||||
throw std::runtime_error("Server mode not implemented");
|
// throw std::runtime_error("Server mode not implemented");
|
||||||
|
TicketSystemEngine engine(data_directory);
|
||||||
|
while (true) {
|
||||||
|
// 接受新的客户端连接
|
||||||
|
sockpp::tcp_socket client = acceptor.accept();
|
||||||
|
if (!client) {
|
||||||
|
LOG->error("Error accepting incoming connection: {}", acceptor.last_error_str());
|
||||||
|
} else {
|
||||||
|
LOG->info("New client connected from {}", client.peer_address().to_string());
|
||||||
|
|
||||||
|
// 创建一个线程来处理客户端连接
|
||||||
|
std::thread(handle_client, std::move(client), std::ref(engine)).detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
std::ios::sync_with_stdio(false);
|
std::ios::sync_with_stdio(false);
|
||||||
|
Reference in New Issue
Block a user