Skip to content

Commit 8218168

Browse files
Photon http fortunes (#10239)
* Add Fortunes endpoint * Forgot the template file * Minor fixes to pass the verification
1 parent e38ccf6 commit 8218168

File tree

4 files changed

+77
-18
lines changed

4 files changed

+77
-18
lines changed

frameworks/D/photon-http/benchmark_config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"tests": [
44
{
55
"default": {
6+
"fortune_url": "/fortunes",
67
"update_url": "/updates?queries=",
78
"query_url": "/queries?queries=",
89
"db_url": "/db",

frameworks/D/photon-http/dub.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
"mir-ion": "~>2.3.4",
1010
"xbuf" : "~>0.2.1",
1111
"photon": "~>0.18.10",
12-
"photon-http": "~>0.6.8"
12+
"photon-http": "~>0.6.8",
13+
"photon-mustache": "~>0.1.1"
1314
},
15+
"dflags": ["-J."],
1416
"description": "Benchmark of photon-http",
1517
"license": "BSL-1.0",
1618
"name": "photon-http-benchmark"

frameworks/D/photon-http/source/app.d

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import std.array;
44
import std.algorithm;
55
import std.conv;
66
import std.ascii;
7+
import core.stdc.stdlib;
8+
import core.stdc.string;
79

810
import mir.ser;
911
import mir.ser.json;
@@ -14,13 +16,14 @@ import std.range.primitives;
1416

1517
import glow.xbuf;
1618

17-
import photon, photon.http;
19+
import photon, photon.http, photon.mustache;
1820

1921
import mir.random : unpredictableSeedOf;
2022
import mir.random.variable : UniformVariable;
2123
import mir.random.engine.xorshift : Xorshift;
2224

2325
import dpq2;
26+
import dpq2.conv.to_d_types;
2427

2528
struct Message {
2629
string message;
@@ -31,6 +34,11 @@ struct WorldResponse {
3134
int randomNumber;
3235
}
3336

37+
struct FortuneResponse {
38+
int id;
39+
string message;
40+
}
41+
3442
enum connectionInfo = "host=tfb-database port=5432 "
3543
~ "dbname=hello_world user=benchmarkdbuser password=benchmarkdbpass";
3644
enum worldSize = 10000;
@@ -41,7 +49,8 @@ shared Pool!Connection connectionPool;
4149
class BenchmarkProcessor : HttpProcessor {
4250
HttpHeader[] plainTextHeaders = [HttpHeader("Content-Type", "text/plain; charset=utf-8")];
4351
HttpHeader[] jsonHeaders = [HttpHeader("Content-Type", "application/json")];
44-
Buffer!char jsonBuf;
52+
HttpHeader[] htmlHeaders = [HttpHeader("Content-Type", "text/html; charset=utf-8")];
53+
Buffer!char outBuf;
4554
Buffer!WorldResponse worlds;
4655
UniformVariable!uint uniformVariable;
4756
Xorshift gen;
@@ -50,7 +59,7 @@ class BenchmarkProcessor : HttpProcessor {
5059
super(sock);
5160
gen = Xorshift(unpredictableSeed!uint);
5261
uniformVariable = UniformVariable!uint(1, worldSize);
53-
jsonBuf = Buffer!char(256);
62+
outBuf = Buffer!char(256);
5463
worlds = Buffer!WorldResponse(500);
5564
}
5665

@@ -65,8 +74,9 @@ class BenchmarkProcessor : HttpProcessor {
6574
queries(req.uri);
6675
} else if(req.uri.startsWith("/updates")) {
6776
updates(req.uri);
68-
}
69-
else {
77+
} else if(req.uri == "/fortunes") {
78+
fortunes();
79+
} else {
7080
respondWith("Not found", HttpStatus.NotFound, plainTextHeaders);
7181
}
7282
}
@@ -76,13 +86,13 @@ class BenchmarkProcessor : HttpProcessor {
7686
}
7787

7888
final void json() {
79-
jsonBuf.clear();
80-
serializeJsonPretty!""(jsonBuf, Message("Hello, World!"));
81-
respondWith(jsonBuf.data, HttpStatus.OK, jsonHeaders);
89+
outBuf.clear();
90+
serializeJsonPretty!""(outBuf, Message("Hello, World!"));
91+
respondWith(outBuf.data, HttpStatus.OK, jsonHeaders);
8292
}
8393

8494
final void db() {
85-
jsonBuf.clear();
95+
outBuf.clear();
8696
int id = uniformVariable(gen);
8797
auto c = connectionPool.acquire();
8898
scope(exit) connectionPool.release(c);
@@ -91,13 +101,13 @@ class BenchmarkProcessor : HttpProcessor {
91101
qp.argsVariadic(id);
92102
immutable result = c.execPrepared(qp).rangify.front;
93103
auto w = WorldResponse(id, result[0].as!PGinteger);
94-
serializeJsonPretty!""(jsonBuf, w);
95-
respondWith(jsonBuf.data, HttpStatus.OK, jsonHeaders);
104+
serializeJsonPretty!""(outBuf, w);
105+
respondWith(outBuf.data, HttpStatus.OK, jsonHeaders);
96106
}
97107

98108
// GET /queries?queries=...
99109
final void queries(const(char)[] uri) {
100-
jsonBuf.clear();
110+
outBuf.clear();
101111
worlds.clear();
102112
auto c = connectionPool.acquire();
103113
scope(exit) connectionPool.release(c);
@@ -118,13 +128,13 @@ class BenchmarkProcessor : HttpProcessor {
118128
immutable result = c.execPrepared(qp).rangify.front;
119129
worlds.put(WorldResponse(id, result[0].as!PGinteger));
120130
}
121-
serializeJsonPretty!""(jsonBuf, worlds.data);
122-
respondWith(jsonBuf.data, HttpStatus.OK, jsonHeaders);
131+
serializeJsonPretty!""(outBuf, worlds.data);
132+
respondWith(outBuf.data, HttpStatus.OK, jsonHeaders);
123133
}
124134

125135
// GET /updates?queries=...
126136
final void updates(const(char)[] uri) {
127-
jsonBuf.clear();
137+
outBuf.clear();
128138
worlds.clear();
129139
auto c = connectionPool.acquire();
130140
scope(exit) connectionPool.release(c);
@@ -157,11 +167,44 @@ class BenchmarkProcessor : HttpProcessor {
157167
c.execPrepared(qp_update);
158168
worlds.put(w);
159169
}
160-
serializeJsonPretty!""(jsonBuf, worlds.data);
161-
respondWith(jsonBuf.data, HttpStatus.OK, jsonHeaders);
170+
serializeJsonPretty!""(outBuf, worlds.data);
171+
respondWith(outBuf.data, HttpStatus.OK, jsonHeaders);
172+
}
173+
174+
final void fortunes() {
175+
outBuf.clear();
176+
auto c = connectionPool.acquire();
177+
scope(exit) connectionPool.release(c);
178+
import std.algorithm : map, sort;
179+
180+
auto buf = Buffer!FortuneResponse(20);
181+
QueryParams qp;
182+
qp.preparedStatementName("fortune_prpq");
183+
auto result = c.execPrepared(qp).rangify;
184+
foreach (ref f; result) {
185+
buf.put(FortuneResponse(f[0].as!PGinteger, f[1].data.alloced));
186+
}
187+
buf.put(FortuneResponse(0, "Additional fortune added at request time."));
188+
auto data = buf.data;
189+
data.sort!((a, b) => a.message < b.message);
190+
mustache!(import("template.mustache"))(data, outBuf);
191+
foreach (ref v; data) {
192+
if (v.id != 0) dealloc(v.message);
193+
}
194+
respondWith(outBuf.data, HttpStatus.OK, htmlHeaders);
162195
}
163196
}
164197

198+
string alloced(const(ubyte)[] data) {
199+
void* ptr = malloc(data.length);
200+
memcpy(ptr, data.ptr, data.length);
201+
return (cast(immutable(char)*)ptr)[0..data.length];
202+
}
203+
204+
void dealloc(const(char)[] slice) {
205+
free(cast(void*)slice.ptr);
206+
}
207+
165208
void server_worker(Socket client) {
166209
scope processor = new BenchmarkProcessor(client);
167210
try {
@@ -201,6 +244,7 @@ void main() {
201244
initPhoton();
202245
connectionPool = pool(poolSize, 15.seconds, () {
203246
auto c = new Connection(connectionInfo);
247+
c.prepareEx("fortune_prpq", "SELECT id, message::text FROM Fortune");
204248
c.prepareEx("db_prpq", "SELECT randomNumber, id FROM world WHERE id = $1");
205249
c.prepareEx("db_update_prpq", "UPDATE world SET randomNumber = $1 WHERE id = $2");
206250
return c;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head><title>Fortunes</title></head>
4+
<body>
5+
<table>
6+
<tr><th>id</th><th>message</th></tr>
7+
{{#.}}
8+
<tr><td>{{id}}</td><td>{{message}}</td></tr>
9+
{{/.}}
10+
</table>
11+
</body>
12+
</html>

0 commit comments

Comments
 (0)