However, he knew that many of us are die hard Pascal fans that's alergy to non-pure Pascal code, so he created another one: https://github.com/risoflora/brookfreepascal, which is closer to the original Brook up to v3 (I still use this at work). The unfortunate part is that the two are not interchangeable, brookfreepascal is not simply brookframework with libsagui replaced by the same library implemented in pure Pascal.
Indeed, they appear to be significantly different. BrookFreePascal (BFP) appears to be mainly a CGI framework. (The README for the Brook framework doesn't say exactly
what it is or for what use cases it would be applicable
) A screenshot on the BFP home page (
https://risoflora.github.io/brookfreepascal/) suggests that it could be used to create an embedded server. So, I looked through the code a bit, and the only possible HTTP server related unit I found is BrookFCLHttpAppBroker which ... relies on FPHttpServer.
At one point in my research, I must have gotten some search terms right and discovered a program in an article that, I believe, you wrote at
https://pascalgeek.blogspot.com/2012/06/encryption-decryption-and-asynchronous.html ("fcl-net, the undocumented treasure"). It's a relatively simple multi-threaded TCP server! I struggled and over time managed to adapt that program to correctly read and respond to a request from a web browser. Aside from a just a few minor changes including adding the 'cmem' unit and defining the "Response" buffer globally, here is what I ended up with for the TClientHandlerThread.Execute procedure:
procedure TClientHandlerThread.Execute;
var
Request: array[0..1023] of char;
Done: Boolean;
begin
Done := false;
repeat
try
FClientStream.Read(Request, Length(Request))
FClientStream.Write(Response, Length(Response))
FClientStream.Free;
Exit;
except
on e: EStreamError do begin
Done := true;
end;
end;
until Done;
WriteLn(AddrToString(FClientStream.PeerAddress) + ' disconnected');
end;
That server program yields results similar to the FPHttpServer-based server example, from Rosetta Code, that I started with:
Concurrency Level: 500
Time taken for tests: 0.232 seconds
Complete requests: 500
Failed requests: 0
Total transferred: 32000 bytes
HTML transferred: 12500 bytes
Requests per second: 2157.69 [#/sec] (mean)
Time per request: 231.729 [ms] (mean)
Time per request: 0.463 [ms] (mean, across all concurrent requests)
Transfer rate: 134.86 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 12 12.0 14 28
Processing: 0 8 14.0 10 198
Waiting: 0 6 13.7 5 198
Total: 0 20 21.8 28 218
Percentage of the requests served within a certain time (ms)
50% 28
66% 36
75% 36
80% 37
90% 38
95% 38
98% 39
99% 59
100% 218 (longest request)
The numbers look good except for that last 1% of requests served outlier of 218ms. Occasionally, though, that same server will yield an anomalous result:
Concurrency Level: 500
Time taken for tests: 0.094 seconds
Complete requests: 500
Failed requests: 0
Total transferred: 32000 bytes
HTML transferred: 12500 bytes
Requests per second: 5317.68 [#/sec] (mean)
Time per request: 94.026 [ms] (mean)
Time per request: 0.188 [ms] (mean, across all concurrent requests)
Transfer rate: 332.35 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 18 10.6 15 34
Processing: 5 14 3.7 14 32
Waiting: 3 9 4.6 9 29
Total: 18 32 11.0 24 65
Percentage of the requests served within a certain time (ms)
50% 24
66% 43
75% 44
80% 45
90% 46
95% 46
98% 47
99% 47
100% 65 (longest request)
ALL good numbers and definitely comparable with the Golang and Rust server implementations. But unfortunately, this type of result is the exception, and I have no clue how to reproduce it consistently.
And, confusingly to me, the FPHttpServer-based server under "Siege" (`siege -b -c500 -r1
http://localhost:8080/`) will be relatively consistent in performance (1.49-3.81 secs) while the TCP server's performance will get progressively worse on each successive run eventually slowing to a crawl. Golang and Rust server implementations are both rather consistent under siege at around 0.22-1.28 secs.
Anyway, I've spent more time than I should have exploring this potential project. I sincerely appreciate everyone's comments and suggestions.