diff --git a/frameworks/Rust/soli/app/controllers/bench_controller.sl b/frameworks/Rust/soli/app/controllers/bench_controller.sl
index 026fce333fa..74f65b9a314 100644
--- a/frameworks/Rust/soli/app/controllers/bench_controller.sl
+++ b/frameworks/Rust/soli/app/controllers/bench_controller.sl
@@ -10,3 +10,11 @@ fn plaintext(req: Any) -> Any {
fn json(req: Any) -> Any {
return render_json({ "message": "Hello, World!" });
}
+
+// Fortune endpoint - queries fortunes from SoliDB, adds runtime fortune, sorts, renders HTML
+fn fortunes(req: Any) -> Any {
+ let fortunes = Fortune.all();
+ fortunes.push({ "id": 0, "message": "Additional fortune added at request time." });
+ let sorted = fortunes.sort_by("message");
+ return render("fortunes/index", { "fortunes": sorted });
+}
diff --git a/frameworks/Rust/soli/app/models/fortune.sl b/frameworks/Rust/soli/app/models/fortune.sl
new file mode 100644
index 00000000000..d62dcccaa63
--- /dev/null
+++ b/frameworks/Rust/soli/app/models/fortune.sl
@@ -0,0 +1,3 @@
+// Fortune model for TechEmpower benchmark
+class Fortune extends Model {
+}
diff --git a/frameworks/Rust/soli/app/views/fortunes/index.html.erb b/frameworks/Rust/soli/app/views/fortunes/index.html.erb
new file mode 100644
index 00000000000..235cc3e62c5
--- /dev/null
+++ b/frameworks/Rust/soli/app/views/fortunes/index.html.erb
@@ -0,0 +1,12 @@
+
+
+
Fortunes
+
+
+| id | message |
+<% for fortune in fortunes %>
+| <%= fortune["id"] %> | <%= fortune["message"] %> |
+<% end %>
+
+
+
diff --git a/frameworks/Rust/soli/benchmark_config.json b/frameworks/Rust/soli/benchmark_config.json
index 4812ed3cb74..4035484a349 100644
--- a/frameworks/Rust/soli/benchmark_config.json
+++ b/frameworks/Rust/soli/benchmark_config.json
@@ -5,20 +5,22 @@
"default": {
"plaintext_url": "/plaintext",
"json_url": "/json",
+ "fortune_url": "/fortunes",
"port": 3000,
"approach": "Realistic",
- "classification": "Platform",
- "database": "None",
+ "classification": "Fullstack",
"framework": "soli",
"language": "Rust",
- "orm": "Raw",
+ "database": "solidb",
+ "orm": "Full",
"platform": "Rust",
"webserver": "soli",
"os": "Linux",
"database_os": "Linux",
"display_name": "Soli",
"notes": "Soli MVC Framework",
- "versus": "hyper"
+ "versus": "hyper",
+ "dockerfile": "soli-solidb.dockerfile"
}
}]
}
diff --git a/frameworks/Rust/soli/config/routes.sl b/frameworks/Rust/soli/config/routes.sl
index 14c6ead4afd..2395a220110 100644
--- a/frameworks/Rust/soli/config/routes.sl
+++ b/frameworks/Rust/soli/config/routes.sl
@@ -5,3 +5,6 @@ get("/plaintext", "bench#plaintext");
// JSON endpoint
get("/json", "bench#json");
+
+// Fortune endpoint
+get("/fortunes", "bench#fortunes");
diff --git a/frameworks/Rust/soli/entrypoint.sh b/frameworks/Rust/soli/entrypoint.sh
new file mode 100644
index 00000000000..508ae443c7b
--- /dev/null
+++ b/frameworks/Rust/soli/entrypoint.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+set -e
+
+BASE="http://tfb-database:6745"
+
+# Wait for SoliDB to be ready
+echo "Waiting for SoliDB to be ready..."
+echo "BASE: $BASE"
+
+READY=false
+for i in $(seq 1 60); do
+ if curl -sf "$BASE/_api/health" > /dev/null 2>&1; then
+ READY=true
+ break
+ fi
+ echo "Attempt $i: SoliDB not ready, retrying..."
+ sleep 1
+done
+
+if [ "$READY" != "true" ]; then
+ echo "ERROR: SoliDB did not become ready after 60 seconds"
+ exit 1
+fi
+
+echo "SoliDB is ready"
+
+# Authenticate and get JWT token
+TOKEN=$(curl -sf -X POST "$BASE/auth/login" \
+ -H "Content-Type: application/json" \
+ -d '{"username": "admin", "password": "benchmarkdbpass"}' \
+ | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
+
+# Create an API key
+API_KEY=$(curl -sf -X POST "$BASE/_api/auth/api-keys" \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer $TOKEN" \
+ -d '{"name": "soli-benchmark"}' \
+ | sed -n 's/.*"key":"\([^"]*\)".*/\1/p')
+
+echo "API key created: ${API_KEY:0:8}..."
+
+# Write .env file for the soli framework
+cat > /app/.env < /dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+
+# Authenticate and get JWT token
+TOKEN=$(curl -sf -X POST "$BASE/auth/login" \
+ -H "Content-Type: application/json" \
+ -d '{"username": "admin", "password": "benchmarkdbpass"}' \
+ | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
+
+AUTH="Authorization: Bearer $TOKEN"
+
+# Create database
+curl -sf -X POST "$BASE/_api/database" \
+ -H "Content-Type: application/json" \
+ -H "$AUTH" \
+ -d '{"name": "hello_world"}' || true
+
+DB="$BASE/_api/database/hello_world"
+
+# Create collections before inserting documents
+curl -sf -X POST "$DB/collection" \
+ -H "Content-Type: application/json" \
+ -H "$AUTH" \
+ -d '{"name": "fortunes"}' || true
+
+curl -sf -X POST "$DB/collection" \
+ -H "Content-Type: application/json" \
+ -H "$AUTH" \
+ -d '{"name": "worlds"}' || true
+
+# Seeding errors should not kill the database container
+set +e
+
+# Seed fortune collection via batch insert
+curl -sf -X POST "$DB/document/fortunes/_batch" \
+ -H "Content-Type: application/json" \
+ -H "$AUTH" \
+ -H "X-Shard-Direct: true" \
+ -d '[
+ {"id": 1, "message": "fortune: No such file or directory"},
+ {"id": 2, "message": "A computer scientist is someone who fixes things that aren'\''t broken."},
+ {"id": 3, "message": "After enough decimal places, nobody gives a damn."},
+ {"id": 4, "message": "A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1"},
+ {"id": 5, "message": "A computer program does what you tell it to do, not what you want it to do."},
+ {"id": 6, "message": "Emacs is a nice operating system, but I prefer UNIX. \u2014 Tom Christaensen"},
+ {"id": 7, "message": "Any program that runs right is obsolete."},
+ {"id": 8, "message": "A list is only as strong as its weakest link. \u2014 Donald Knuth"},
+ {"id": 9, "message": "Feature: A bug with seniority."},
+ {"id": 10, "message": "Computers make very fast, very accurate mistakes."},
+ {"id": 11, "message": "