Skip to content

Commit

Permalink
rewrite logging with reusable WebServer
Browse files Browse the repository at this point in the history
  • Loading branch information
Depetrol committed Oct 10, 2024
1 parent 42763e7 commit 5588c73
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 102 deletions.
18 changes: 8 additions & 10 deletions examples/Python/src/WebServer/logging.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,18 @@ <h2>Stored Logs:</h2>
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() {
Expand All @@ -63,11 +59,12 @@ <h2>Stored Logs:</h2>
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) => {
Expand Down Expand Up @@ -99,11 +96,12 @@ <h2>Stored Logs:</h2>
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) => {
Expand Down
129 changes: 37 additions & 92 deletions examples/Python/src/WebServer/logging.lf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
=}
}

Expand All @@ -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)
}
3 changes: 3 additions & 0 deletions examples/Python/src/lib/WebServer.lf
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 5588c73

Please sign in to comment.