|
from fastapi import FastAPI
|
|
from fastapi.responses import HTMLResponse
|
|
import os
|
|
import threading
|
|
from datetime import datetime
|
|
from ads import AsyncDataSet
|
|
import uvicorn
|
|
|
|
app = FastAPI()
|
|
|
|
# Initialize AsyncDataSet
|
|
db = AsyncDataSet(":memory:", socket_path="test_workers.sock")
|
|
|
|
|
|
@app.get("/write")
|
|
async def write_data():
|
|
"""Write process and thread ID to database."""
|
|
process_id = os.getpid()
|
|
thread_id = threading.get_ident()
|
|
timestamp = datetime.now().isoformat()
|
|
|
|
# Insert data with process and thread info
|
|
await db.insert(
|
|
"requests",
|
|
{
|
|
"process_id": process_id,
|
|
"thread_id": thread_id,
|
|
"timestamp": timestamp,
|
|
"endpoint": "/write",
|
|
},
|
|
)
|
|
|
|
return {
|
|
"status": "success",
|
|
"process_id": process_id,
|
|
"thread_id": thread_id,
|
|
"timestamp": timestamp,
|
|
}
|
|
|
|
|
|
@app.get("/data", response_class=HTMLResponse)
|
|
async def get_all_data():
|
|
"""Return all request data as HTML table."""
|
|
# Get all records ordered by timestamp
|
|
records = await db.find("requests", order_by="timestamp DESC")
|
|
|
|
# Build HTML table
|
|
html = """
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Worker Test Results</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
table { border-collapse: collapse; width: 100%; }
|
|
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
th { background-color: #4CAF50; color: white; }
|
|
tr:nth-child(even) { background-color: #f2f2f2; }
|
|
h1 { color: #333; }
|
|
.stats { margin: 20px 0; padding: 10px; background-color: #e7f3ff; border-radius: 5px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>AsyncDataSet Multi-Worker Test Results</h1>
|
|
"""
|
|
|
|
# Calculate statistics
|
|
if records:
|
|
unique_processes = len(set(r["process_id"] for r in records))
|
|
unique_threads = len(set((r["process_id"], r["thread_id"]) for r in records))
|
|
total_requests = len(records)
|
|
|
|
html += f"""
|
|
<div class="stats">
|
|
<strong>Statistics:</strong><br>
|
|
Total Requests: {total_requests}<br>
|
|
Unique Processes: {unique_processes}<br>
|
|
Unique Process-Thread Combinations: {unique_threads}<br>
|
|
</div>
|
|
"""
|
|
|
|
html += """
|
|
<table>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Process ID</th>
|
|
<th>Thread ID</th>
|
|
<th>Timestamp</th>
|
|
<th>Endpoint</th>
|
|
</tr>
|
|
"""
|
|
|
|
for record in records:
|
|
html += f"""
|
|
<tr>
|
|
<td>{record.get('uid', 'N/A')[:8]}...</td>
|
|
<td>{record.get('process_id', 'N/A')}</td>
|
|
<td>{record.get('thread_id', 'N/A')}</td>
|
|
<td>{record.get('timestamp', 'N/A')}</td>
|
|
<td>{record.get('endpoint', 'N/A')}</td>
|
|
</tr>
|
|
"""
|
|
|
|
html += """
|
|
</table>
|
|
<p style="margin-top: 20px;">
|
|
<a href="/write" target="_blank">Make a write request</a> |
|
|
<a href="/data">Refresh</a>
|
|
</p>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
return html
|
|
|
|
|
|
@app.get("/")
|
|
async def root():
|
|
"""Root endpoint showing process and thread info."""
|
|
process_id = os.getpid()
|
|
thread_id = threading.get_ident()
|
|
|
|
# Log this request too
|
|
await db.insert(
|
|
"requests",
|
|
{
|
|
"process_id": process_id,
|
|
"thread_id": thread_id,
|
|
"timestamp": datetime.now().isoformat(),
|
|
"endpoint": "/",
|
|
},
|
|
)
|
|
|
|
return {
|
|
"message": "FastAPI Multi-Worker Test Server",
|
|
"current_process_id": process_id,
|
|
"current_thread_id": thread_id,
|
|
"endpoints": {
|
|
"/": "This endpoint",
|
|
"/write": "Write process/thread data (POST)",
|
|
"/data": "View all data as HTML table (GET)",
|
|
},
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Run with multiple workers
|
|
# You can also run this from command line:
|
|
# uvicorn test_server:app --workers 4 --host 0.0.0.0 --port 8000
|
|
uvicorn.run(
|
|
"ads_test_server:app",
|
|
host="0.0.0.0",
|
|
port=8000,
|
|
workers=50, # Run with 4 worker processes
|
|
reload=False,
|
|
)
|