diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 457ecabd..e72a764a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -240,6 +240,42 @@ jobs: GRPC_IMAGE_NAME: ${{ needs.set-image-name.outputs.name }} + dart_grpc_bench: + runs-on: ubuntu-latest + needs: + - set-image-name + - changed + if: fromJSON(needs.changed.outputs.base) || contains(needs.changed.outputs.files, 'dart_grpc_bench/') + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Build dart_grpc_bench + run: ./build.sh dart_grpc_bench + env: + GRPC_IMAGE_NAME: ${{ needs.set-image-name.outputs.name }} + + - name: Benchmark dart_grpc_bench + run: ./bench.sh dart_grpc_bench + env: + GRPC_BENCHMARK_DURATION: 30s + GRPC_IMAGE_NAME: ${{ needs.set-image-name.outputs.name }} + + - if: github.ref == 'refs/heads/master' + name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - if: github.ref == 'refs/heads/master' + name: If on master push image to GHCR + run: docker push $GRPC_IMAGE_NAME:dart_grpc_bench-complex_proto + env: + GRPC_IMAGE_NAME: ${{ needs.set-image-name.outputs.name }} + + dotnet_grpc_bench: runs-on: ubuntu-latest needs: diff --git a/dart_grpc_bench/.dockerignore b/dart_grpc_bench/.dockerignore new file mode 100644 index 00000000..91da415d --- /dev/null +++ b/dart_grpc_bench/.dockerignore @@ -0,0 +1,3 @@ +.dockerignore +Dockerfile +.dart_tool/ \ No newline at end of file diff --git a/dart_grpc_bench/Dockerfile b/dart_grpc_bench/Dockerfile new file mode 100644 index 00000000..8ae7846e --- /dev/null +++ b/dart_grpc_bench/Dockerfile @@ -0,0 +1,28 @@ +FROM dart:stable AS build + +WORKDIR /app +COPY dart_grpc_bench/pubspec.yaml /app/pubspec.yaml +COPY proto /app/proto + +RUN dart pub get +COPY dart_grpc_bench /app +# Ensure packages are still up-to-date if anything has changed +RUN dart pub get --offline +RUN apt update && apt install -y protobuf-compiler +RUN dart pub global activate protoc_plugin +RUN mkdir -p lib/src/generated +RUN protoc --plugin=protoc-gen-dart=$HOME/.pub-cache/bin/protoc-gen-dart --proto_path=/app/proto/helloworld --dart_out=grpc:lib/src/generated -Iproto /app/proto/helloworld/helloworld.proto + +RUN dart compile exe bin/server.dart -o bin/server + +# ENTRYPOINT [ "/usr/bin/dart", "/app/bin/server.dart" ] + +# Build minimal serving image from AOT-compiled `/server` and required system +# libraries and configuration files stored in `/runtime/` from the build stage. +FROM scratch +COPY --from=build /runtime/ / +COPY --from=build /app/bin/server /app/bin/ + +# Start server. +EXPOSE 50051 +CMD ["/app/bin/server"] \ No newline at end of file diff --git a/dart_grpc_onhold/bin/server.dart b/dart_grpc_bench/bin/server.dart similarity index 65% rename from dart_grpc_onhold/bin/server.dart rename to dart_grpc_bench/bin/server.dart index c6b6b7f7..ced7ed45 100644 --- a/dart_grpc_onhold/bin/server.dart +++ b/dart_grpc_bench/bin/server.dart @@ -14,6 +14,9 @@ // limitations under the License. /// Dart implementation of the gRPC helloworld.Greeter server. +import 'dart:io'; +import 'dart:isolate'; + import 'package:grpc/grpc.dart'; import 'package:helloworld/src/generated/helloworld.pb.dart'; @@ -22,12 +25,28 @@ import 'package:helloworld/src/generated/helloworld.pbgrpc.dart'; class GreeterService extends GreeterServiceBase { @override Future sayHello(ServiceCall call, HelloRequest request) async { - return HelloReply()..message = '${request.name}'; + return HelloReply()..response = request.request; } } Future main(List args) async { + Map env = Platform.environment; + final cpus = int.tryParse(env["GRPC_SERVER_CPUS"] ?? '1') ?? 1; + + if (cpus > 1) { + for (var serve = 0; serve < cpus; serve++) { + Isolate.spawn(_startServer, []); + } + } + // Bind one server in current Isolate + _startServer(); + + print('Server listening on port 50051...'); + await ProcessSignal.sigterm.watch().first; +} + +void _startServer([List? args]) async { final server = Server([GreeterService()]); - await server.serve(port: 50051); - print('Server listening on port ${server.port}...'); + await server.serve( + address: InternetAddress.anyIPv4, port: 50051, shared: true); } diff --git a/dart_grpc_bench/pubspec.lock b/dart_grpc_bench/pubspec.lock new file mode 100644 index 00000000..e5e21b8c --- /dev/null +++ b/dart_grpc_bench/pubspec.lock @@ -0,0 +1,165 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + sha256: d6347d54a2d8028e0437e3c099f66fdb8ae02c4720c1e7534c9f24c10351f85d + url: "https://pub.dev" + source: hosted + version: "3.3.6" + async: + dependency: "direct main" + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + collection: + dependency: transitive + description: + name: collection + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" + source: hosted + version: "1.17.1" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + googleapis_auth: + dependency: transitive + description: + name: googleapis_auth + sha256: "127b1bbd32170ab8312f503bd57f1d654d8e4039ddfbc63c027d3f7ade0eff74" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + grpc: + dependency: "direct main" + description: + name: grpc + sha256: a73c16e4f6a4a819be892bb2c73cc1d0b00e36095f69b0738cc91a733e3d27ba + url: "https://pub.dev" + source: hosted + version: "3.1.0" + http: + dependency: transitive + description: + name: http + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" + source: hosted + version: "0.13.5" + http2: + dependency: transitive + description: + name: http2 + sha256: "58805ebc6513eed3b98ee0a455a8357e61d187bf2e0fdc1e53120770f78de258" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + meta: + dependency: transitive + description: + name: meta + sha256: "12307e7f0605ce3da64cf0db90e5fcab0869f3ca03f76be6bb2991ce0a55e82b" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 + url: "https://pub.dev" + source: hosted + version: "3.6.2" + protobuf: + dependency: "direct main" + description: + name: protobuf + sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" + source: hosted + version: "1.3.1" +sdks: + dart: ">=2.19.0 <4.0.0" diff --git a/dart_grpc_bench/pubspec.yaml b/dart_grpc_bench/pubspec.yaml new file mode 100644 index 00000000..f06dc33d --- /dev/null +++ b/dart_grpc_bench/pubspec.yaml @@ -0,0 +1,9 @@ +name: helloworld + +environment: + sdk: '>=2.19.0 <3.0.0' + +dependencies: + async: ^2.10.0 + grpc: ^3.1.0 + protobuf: ^2.1.0 diff --git a/dart_grpc_onhold/Dockerfile b/dart_grpc_onhold/Dockerfile deleted file mode 100644 index 8006834a..00000000 --- a/dart_grpc_onhold/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM google/dart - -WORKDIR /app -COPY dart_grpc_bench/pubspec.yaml /app/pubspec.yaml -COPY proto /app/proto - -RUN pub get -COPY dart_grpc_bench /app -RUN pub get --offline -RUN apt update && apt install -y protobuf-compiler -RUN pub global activate protoc_plugin -RUN mkdir -p lib/src/generated -RUN protoc --proto_path=/app/proto/helloworld --dart_out=grpc:lib/src/generated -Iprotos /app/proto/helloworld/helloworld.proto - -ENTRYPOINT [ "/usr/bin/dart", "/app/bin/server.dart" ] diff --git a/dart_grpc_onhold/pubspec.yaml b/dart_grpc_onhold/pubspec.yaml deleted file mode 100644 index 7618e35c..00000000 --- a/dart_grpc_onhold/pubspec.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: helloworld - -environment: - sdk: '>=2.2.0 <3.0.0' - -dependencies: - async: ^2.2.0 - grpc: ^2.2.0 - protobuf: ^1.0.1