15. Graphical Workflows
This document contains all graphical workflow diagrams extracted from the specification documents.
15.1. Application Server Process Handler
15.1.1. ASProcessHandler Initialization
flowchart TD;
A[forkProcessASHandler] --> B[ASIndex = 0];
B --> C{More VirtualDomains?};
C -->|Yes| D{More Interpreters for Domain?};
D -->|Yes| E[Fork AS Process];
E --> F{Parent Process?};
F -->|Yes| G[Register Child PID];
G --> H[Increment ASIndex];
H --> D;
F -->|No| I[Child: Setup PID FD to Parent];
I --> J[Set Termination Handler];
J --> K[Setup SHM Pointers];
K --> L[Initialize Backend Processor];
L --> M[Enter Main Loop];
D -->|No| C;
C -->|No| N[All AS Processes Forked];
15.1.2. ASProcessHandler Main Loop
flowchart TD;
A[AS Main Loop] --> B{RunServer == True?};
B -->|Yes| C[Get SHM Meta Addresses];
C --> D{CanRead == 1 AND WriteReady == 0?};
D -->|Yes| E[Read Request from SHM];
E --> F[Process Request via Backend];
F --> G[Write Result to SHM];
G --> H[Set CanRead = 0, WriteReady = 1];
H --> B;
D -->|No| I[Check Parent Process Alive];
I --> J{Parent Alive?};
J -->|No| K[Exit Loop];
J -->|Yes| L[Sleep Microseconds];
L --> B;
B -->|No| M[AS Process Exit];
K --> M;
15.2. Client Handler
15.2.1. Add Client
flowchart TD;
A[addClient ClientFD] --> B[Set Socket Non-blocking];
B --> C[Create HTTPParser Object];
C --> D[Insert Client to Map];
D --> E[Setup Epoll Event EPOLLIN,EPOLLET];
E --> F[Add FD to Epoll];
15.2.2. Process Clients
flowchart TD;
A[processClients] --> B[Reset ProcessedClients = 0];
B --> C[epoll_wait for Ready FDs];
C --> D{Error?};
D -->|Yes| E[Log Error and Return];
D -->|No| F{FDCount > 0?};
F -->|Yes| G[readClientData FDCount];
F -->|No| H[Process AppServer Queue];
G --> H;
H --> I[Update ProcessedClients];
15.2.3. Read Client Data
flowchart TD;
A[readClientData FDCount] --> B[Initialize SHM Pointers];
B --> C[Loop Through Ready FDs];
C --> D{More FDs?};
D -->|Yes| E[Get ClientFD from Epoll Events];
E --> F[Receive Data from Socket];
F --> G{Bytes Received?};
G -->|0 bytes| H[Close Connection];
H --> I[Remove from Epoll];
I --> J[Remove from Client Map];
J --> D;
G -->|> 0 bytes| K{Client in Map?};
K -->|No| D;
K -->|Yes| L[Append Data to Buffer];
L --> M[Parse HTTP Request];
M --> N{Request Complete?};
N -->|Yes| O{GET Request?};
O -->|Yes| P[Add to StaticFS SHM];
O -->|No| Q{POST Request?};
Q -->|Yes| R[Add to AS Request Queue];
R --> D;
P --> S[Increment Request Count];
S --> D;
N -->|No| D;
D -->|No| T{Requests Added?};
T -->|Yes| U[Release StaticFS Lock];
T -->|No| V[Return];
U --> V;
15.3. Main Server
15.3.1. Server Initialization
flowchart TD;
A[Server::init] --> B[Setup Shared Memory];
B --> C[Set Shared Memory Pointers];
C --> D[Init Static Filesystem];
D --> E[Set Client Handler Config];
E --> F[Configure Socket Address/Port];
F --> G[Disable OS Signals SIGINT, SIGPIPE];
G --> H[Setup Termination Handler];
H --> I[Setup Server Socket];
I --> J[Setup Poll for Server Socket];
J --> K[Get ASRequestHandler Reference];
K --> L[Fork Result Processor Process];
L --> M[Register ResultProcessor PID];
M --> N[Fork Application Server Processes];
N --> O[Check AS Interpreter Count];
O --> P[Drop System Privileges];
P --> Q[Enter ServerLoop];
15.3.2. ServerLoop
flowchart TD;
A[ServerLoop Start] --> B{RunServer == True?};
B -->|Yes| C[Poll Server FD for Connections];
C --> D{Poll Error?};
D -->|Yes| E[Log Error];
E --> B;
D -->|No| F{POLLIN Event?};
F -->|Yes| G[acceptClient];
G --> H[Add Client to ClientHandler];
H --> I[processClients];
I --> B;
F -->|No| J{ProcessedClients == 0?};
J -->|Yes| K[Sleep IDLE_SLEEP_MICROSECONDS];
K --> I;
J -->|No| I;
B -->|No| L[Server Exit];
15.4. Result Processor
15.4.1. Read StaticFS Requests
flowchart TD;
A[Check StaticFS Lock] --> B{StaticFSLock == 1?};
B -->|Yes| C[Read Request Count from SHM];
C --> D[Loop Through Requests];
D --> E{More Requests?};
E -->|Yes| F[Read Request Metadata];
F --> G[Parse HTTP Properties];
G --> H[Append to ResultOrder];
H --> E;
E -->|No| I[Set StaticFSLock = 0];
I --> J[Mark Work Done];
B -->|No| K[Continue];
15.4.2. Read AS Results
flowchart TD;
A[Check AS Instances] --> B[Loop Through AS Instances];
B --> C{More Instances?};
C -->|Yes| D[Get Meta Addresses];
D --> E{WriteReady == 1?};
E -->|Yes| F[Read Result Metadata];
F --> G[Read Result Payload];
G --> H[Append to ResultOrder];
H --> I[Set CanRead = 1, WriteReady = 0];
I --> J[Mark Work Done];
J --> C;
E -->|No| C;
C -->|No| K[Return Result Count];
15.4.3. ResultProcessor Main Loop
flowchart TD;
A[ResultProcessor Main Loop] --> B{RunServer == True?};
B -->|Yes| C[WorkDone = False];
C --> D[Reset ResultOrder];
D --> E{StaticFS Lock == 1?};
E -->|Yes| F[Process StaticFS Requests];
F --> G[WorkDone = True];
G --> H[Process AS Results];
E -->|No| H;
H --> I{Results Processed?};
I -->|Yes| J[WorkDone = True];
I -->|No| K[Calculate ResultOrder];
J --> K;
K --> L[Process HTTP/1.2 Requests];
L --> M[Process HTTP/1.1 Requests];
M --> N{Requests to Process?};
N -->|Yes| O[ThreadHandler::processThreads];
O --> P[WorkDone = True];
P --> Q{WorkDone == False?};
N -->|No| Q;
Q -->|Yes| R[Sleep Microseconds];
R --> S{Parent Process Alive?};
Q -->|No| S;
S -->|Yes| B;
S -->|No| T[Exit Loop];
B -->|No| U[ResultProcessor Exit];
T --> U;
15.4.4. ThreadHandler Process
flowchart TD;
A[ThreadHandler::processThreads] --> B[Sort Requests by ClientFD];
B --> C[Add to ProcessRequests Queue];
C --> D[Loop Through ProcessRequests];
D --> E{More Requests?};
E -->|Yes| F{Thread Exists for ClientFD?};
F -->|Yes| G[Skip - Thread in Progress];
G --> E;
F -->|No| H[Create ClientThread Object];
H --> I[Store Thread Index];
I --> J[Start Thread];
J --> E;
E -->|No| K[Check Processed Threads];
K --> L{Thread Joinable?};
L -->|Yes| M[Join Thread];
M --> N[Remove from ProcessRequests];
N --> O[Remove from Index Map];
O --> P[Remove from ClientThreads];
P --> L;
L -->|No| Q[Return];
15.4.5. ClientThread Processing
flowchart TD;
A[ClientThread::processRequests] --> B[Loop Through Client Requests];
B --> C{More Requests?};
C -->|Yes| D{Request Type?};
D -->|StaticFS| E[Lookup File in VHost Map];
E --> F{File Found?};
F -->|Yes| G[Build HTTP Response Header];
G --> H[Send Header via write];
H --> I[Send File via sendfile];
I --> C;
F -->|No| J[Build 404 Response];
J --> K[Send 404 via write];
K --> C;
D -->|AppServer| L[Build HTTP Response Header];
L --> M[Send Header via write];
M --> N[Send AS Result via write];
N --> C;
C -->|No| O[Close Client Socket];
O --> P[Set Thread Complete Flag];