diff --git a/examples/Python/src/WebServer/logging.html b/examples/Python/src/WebServer/logging.html index a7d671e0..2617992e 100644 --- a/examples/Python/src/WebServer/logging.html +++ b/examples/Python/src/WebServer/logging.html @@ -36,22 +36,18 @@

Stored Logs:

const port = document.getElementById("portInput").value || 5000; const fullLogMessage = `Log from ${port}: ${logMessage}`; const logData = { + operation: "newlog", log: fullLogMessage, }; - fetch(`http://127.0.0.1:${port}/log`, { + fetch(`http://127.0.0.1:${port}/`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(logData), - }) - .then((response) => response.json()) - .then((data) => { - console.log("Response from server:", data); - incrementLogValue(); - }) - .catch((error) => console.error("Error:", error)); + }).catch((error) => console.error("Error:", error)); + incrementLogValue(); } function incrementLogValue() { @@ -63,11 +59,12 @@

Stored Logs:

const port = document.getElementById("portInput").value || 5000; const startTime = performance.now(); - fetch(`http://127.0.0.1:${port}/getlogs`, { + fetch(`http://127.0.0.1:${port}/`, { method: "POST", headers: { "Content-Type": "application/json", }, + body: JSON.stringify({ operation: "getlog" }), }) .then((response) => response.json()) .then((data) => { @@ -99,11 +96,12 @@

Stored Logs:

const port = document.getElementById("portInput").value || 5000; const startTime = performance.now(); - fetch(`http://127.0.0.1:${port}/getlogs_consistent`, { + fetch(`http://127.0.0.1:${port}/`, { method: "POST", headers: { "Content-Type": "application/json", }, + body: JSON.stringify({ operation: "getlog_consistent" }), }) .then((response) => response.json()) .then((data) => { diff --git a/examples/Python/src/WebServer/logging.lf b/examples/Python/src/WebServer/logging.lf index 0388818c..81c64054 100644 --- a/examples/Python/src/WebServer/logging.lf +++ b/examples/Python/src/WebServer/logging.lf @@ -2,99 +2,45 @@ target Python { coordination: decentralized } -preamble {= - from fastapi import FastAPI, Request, HTTPException - from fastapi.middleware.cors import CORSMiddleware - import threading - import uvicorn - import asyncio - import uuid -=} +import WebServer from "../lib/WebServer.lf" -reactor WebServer(bank_index=0, STA=0) { - state app - state events - input sendlogs - input sendlogs_consistent +reactor Router { + input request output newlog output getlog output getlog_consistent - physical action newlog_action - physical action getlog_action - logical action getlog_consistent_action - reaction(startup) -> newlog_action, getlog_action, getlog_consistent_action {= - self.events = {} - self.app = FastAPI() - self.app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], - ) - @self.app.post("/log") - async def receive_log(request: Request): - data = await request.json() - if "log" in data: - log_message = data["log"] - newlog_action.schedule(0, log_message) - return {"status": "success", "message": "Log stored successfully"} - else: - return {"status": "error", "message": "No log provided"}, 400 - @self.app.post("/getlogs") - async def get_logs(request: Request): - event = asyncio.Event() - request_id = str(uuid.uuid4()) - self.events[request_id] = event - getlog_action.schedule(0, request_id) - await event.wait() - logs = self.events[request_id] - del self.events[request_id] - return {"status": "success", "logs": logs} - - @self.app.post("/getlogs_consistent") - async def getlogs_consistent(request: Request): - event = asyncio.Event() - request_id = str(uuid.uuid4()) - self.events[request_id] = event - getlog_consistent_action.schedule(0, request_id) - await event.wait() - logs = self.events[request_id] - del self.events[request_id] - return {"status": "success", "logs": logs} - - def run_fastapi_app(): - print(f"[WebServer{self.bank_index}] FastAPI server starting") - uvicorn.run(self.app, host="127.0.0.1", port=5000+self.bank_index, log_level="warning") - fastapi_thread = threading.Thread(target=run_fastapi_app) - fastapi_thread.start() - =} - - reaction(newlog_action) -> newlog {= - newlog.set(newlog_action.value) - =} - - reaction(getlog_action) -> getlog {= - getlog.set(getlog_action.value) - =} - - reaction(getlog_consistent_action) -> getlog_consistent {= - getlog_consistent.set(getlog_consistent_action.value) - =} - - reaction(sendlogs) {= - [logs, event_id] = sendlogs.value - event = self.events[event_id] - self.events[event_id] = logs - event.set() + reaction(request) -> newlog, getlog, getlog_consistent {= + # print(f"Router received request: {request.value}") + request_id, req_data = request.value + if req_data["operation"] == "newlog" and "log" in req_data.keys(): + newlog.set([request_id, req_data["log"]]) + elif req_data["operation"] == "getlog": + getlog.set(request_id) + elif req_data["operation"] == "getlog_consistent": + getlog_consistent.set(request_id) + else: + print("Invalid Request") + return =} +} - reaction(sendlogs_consistent) {= - [logs, event_id] = sendlogs_consistent.value - event = self.events[event_id] - self.events[event_id] = logs - event.set() +reactor WebServerRouter(bank_index=0, STA=0) { + output newlog + output getlog + output getlog_consistent + webserver = new WebServer(port = {= 5000+self.bank_index =}, endpoint="/") + router = new Router() + webserver.request -> router.request + router.newlog -> newlog + router.getlog -> getlog + router.getlog_consistent -> getlog_consistent + input[2] response + + reaction(response) -> webserver.response {= + for port in response: + if port.is_present: + webserver.response.set(port.value) =} } @@ -108,27 +54,26 @@ reactor Database(bank_index=0, portwidth=2, STA = 0 s) { self.logs = [] =} - reaction(addlog) {= + reaction(addlog) -> sendlogs {= for i, port in enumerate(addlog): if port.is_present: - log_message = port.value + request_id, log_message = port.value self.logs.append(log_message) =} reaction(getlog) -> sendlogs {= - sendlogs.set([self.logs, getlog.value]) + sendlogs.set([getlog.value, {"status": "success", "logs": self.logs}]) =} } federated reactor(ReplicaCount=2) { - server = new[ReplicaCount] WebServer() + server = new[ReplicaCount] WebServerRouter() db = new[ReplicaCount] Database(portwidth=ReplicaCount) (server.newlog)+ ~> db.addlog server.getlog ~> db.getlog - db.sendlogs ~> server.sendlogs dbc = new[ReplicaCount] Database(portwidth=ReplicaCount, STA = 3 s) (server.newlog)+ -> dbc.addlog server.getlog_consistent -> dbc.getlog - dbc.sendlogs ~> server.sendlogs_consistent + db.sendlogs, dbc.sendlogs ~> interleaved(server.response) } diff --git a/examples/Python/src/lib/WebServer.lf b/examples/Python/src/lib/WebServer.lf index 1f9cdc74..7332d229 100644 --- a/examples/Python/src/lib/WebServer.lf +++ b/examples/Python/src/lib/WebServer.lf @@ -51,6 +51,9 @@ reactor WebServer(port=5000, endpoint="/") { reaction(response) {= request_id, resp_data = response.value + if request_id not in self.events: + print("Invalid Request ID") + return event = self.events[request_id] self.events[request_id] = resp_data event.set()