From 536a4c4c0528424993d83e0aa5543a7c8eda676d Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Sun, 3 Aug 2025 16:03:37 -0500 Subject: [PATCH] Add Shelf Framework --- frameworks/Dart/shelf/.dockerignore | 9 +++ frameworks/Dart/shelf/.gitignore | 5 ++ frameworks/Dart/shelf/README.md | 23 ++++++ frameworks/Dart/shelf/benchmark_config.json | 26 +++++++ frameworks/Dart/shelf/bin/server.dart | 84 +++++++++++++++++++++ frameworks/Dart/shelf/pubspec.yaml | 7 ++ frameworks/Dart/shelf/shelf.dockerfile | 14 ++++ 7 files changed, 168 insertions(+) create mode 100644 frameworks/Dart/shelf/.dockerignore create mode 100644 frameworks/Dart/shelf/.gitignore create mode 100644 frameworks/Dart/shelf/README.md create mode 100644 frameworks/Dart/shelf/benchmark_config.json create mode 100755 frameworks/Dart/shelf/bin/server.dart create mode 100644 frameworks/Dart/shelf/pubspec.yaml create mode 100644 frameworks/Dart/shelf/shelf.dockerfile diff --git a/frameworks/Dart/shelf/.dockerignore b/frameworks/Dart/shelf/.dockerignore new file mode 100644 index 00000000000..6a6cc8727a7 --- /dev/null +++ b/frameworks/Dart/shelf/.dockerignore @@ -0,0 +1,9 @@ +# From https://hub.docker.com/_/dart +.dockerignore +Dockerfile +build/ +.dart_tool/ +.git/ +.github/ +.gitignore +.packages diff --git a/frameworks/Dart/shelf/.gitignore b/frameworks/Dart/shelf/.gitignore new file mode 100644 index 00000000000..27fe9f77a4b --- /dev/null +++ b/frameworks/Dart/shelf/.gitignore @@ -0,0 +1,5 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ +*.lock +!bin diff --git a/frameworks/Dart/shelf/README.md b/frameworks/Dart/shelf/README.md new file mode 100644 index 00000000000..90820f340dd --- /dev/null +++ b/frameworks/Dart/shelf/README.md @@ -0,0 +1,23 @@ +# Shelf Benchmarking Test + +### Test Type Implementation Source Code + +- [JSON](server.dart) +- [PLAINTEXT](server.dart) + +## Important Libraries + +The tests were run with: + +- [pkg:shelf](https://pub.dev/packages/shelf) +- [Dart](https://dart.dev/) + +## Test URLs + +### JSON + +http://localhost:8080/json + +### PLAINTEXT + +http://localhost:8080/plaintext diff --git a/frameworks/Dart/shelf/benchmark_config.json b/frameworks/Dart/shelf/benchmark_config.json new file mode 100644 index 00000000000..29200587d0c --- /dev/null +++ b/frameworks/Dart/shelf/benchmark_config.json @@ -0,0 +1,26 @@ +{ + "framework": "shelf", + "tests": [ + { + "default": { + "json_url": "/json", + "plaintext_url": "/plaintext", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "None", + "framework": "shelf", + "language": "Dart", + "flavor": "None", + "orm": "None", + "platform": "shelf", + "webserver": "None", + "os": "Linux", + "database_os": "Linux", + "display_name": "shelf", + "notes": "", + "versus": "None" + } + } + ] +} diff --git a/frameworks/Dart/shelf/bin/server.dart b/frameworks/Dart/shelf/bin/server.dart new file mode 100755 index 00000000000..e3c3b71ca64 --- /dev/null +++ b/frameworks/Dart/shelf/bin/server.dart @@ -0,0 +1,84 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:isolate'; + +import 'package:shelf/shelf.dart'; +import 'package:shelf/shelf_io.dart' as shelf_io; + +void main(List args) async { + /// Create an [Isolate] containing an [HttpServer] + /// for each processor after the first + for (var i = 1; i < Platform.numberOfProcessors; i++) { + await Isolate.spawn(_startServer, args); + } + + /// Create a [HttpServer] for the first processor + await _startServer(args); +} + +/// Create a request handler +Response _handler(Request request) { + switch (request.url.path) { + case 'json': + return _jsonTest(); + case 'plaintext': + return _plaintextTest(); + default: + return _sendResponse(HttpStatus.notFound); + } +} + +/// Creates and setup a [HttpServer]. +Future _startServer(List _) async { + final server = await shelf_io.serve( + _handler, + InternetAddress.anyIPv4, + 8080, + shared: true, + ); + + /// Sets [HttpServer]'s [serverHeader]. + server + ..defaultResponseHeaders.clear() + ..serverHeader = 'shelf'; +} + +/// Completes the given [request] by writing the [bytes] with the given +/// [statusCode] and [type]. +Response _sendResponse( + int statusCode, { + ContentType? type, + List bytes = const [], +}) { + return Response( + statusCode, + headers: { + HttpHeaders.contentLengthHeader: '${bytes.length}', + HttpHeaders.dateHeader: '${HttpDate.format(DateTime.now())}', + if (type != null) HttpHeaders.contentTypeHeader: type.mimeType, + }, + body: bytes, + ); +} + +/// Completes the given [request] by writing the [response] as JSON. +Response _sendJson(Object response) => _sendResponse( + HttpStatus.ok, + type: ContentType.json, + bytes: _jsonEncoder.convert(response), +); + +/// Completes the given [request] by writing the [response] as plain text. +Response _sendText(String response) => _sendResponse( + HttpStatus.ok, + type: ContentType.text, + bytes: utf8.encode(response), +); + +/// Responds with the JSON test to the [request]. +Response _jsonTest() => _sendJson(const {'message': 'Hello, World!'}); + +/// Responds with the plaintext test to the [request]. +Response _plaintextTest() => _sendText('Hello, World!'); + +final _jsonEncoder = JsonUtf8Encoder(); diff --git a/frameworks/Dart/shelf/pubspec.yaml b/frameworks/Dart/shelf/pubspec.yaml new file mode 100644 index 00000000000..c41cff1b872 --- /dev/null +++ b/frameworks/Dart/shelf/pubspec.yaml @@ -0,0 +1,7 @@ +name: shelfbenchmark +description: A benchmark of pkg:shelf +environment: + sdk: ^3.8.0 + +dependencies: + shelf: ^1.0.0 diff --git a/frameworks/Dart/shelf/shelf.dockerfile b/frameworks/Dart/shelf/shelf.dockerfile new file mode 100644 index 00000000000..812b7e959ee --- /dev/null +++ b/frameworks/Dart/shelf/shelf.dockerfile @@ -0,0 +1,14 @@ + +FROM dart:3.8 AS builder + +COPY . /app +WORKDIR /app +RUN mkdir build +RUN dart compile exe ./bin/server.dart -o build/server + +FROM scratch +COPY --from=builder /runtime/ / +COPY --from=builder /app/build /bin + +EXPOSE 8080 +CMD ["server"]