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,
)