From 423e328d8399593233d7b962a22d52906d6f683c Mon Sep 17 00:00:00 2001 From: Joan Miquel Date: Mon, 20 Nov 2023 22:45:22 +0100 Subject: [PATCH 01/15] [rust] Fix Gotham (#8560) --- frameworks/Rust/gotham/gotham.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Rust/gotham/gotham.dockerfile b/frameworks/Rust/gotham/gotham.dockerfile index 197ca3dc0a8..aec3a1dc178 100644 --- a/frameworks/Rust/gotham/gotham.dockerfile +++ b/frameworks/Rust/gotham/gotham.dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.60 +FROM rust:1.65 WORKDIR /gotham COPY ./src ./src From 0ec8ed488ec87718eaee9ed05c0ffd51ca48113b Mon Sep 17 00:00:00 2001 From: srisaiswaroop Date: Tue, 21 Nov 2023 03:15:45 +0530 Subject: [PATCH 02/15] 1. Made the query for bulk update a bit readable. (#8555) 2. Updated the cluster code to use availableParallelism as used nowdays witth the recent node.js versions. 3. Updated to the ESM require modules which are used in all latest node.js projects instead of old CJS modules. --- frameworks/JavaScript/nodejs/app.js | 11 ++++++----- frameworks/JavaScript/nodejs/create-server.js | 2 +- frameworks/JavaScript/nodejs/handlers/postgres.js | 12 ++++++------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/frameworks/JavaScript/nodejs/app.js b/frameworks/JavaScript/nodejs/app.js index 95c97a34291..b118b71bc61 100755 --- a/frameworks/JavaScript/nodejs/app.js +++ b/frameworks/JavaScript/nodejs/app.js @@ -1,5 +1,6 @@ -const cluster = require('cluster'); -const numCPUs = require('os').cpus().length; +const cluster = require('node:cluster'); +const { availableParallelism } = require('node:os'); +const numCPUs = availableParallelism(); process.env.NODE_HANDLER = 'postgres'; @@ -13,18 +14,18 @@ if (process.env.TFB_TEST_NAME === 'nodejs-mongodb') { process.env.NODE_HANDLER = 'mysql-raw'; } else if (process.env.TFB_TEST_NAME === 'nodejs-postgres') { process.env.NODE_HANDLER = 'sequelize-postgres'; -}else if (process.env.TFB_TEST_NAME === 'nodejs-postgresjs-raw') { +} else if (process.env.TFB_TEST_NAME === 'nodejs-postgresjs-raw') { process.env.NODE_HANDLER = 'postgres'; } -if (cluster.isPrimary) { +if (numCPUs > 1 && cluster.isPrimary) { console.log(`Primary ${process.pid} is running`); // Fork workers. for (let i = 0; i < numCPUs; i++) { cluster.fork(); } - + cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); process.exit(1); diff --git a/frameworks/JavaScript/nodejs/create-server.js b/frameworks/JavaScript/nodejs/create-server.js index b0e142deb1a..38fdb6c938c 100644 --- a/frameworks/JavaScript/nodejs/create-server.js +++ b/frameworks/JavaScript/nodejs/create-server.js @@ -1,7 +1,7 @@ // Forked workers will run this code when found to not be // the master of the cluster. -const http = require('http'); +const http = require('node:http'); const parseurl = require('parseurl'); // faster than native nodejs url package // Initialize routes & their handlers (once) diff --git a/frameworks/JavaScript/nodejs/handlers/postgres.js b/frameworks/JavaScript/nodejs/handlers/postgres.js index c7411c64fad..3d6eee29872 100644 --- a/frameworks/JavaScript/nodejs/handlers/postgres.js +++ b/frameworks/JavaScript/nodejs/handlers/postgres.js @@ -17,14 +17,14 @@ const dbfind = async (id) => (arr) => arr[0] ); -const dbbulkUpdate = async (worlds) => +const dbbulkUpdate = async (worlds) => { + const sorted = sql(worlds + .map((world) => [world.id, world.randomNumber]) + .sort((a, b) => (a[0] < b[0] ? -1 : 1))); await sql`UPDATE world SET randomNumber = (update_data.randomNumber)::int - FROM (VALUES ${sql( - worlds - .map((world) => [world.id, world.randomNumber]) - .sort((a, b) => (a[0] < b[0] ? -1 : 1)) - )}) AS update_data (id, randomNumber) + FROM (VALUES ${sorted}) AS update_data (id, randomNumber) WHERE world.id = (update_data.id)::int`; +}; const dbgetAllWorlds = async () => sql`SELECT id, randomNumber FROM world`; From ba03ee555f338ad3e06b9f5f64d166a3d60cac06 Mon Sep 17 00:00:00 2001 From: Petrik de Heus Date: Mon, 27 Nov 2023 19:11:16 +0100 Subject: [PATCH 03/15] [rails] Set connection pool to 5 (#8562) The connection pool size should be set to the number of threads per worker. This was previously correct. This partially reverts commit 43761fca4aa920e78b5ea6a13c690da1d2b75565. --- frameworks/Ruby/rails/config/database.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Ruby/rails/config/database.yml b/frameworks/Ruby/rails/config/database.yml index 8fa7b78a4e1..ae7de0910d7 100644 --- a/frameworks/Ruby/rails/config/database.yml +++ b/frameworks/Ruby/rails/config/database.yml @@ -5,7 +5,7 @@ default: &default password: benchmarkdbpass host: tfb-database timeout: 5000 - pool: <%= require_relative 'auto_tune'; auto_tune.reduce(:*) %> + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default From 49f05b16e7a02a22b468fd00898a28934462b959 Mon Sep 17 00:00:00 2001 From: n-stefan <38526229+n-stefan@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:11:38 +0200 Subject: [PATCH 04/15] [ASP.NET Core] Inline completions (#8546) * aspcore: add platform multiple queries * Add missing console output * tweak postgresql connectionstring * Set DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS --------- Co-authored-by: Stefan Negulescu --- frameworks/CSharp/aspnetcore/aspnetcore.dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/CSharp/aspnetcore/aspnetcore.dockerfile b/frameworks/CSharp/aspnetcore/aspnetcore.dockerfile index d1e50dd88e0..90409f3b188 100644 --- a/frameworks/CSharp/aspnetcore/aspnetcore.dockerfile +++ b/frameworks/CSharp/aspnetcore/aspnetcore.dockerfile @@ -5,6 +5,7 @@ RUN dotnet publish -c Release -o out /p:DatabaseProvider=Npgsql FROM mcr.microsoft.com/dotnet/aspnet:8.0.0-rc.2 AS runtime ENV URLS http://+:8080 +ENV DOTNET_SYSTEM_NET_SOCKETS_INLINE_COMPLETIONS 1 WORKDIR /app COPY --from=build /app/out ./ From 78d170c974efaa61974fe70baa243e90ea0a5b3a Mon Sep 17 00:00:00 2001 From: Jorge Alexandre Delesderrier da Silva Date: Mon, 27 Nov 2023 15:12:04 -0300 Subject: [PATCH 05/15] just-boost added (#8476) --- frameworks/C++/just-boost/README.md | 38 ++ .../C++/just-boost/benchmark_config.json | 27 ++ .../C++/just-boost/just-boost.dockerfile | 25 ++ frameworks/C++/just-boost/main.cpp | 396 ++++++++++++++++++ 4 files changed, 486 insertions(+) create mode 100644 frameworks/C++/just-boost/README.md create mode 100644 frameworks/C++/just-boost/benchmark_config.json create mode 100644 frameworks/C++/just-boost/just-boost.dockerfile create mode 100644 frameworks/C++/just-boost/main.cpp diff --git a/frameworks/C++/just-boost/README.md b/frameworks/C++/just-boost/README.md new file mode 100644 index 00000000000..2c65928d229 --- /dev/null +++ b/frameworks/C++/just-boost/README.md @@ -0,0 +1,38 @@ +# Just.Boost Benchmarking Test + +## Description + +Backend using just C++(20) and Boost. + +## Run Test + + cd FrameworkBenchmarks/ + ./tfb --mode verify --test just-boost + +## Software Versions + +- [Alpine 3.18](https://hub.docker.com/_/alpine) +- [gcc](https://gcc.gnu.org/) +- [c++20](https://en.cppreference.com/w/cpp/20) +- [Boost](https://www.boost.org/) + - [Beast](https://www.boost.org/doc/libs/1_83_0/libs/beast/doc/html/index.html) ([HTTP Server with C++ 20 coroutine](https://www.boost.org/doc/libs/1_83_0/libs/beast/example/http/server/awaitable/http_server_awaitable.cpp)) + - [JSON](https://www.boost.org/doc/libs/1_83_0/libs/json/doc/html/index.html) +- [libpq — C Library](https://www.postgresql.org/docs/current/libpq.html) (PostgreSQL client) + +## Test URLs + +### Test 1: JSON Encoding + + http://localhost:8000/json + +### Test 2: Single Row Query + + http://localhost:8000/db + +### Test 3: Multi Row Query + + http://localhost:8000/queries/{count} + +### Test 6: Plaintext + + http://localhost:8000/plaintext diff --git a/frameworks/C++/just-boost/benchmark_config.json b/frameworks/C++/just-boost/benchmark_config.json new file mode 100644 index 00000000000..462fd21432c --- /dev/null +++ b/frameworks/C++/just-boost/benchmark_config.json @@ -0,0 +1,27 @@ +{ + "framework": "just-boost", + "tests": [ + { + "default": { + "json_url": "/json", + "plaintext_url": "/plaintext", + "db_url": "/db", + "query_url": "/queries/", + "port": 8000, + "approach": "Realistic", + "classification": "Micro", + "database": "Postgres", + "framework": "Boost", + "language": "C++", + "orm": "Raw", + "platform": "None", + "webserver": "None", + "os": "Linux", + "database_os": "Linux", + "display_name": "just-boost", + "notes": "", + "versus": "" + } + } + ] +} diff --git a/frameworks/C++/just-boost/just-boost.dockerfile b/frameworks/C++/just-boost/just-boost.dockerfile new file mode 100644 index 00000000000..0eb409e1ab9 --- /dev/null +++ b/frameworks/C++/just-boost/just-boost.dockerfile @@ -0,0 +1,25 @@ +# docker build --progress=plain --build-arg CXXFLAGS="-Wall" -t just-boost -f just-boost.dockerfile . +# docker run --rm --name just-boost -p 8000:8000 -d just-boost +# docker container stop just-boost +FROM alpine:3.18 + +ARG APP=just-boost +ARG CXXFLAGS=-O3 + +ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 +ENV BCPP_PG_CONN_STR="postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world" +ENV BCPP_N_THREADS=32 + +WORKDIR /usr/src/${APP} + +RUN apk add --no-cache build-base boost-dev libpq-dev +COPY *.cpp ./ +RUN g++ ${CXXFLAGS} -std=c++20 \ + -I$(pg_config --includedir) \ + -o main main.cpp \ + -L$(pg_config --libdir) -lpq \ + && rm *.cpp + +EXPOSE 8000 + +CMD ["./main"] diff --git a/frameworks/C++/just-boost/main.cpp b/frameworks/C++/just-boost/main.cpp new file mode 100644 index 00000000000..fc296da6837 --- /dev/null +++ b/frameworks/C++/just-boost/main.cpp @@ -0,0 +1,396 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_ASIO_HAS_CO_AWAIT) + +#include + +namespace beast = boost::beast; // from +namespace http = beast::http; // from +namespace net = boost::asio; // from +using tcp = boost::asio::ip::tcp; // from +namespace json = boost::json; // from + +using tcp_stream = typename beast::tcp_stream::rebind_executor< + net::use_awaitable_t<>::executor_with_default>::other; + +namespace becpp +{ + +using result_ptr = std::unique_ptr; + +//https://gist.github.com/ictlyh/12fe787ec265b33fd7e4b0bd08bc27cb +result_ptr prepare(PGconn* conn, + const char* stmtName, + const char* command, + uint8_t nParams) +{ + auto res = PQprepare(conn, stmtName, command, nParams, nullptr); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + std::cerr << "PQprepare failed: " << PQresultErrorMessage(res) + << std::endl; + PQclear(res); + return {nullptr, nullptr}; + } + + return {res, &PQclear}; +} + +result_ptr execute(PGconn* conn, + const char* stmtName, + uint8_t nParams, + const char* const* paramValues, + const int* paramLengths = nullptr, + const int* paramFormats = nullptr, + int resultFormat = 0) +{ + auto res = PQexecPrepared(conn, stmtName, nParams, paramValues, paramLengths, + paramFormats, resultFormat); + const auto status = PQresultStatus(res); + if (status != PGRES_COMMAND_OK && + status != PGRES_TUPLES_OK && + status != PGRES_SINGLE_TUPLE) + { + std::cerr << "PQexecPrepared failed: " << PQresultErrorMessage(res) + << std::endl; + PQclear(res); + return {nullptr, nullptr}; + } + + return {res, &PQclear}; +} + +const char* env(const char* env_var, const char* default_value) +{ + if (const char* env_p = std::getenv(env_var)) + return env_p; + + return default_value; +} + +std::string now_string() +{ + std::time_t time = std::time(nullptr); + char timeString[std::size("Wed, 17 Apr 2013 12:00:00 GMT")]; + std::strftime(std::data(timeString), std::size(timeString), "%a, %d %b %Y %X %Z", std::localtime(&time)); + return timeString; +} + +template +http::message_generator +handle_error( + http::request>&& req, + http::status status, + beast::string_view msg) +{ + http::response res{status, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "text/html"); + res.set(http::field::date, now_string()); + res.keep_alive(req.keep_alive()); + res.body() = std::string(msg); + res.prepare_payload(); + return res; +} + +template +http::message_generator +handle_target( + http::request>&& req, + PGconn* conn = nullptr) +{ + static std::string msg = "Hello, World!"; + + //std::cout << "handle_target: " << req.target() << std::endl; + http::response res{http::status::ok, req.version()}; + res.set(http::field::server, BOOST_BEAST_VERSION_STRING); + res.set(http::field::content_type, "application/json"); + res.set(http::field::date, now_string()); + res.keep_alive(req.keep_alive()); + + if (req.target() == "/json") + { + // {"message":"Hello, World!"} + json::object obj; + obj["message"] = msg; + res.body() = json::serialize(obj); + } + else if (req.target() == "/plaintext") + { + res.set(http::field::content_type, "text/plain"); + res.body() = msg; + } + else if (req.target() == "/db" || req.target().starts_with("/queries/")) + { + static std::random_device rd; + static std::minstd_rand gen(rd()); + static std::uniform_int_distribution<> distrib(1, 10000); + static const char* word_query = "SELECT randomNumber FROM world WHERE id=$1"; + thread_local auto stmt = prepare(conn, "word_query_stmt", word_query, 1); + + if (req.target() == "/db") + { + const unsigned uint_id = distrib(gen); + const auto str_id = std::to_string(uint_id); + const char* char_ptr_id = str_id.c_str(); + if (auto rs = execute(conn, "word_query_stmt", 1, &char_ptr_id)) + { + // {"id":3217,"randomNumber":2149} + json::object obj; + obj["id"] = uint_id; + obj["randomNumber"] = std::atoi(PQgetvalue(rs.get(), 0, 0)); + res.body() = json::serialize(obj); + //std::cout << "res.body(): " << res.body() << std::endl; + } + else + return handle_error(std::move(req), + http::status::internal_server_error, + "internal_server_error"); + } + else if (req.target().starts_with("/queries/")) + { + int n_queries = 1; + try + { + const int n = std::stoi(req.target().substr(req.target().find_last_of('/')+1)); + if (n > 1) n_queries = n; + } catch(...) {} + if (n_queries > 500) n_queries = 500; + json::array objs; + for (auto i = 0; i < n_queries; ++i) + { + const unsigned uint_id = distrib(gen); + const auto str_id = std::to_string(uint_id); + const char* char_ptr_id = str_id.c_str(); + if (auto rs = execute(conn, "word_query_stmt", 1, &char_ptr_id)) + { + // {"id":3217,"randomNumber":2149} + json::object obj; + obj["id"] = uint_id; + obj["randomNumber"] = std::atoi(PQgetvalue(rs.get(), 0, 0)); + objs.push_back(obj); + } + else + return handle_error(std::move(req), + http::status::internal_server_error, + "internal_server_error"); + } + res.body() = json::serialize(objs); + //std::cout << "res.body(): " << res.body() << std::endl; + } + } + else + { + return handle_error(std::move(req), + http::status::not_found, + "Unhandled target: '" + std::string(req.target()) + "'"); + } + + res.prepare_payload(); + return res; +} + +// Return a response for the given request. +// +// The concrete type of the response message (which depends on the +// request), is type-erased in message_generator. +template +http::message_generator +handle_request( + http::request>&& req) +{ + // Make sure we can handle the method + if (req.method() != http::verb::get) + return handle_error(std::move(req), + http::status::not_found, + "Unhandled method: '" + std::string(req.method_string()) + "'"); + + if (req.target() == "/json" || req.target() == "/plaintext") + return handle_target(std::move(req)); + + thread_local std::unique_ptr conn + { + PQconnectdb(env("BCPP_PG_CONN_STR", "")), + &PQfinish + }; + if (PQstatus(conn.get()) != CONNECTION_OK) + { + auto msg = PQerrorMessage(conn.get()); + std::cerr << "PQerrorMessage: " << msg << std::endl; + return handle_error(std::move(req), + http::status::internal_server_error, + msg); + } + return handle_target(std::move(req), conn.get()); +} + +} +//------------------------------------------------------------------------------ + + +// Handles an HTTP server connection +net::awaitable +do_session(tcp_stream stream) +{ + // This buffer is required to persist across reads + beast::flat_buffer buffer; + + // This lambda is used to send messages + try + { + for(;;) + { + // Set the timeout. + stream.expires_after(std::chrono::seconds(30)); + + // Read a request + http::request req; + co_await http::async_read(stream, buffer, req); + + // Handle the request + http::message_generator msg = + becpp::handle_request(std::move(req)); + + // Determine if we should close the connection + bool keep_alive = msg.keep_alive(); + + // Send the response + co_await beast::async_write(stream, std::move(msg), net::use_awaitable); + + if(! keep_alive) + { + // This means we should close the connection, usually because + // the response indicated the "Connection: close" semantic. + break; + } + } + } + catch (boost::system::system_error & se) + { + if (se.code() != http::error::end_of_stream ) + throw ; + } + + // Send a TCP shutdown + beast::error_code ec; + stream.socket().shutdown(tcp::socket::shutdown_send, ec); + + // At this point the connection is closed gracefully + // we ignore the error because the client might have + // dropped the connection already. +} + +//------------------------------------------------------------------------------ + +// Accepts incoming connections and launches the sessions +net::awaitable +do_listen(tcp::endpoint endpoint) +{ + // Open the acceptor + auto acceptor = net::use_awaitable.as_default_on(tcp::acceptor(co_await net::this_coro::executor)); + acceptor.open(endpoint.protocol()); + + // Allow address reuse + acceptor.set_option(net::socket_base::reuse_address(true)); + + // Bind to the server address + acceptor.bind(endpoint); + + // Start listening for connections + acceptor.listen(net::socket_base::max_listen_connections); + + for(;;) + boost::asio::co_spawn( + acceptor.get_executor(), + do_session(tcp_stream(co_await acceptor.async_accept())), + [](std::exception_ptr e) + { + if (e) + try + { + std::rethrow_exception(e); + } + catch (std::exception &e) { + std::cerr << "Error in session: " << e.what() << "\n"; + } + }); + +} + +int main(int argc, char* argv[]) +{ + auto const address = net::ip::make_address(becpp::env("BCPP_ADDRESS", "0.0.0.0")); + auto const port = static_cast(std::atoi(becpp::env("BCPP_PORT", "8000"))); + auto const threads = std::max(1, std::atoi(becpp::env("BCPP_N_THREADS", "3"))); + + std::cout << "__GNUG__=" << __GNUG__ << '\n'; + std::cout << "__cplusplus=" << __cplusplus << '\n'; + std::cout << "__TIMESTAMP__=" << __TIMESTAMP__ << '\n'; + std::cout << "__GNUC_EXECUTION_CHARSET_NAME=" << __GNUC_EXECUTION_CHARSET_NAME << '\n'; + std::cout << "Listening " << address << ':' << port << " threads=" << threads << std::endl; + + // The io_context is required for all I/O + net::io_context ioc{threads}; + + // Spawn a listening port + boost::asio::co_spawn(ioc, + do_listen(tcp::endpoint{address, port}), + [](std::exception_ptr e) + { + if (e) + try + { + std::rethrow_exception(e); + } + catch(std::exception & e) + { + std::cerr << "Error in acceptor: " << e.what() << "\n"; + } + }); + + // Run the I/O service on the requested number of threads + try { + std::vector v; + v.reserve(threads - 1); + for(auto i = threads - 1; i > 0; --i) + v.emplace_back( + [&ioc] + { + ioc.run(); + }); + ioc.run(); + } catch (std::exception& e) + { + std::cerr << "Error in main: " << e.what() << "\n"; + } + + return EXIT_SUCCESS; +} + +#else + +int main(int, char * []) +{ + std::printf("awaitables require C++20\n"); + return 1; +} + +#endif From 8f34a2f470512899448918fe91a0e5cc1634fbf8 Mon Sep 17 00:00:00 2001 From: Petrik de Heus Date: Mon, 27 Nov 2023 19:13:39 +0100 Subject: [PATCH 06/15] [ruby] Set the MIN_WORKERS to 2, like all other Ruby frameworks. (#8533) This allows better comparison between other frameworks and the Rack baseline. --- frameworks/Ruby/hanami/config/auto_tune.rb | 2 +- frameworks/Ruby/rack/config/auto_tune.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frameworks/Ruby/hanami/config/auto_tune.rb b/frameworks/Ruby/hanami/config/auto_tune.rb index fbb495c6647..476ed1a45bd 100644 --- a/frameworks/Ruby/hanami/config/auto_tune.rb +++ b/frameworks/Ruby/hanami/config/auto_tune.rb @@ -8,7 +8,7 @@ require 'etc' KB_PER_WORKER = 128 * 1_024 # average of peak PSS of single-threaded processes (watch smem -k) -MIN_WORKERS = 15 +MIN_WORKERS = 2 MAX_WORKERS_PER_VCPU = 1.25 # virtual/logical MIN_THREADS_PER_WORKER = 1 MAX_THREADS = Integer(ENV['MAX_CONCURRENCY'] || 256) diff --git a/frameworks/Ruby/rack/config/auto_tune.rb b/frameworks/Ruby/rack/config/auto_tune.rb index fbb495c6647..476ed1a45bd 100755 --- a/frameworks/Ruby/rack/config/auto_tune.rb +++ b/frameworks/Ruby/rack/config/auto_tune.rb @@ -8,7 +8,7 @@ require 'etc' KB_PER_WORKER = 128 * 1_024 # average of peak PSS of single-threaded processes (watch smem -k) -MIN_WORKERS = 15 +MIN_WORKERS = 2 MAX_WORKERS_PER_VCPU = 1.25 # virtual/logical MIN_THREADS_PER_WORKER = 1 MAX_THREADS = Integer(ENV['MAX_CONCURRENCY'] || 256) From fb054926d2e3f985dda03910c2fe57251b004f31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:14:00 -0800 Subject: [PATCH 07/15] Bump aiohttp from 3.8.5 to 3.8.6 in /frameworks/Python/aiohttp (#8542) Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.5 to 3.8.6. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.5...v3.8.6) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frameworks/Python/aiohttp/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/aiohttp/requirements.txt b/frameworks/Python/aiohttp/requirements.txt index 91fb238338d..5763f8624a4 100644 --- a/frameworks/Python/aiohttp/requirements.txt +++ b/frameworks/Python/aiohttp/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.8.5 +aiohttp==3.8.6 asyncpg==0.25.0 cchardet==2.1.7 gunicorn==20.1 From 8a43748a1c5344e5464df32b40f730390e95cb51 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Mon, 27 Nov 2023 19:14:58 +0100 Subject: [PATCH 08/15] Update giraffe and zebra to .NET 8.0 (#8544) * Update giraffe to .NET 8.0 * Update zebra * No need for utf8json * No need for utf8json --- frameworks/FSharp/giraffe/README.md | 3 +-- .../FSharp/giraffe/benchmark_config.json | 18 ------------------ frameworks/FSharp/giraffe/config.toml | 12 ------------ .../giraffe/giraffe-newtonsoft.dockerfile | 8 ++++---- .../giraffe/giraffe-utf8json.dockerfile | 19 ------------------- frameworks/FSharp/giraffe/giraffe.dockerfile | 8 ++++---- frameworks/FSharp/giraffe/src/App/App.fsproj | 13 +++++-------- frameworks/FSharp/giraffe/src/App/Program.fs | 11 +++-------- frameworks/FSharp/zebra/README.md | 2 +- frameworks/FSharp/zebra/src/App/App.fsproj | 10 ++++------ .../FSharp/zebra/zebra-simple.dockerfile | 8 ++++---- frameworks/FSharp/zebra/zebra.dockerfile | 8 ++++---- 12 files changed, 30 insertions(+), 90 deletions(-) delete mode 100644 frameworks/FSharp/giraffe/giraffe-utf8json.dockerfile diff --git a/frameworks/FSharp/giraffe/README.md b/frameworks/FSharp/giraffe/README.md index b6a61090be7..fa4751bbda2 100644 --- a/frameworks/FSharp/giraffe/README.md +++ b/frameworks/FSharp/giraffe/README.md @@ -10,7 +10,7 @@ This application tests Giraffe in 3 modes: **Language** -* F# 6.0 +* F# 8.0 **Platforms** @@ -32,5 +32,4 @@ All source code is inside `Program.fs`. App listens for a single command line argument to pick the desired JSON implementation: - `system`: `System.Text.Json` - - `utf8`: `Utf8Json` - `newtonsoft`: `Newtonsoft.Json` diff --git a/frameworks/FSharp/giraffe/benchmark_config.json b/frameworks/FSharp/giraffe/benchmark_config.json index 8dc135e931c..4384822a751 100644 --- a/frameworks/FSharp/giraffe/benchmark_config.json +++ b/frameworks/FSharp/giraffe/benchmark_config.json @@ -22,24 +22,6 @@ "notes": "", "versus": "aspcore" }, - "utf8json": { - "json_url": "/json", - "port": 8080, - "approach": "Realistic", - "classification": "Micro", - "database": "None", - "framework": "giraffe", - "language": "F#", - "orm": "Raw", - "platform": ".NET", - "flavor": "CoreCLR", - "webserver": "Kestrel", - "os": "Linux", - "database_os": "Linux", - "display_name": "Giraffe, Utf8Json", - "notes": "", - "versus": "aspcore" - }, "newtonsoft": { "json_url": "/json", "port": 8080, diff --git a/frameworks/FSharp/giraffe/config.toml b/frameworks/FSharp/giraffe/config.toml index dfafd84d70d..15122b9ddba 100644 --- a/frameworks/FSharp/giraffe/config.toml +++ b/frameworks/FSharp/giraffe/config.toml @@ -26,15 +26,3 @@ orm = "Raw" platform = ".NET" webserver = "Kestrel" versus = "aspcore" - -[utf8json] -urls.json = "/json" -approach = "Realistic" -classification = "Micro" -database = "None" -database_os = "Linux" -os = "Linux" -orm = "Raw" -platform = ".NET" -webserver = "Kestrel" -versus = "aspcore" diff --git a/frameworks/FSharp/giraffe/giraffe-newtonsoft.dockerfile b/frameworks/FSharp/giraffe/giraffe-newtonsoft.dockerfile index e3b3ec0c3b5..b22de354452 100644 --- a/frameworks/FSharp/giraffe/giraffe-newtonsoft.dockerfile +++ b/frameworks/FSharp/giraffe/giraffe-newtonsoft.dockerfile @@ -1,14 +1,14 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build WORKDIR /app COPY src/App . RUN dotnet publish -c Release -o out -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime ENV ASPNETCORE_URLS http://+:8080 # Full PGO -ENV DOTNET_TieredPGO 1 -ENV DOTNET_TC_QuickJitForLoops 1 +ENV DOTNET_TieredPGO 1 +ENV DOTNET_TC_QuickJitForLoops 1 ENV DOTNET_ReadyToRun 0 WORKDIR /app diff --git a/frameworks/FSharp/giraffe/giraffe-utf8json.dockerfile b/frameworks/FSharp/giraffe/giraffe-utf8json.dockerfile deleted file mode 100644 index 52cbdae7283..00000000000 --- a/frameworks/FSharp/giraffe/giraffe-utf8json.dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build -WORKDIR /app -COPY src/App . -RUN dotnet publish -c Release -o out - -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime -ENV ASPNETCORE_URLS http://+:8080 - -# Full PGO -ENV DOTNET_TieredPGO 1 -ENV DOTNET_TC_QuickJitForLoops 1 -ENV DOTNET_ReadyToRun 0 - -WORKDIR /app -COPY --from=build /app/out ./ - -EXPOSE 8080 - -ENTRYPOINT ["dotnet", "App.dll", "utf8"] diff --git a/frameworks/FSharp/giraffe/giraffe.dockerfile b/frameworks/FSharp/giraffe/giraffe.dockerfile index 66b784eb8e0..b63044e65c2 100644 --- a/frameworks/FSharp/giraffe/giraffe.dockerfile +++ b/frameworks/FSharp/giraffe/giraffe.dockerfile @@ -1,14 +1,14 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build WORKDIR /app COPY src/App . RUN dotnet publish -c Release -o out -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime ENV ASPNETCORE_URLS http://+:8080 # Full PGO -ENV DOTNET_TieredPGO 1 -ENV DOTNET_TC_QuickJitForLoops 1 +ENV DOTNET_TieredPGO 1 +ENV DOTNET_TC_QuickJitForLoops 1 ENV DOTNET_ReadyToRun 0 WORKDIR /app diff --git a/frameworks/FSharp/giraffe/src/App/App.fsproj b/frameworks/FSharp/giraffe/src/App/App.fsproj index db327a4549e..bbdd52ee3af 100644 --- a/frameworks/FSharp/giraffe/src/App/App.fsproj +++ b/frameworks/FSharp/giraffe/src/App/App.fsproj @@ -1,18 +1,15 @@ - net7.0 + net8.0 false - - - true - - - - + + + + diff --git a/frameworks/FSharp/giraffe/src/App/Program.fs b/frameworks/FSharp/giraffe/src/App/Program.fs index 4967b043d06..ce8514699cd 100644 --- a/frameworks/FSharp/giraffe/src/App/Program.fs +++ b/frameworks/FSharp/giraffe/src/App/Program.fs @@ -17,7 +17,6 @@ module Common = type JsonMode = | System - | Utf8 | Newtonsoft let FortuneComparer = @@ -109,12 +108,11 @@ module Main = open Microsoft.Extensions.Hosting open Microsoft.Extensions.Logging - [] + [] let main args = let jsonMode = match args with | [| "newtonsoft" |] -> Newtonsoft - | [| "utf8" |] -> Utf8 | _ -> System printfn $"Running with %A{jsonMode} JSON serializer" @@ -124,9 +122,6 @@ module Main = | System -> SystemTextJson.Serializer(SystemTextJson.Serializer.DefaultOptions) :> Json.ISerializer - | Utf8 -> - Utf8Json.Serializer(Utf8Json.Serializer.DefaultResolver) - :> Json.ISerializer | Newtonsoft -> NewtonsoftJson.Serializer(NewtonsoftJson.Serializer.DefaultSettings) :> Json.ISerializer @@ -136,7 +131,7 @@ module Main = builder.Services .AddSingleton(jsonSerializer) .AddGiraffe() |> ignore - + builder.Logging.ClearProviders() |> ignore let app = builder.Build() @@ -145,5 +140,5 @@ module Main = .UseGiraffe HttpHandlers.endpoints |> ignore app.Run() - + 0 \ No newline at end of file diff --git a/frameworks/FSharp/zebra/README.md b/frameworks/FSharp/zebra/README.md index 744b571dba1..0dfe791d8cc 100644 --- a/frameworks/FSharp/zebra/README.md +++ b/frameworks/FSharp/zebra/README.md @@ -7,7 +7,7 @@ Zebra is a new F# functional Asp.net Framework Wrapper that utalises a shared st **Language** -* F# 6.0 +* F# 8.0 **Platforms** diff --git a/frameworks/FSharp/zebra/src/App/App.fsproj b/frameworks/FSharp/zebra/src/App/App.fsproj index 0b11a353111..87f9f551340 100644 --- a/frameworks/FSharp/zebra/src/App/App.fsproj +++ b/frameworks/FSharp/zebra/src/App/App.fsproj @@ -1,20 +1,18 @@  - net7.0 + net8.0 portable App Exe false - - true - - + + - + diff --git a/frameworks/FSharp/zebra/zebra-simple.dockerfile b/frameworks/FSharp/zebra/zebra-simple.dockerfile index 840dd1a2fdd..b02a6c8977f 100644 --- a/frameworks/FSharp/zebra/zebra-simple.dockerfile +++ b/frameworks/FSharp/zebra/zebra-simple.dockerfile @@ -1,12 +1,12 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build WORKDIR /app COPY src/App . RUN dotnet publish -c Release -o out -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime # Full PGO -ENV DOTNET_TieredPGO 1 -ENV DOTNET_TC_QuickJitForLoops 1 +ENV DOTNET_TieredPGO 1 +ENV DOTNET_TC_QuickJitForLoops 1 ENV DOTNET_ReadyToRun 0 ENV ASPNETCORE_URLS http://+:8080 diff --git a/frameworks/FSharp/zebra/zebra.dockerfile b/frameworks/FSharp/zebra/zebra.dockerfile index b0c2d9ec661..a43c8eb1c5c 100644 --- a/frameworks/FSharp/zebra/zebra.dockerfile +++ b/frameworks/FSharp/zebra/zebra.dockerfile @@ -1,12 +1,12 @@ -FROM mcr.microsoft.com/dotnet/sdk:7.0.100 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.100 AS build WORKDIR /app COPY src/App . RUN dotnet publish -c Release -o out -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime # Full PGO -ENV DOTNET_TieredPGO 1 -ENV DOTNET_TC_QuickJitForLoops 1 +ENV DOTNET_TieredPGO 1 +ENV DOTNET_TC_QuickJitForLoops 1 ENV DOTNET_ReadyToRun 0 ENV ASPNETCORE_URLS http://+:8080 From f01f4e5fec5ea2b0f10bc5fc04ad97787a7e3285 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Tue, 28 Nov 2023 00:44:49 +0600 Subject: [PATCH 09/15] ntex: set number of workers (#8569) --- frameworks/Rust/ntex/src/main.rs | 2 +- frameworks/Rust/ntex/src/main_db.rs | 2 +- frameworks/Rust/ntex/src/main_plt.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/Rust/ntex/src/main.rs b/frameworks/Rust/ntex/src/main.rs index 9fdbdf4c4c0..c9220d83247 100644 --- a/frameworks/Rust/ntex/src/main.rs +++ b/frameworks/Rust/ntex/src/main.rs @@ -58,7 +58,7 @@ async fn main() -> std::io::Result<()> { .client_timeout(Seconds(0)) .h1(web::App::new().service(json).service(plaintext).finish()) })? - .workers(num_cpus::get_physical()) + .workers(num_cpus::get()) .run() .await } diff --git a/frameworks/Rust/ntex/src/main_db.rs b/frameworks/Rust/ntex/src/main_db.rs index 14c37112faa..8354a41fd21 100644 --- a/frameworks/Rust/ntex/src/main_db.rs +++ b/frameworks/Rust/ntex/src/main_db.rs @@ -99,7 +99,7 @@ async fn main() -> std::io::Result<()> { .client_timeout(Seconds(0)) .h1(AppFactory) })? - .workers(num_cpus::get_physical()) + .workers(num_cpus::get()) .run() .await } diff --git a/frameworks/Rust/ntex/src/main_plt.rs b/frameworks/Rust/ntex/src/main_plt.rs index bf61ec71a87..4e9279d4ebf 100644 --- a/frameworks/Rust/ntex/src/main_plt.rs +++ b/frameworks/Rust/ntex/src/main_plt.rs @@ -87,7 +87,7 @@ async fn main() -> io::Result<()> { codec: h1::Codec::default(), }) })? - .workers(num_cpus::get_physical()) + .workers(num_cpus::get()) .run() .await } From a2f3f1011e96ea04ffe80d624b23da29f672c2f6 Mon Sep 17 00:00:00 2001 From: Anton Kirilov Date: Mon, 27 Nov 2023 20:45:00 +0200 Subject: [PATCH 10/15] H2O: Optimize the database updates test further (#8570) * H2O: Update dependencies * H2O: Optimize the database updates test further Use the same query as the faster implementations. --- frameworks/C/h2o/h2o.dockerfile | 8 ++--- frameworks/C/h2o/src/database.c | 8 ++--- frameworks/C/h2o/src/handlers/world.c | 47 +++++++++++++++++---------- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/frameworks/C/h2o/h2o.dockerfile b/frameworks/C/h2o/h2o.dockerfile index 7994b193949..8a04c410cac 100644 --- a/frameworks/C/h2o/h2o.dockerfile +++ b/frameworks/C/h2o/h2o.dockerfile @@ -46,7 +46,7 @@ RUN curl -LSs "https://github.com/h2o/h2o/archive/${H2O_VERSION}.tar.gz" | \ cmake --install build && \ cp -a deps/picotls/include/picotls* deps/quicly/include/quicly* /usr/local/include -ARG MUSTACHE_C_REVISION=c1948c599edfe48c6099ed70ab1d5911d8c3ddc8 +ARG MUSTACHE_C_REVISION=7fe52392879d0188c172d94bb4fde7c513d6b929 WORKDIR /tmp/mustache-c-build RUN curl -LSs "https://github.com/x86-64/mustache-c/archive/${MUSTACHE_C_REVISION}.tar.gz" | \ @@ -54,12 +54,12 @@ RUN curl -LSs "https://github.com/x86-64/mustache-c/archive/${MUSTACHE_C_REVISIO CFLAGS="-flto -march=native -mtune=native -O3" ./autogen.sh && \ make -j "$(nproc)" install -ARG POSTGRESQL_VERSION=7b7fa85130330128b404eddebd4f33c6739454b0 +ARG POSTGRESQL_VERSION=c1ec02be1d79eac95160dea7ced32ace84664617 WORKDIR /tmp/postgresql-build RUN curl -LSs "https://github.com/postgres/postgres/archive/${POSTGRESQL_VERSION}.tar.gz" | \ tar --strip-components=1 -xz && \ - curl -LSs "https://www.postgresql.org/message-id/attachment/146614/v2-0001-Add-PQsendSyncMessage-to-libpq.patch" | \ + curl -LSs "https://www.postgresql.org/message-id/attachment/152078/v5-0001-Add-PQsendPipelineSync-to-libpq.patch" | \ patch -Np1 && \ CFLAGS="-flto -march=native -mtune=native -O3" ./configure \ --includedir=/usr/local/include/postgresql \ @@ -92,7 +92,7 @@ RUN apt-get -yqq update && \ ARG H2O_APP_PREFIX COPY --from=compile "${H2O_APP_PREFIX}" "${H2O_APP_PREFIX}/" COPY --from=compile /usr/local/lib/libmustache_c.so "${H2O_APP_PREFIX}/lib/" -COPY --from=compile /usr/local/lib/libpq.so.5.16 "${H2O_APP_PREFIX}/lib/libpq.so.5" +COPY --from=compile /usr/local/lib/libpq.so.5.17 "${H2O_APP_PREFIX}/lib/libpq.so.5" ENV LD_LIBRARY_PATH="${H2O_APP_PREFIX}/lib" EXPOSE 8080 ARG BENCHMARK_ENV diff --git a/frameworks/C/h2o/src/database.c b/frameworks/C/h2o/src/database.c index 3cdc45913b6..59042b1dec3 100644 --- a/frameworks/C/h2o/src/database.c +++ b/frameworks/C/h2o/src/database.c @@ -135,8 +135,8 @@ static int do_execute_query(db_conn_t *conn, db_query_param_t *param) return 1; } - if (!PQsendSyncMessage(conn->conn)) { - LIBRARY_ERROR("PQsendSyncMessage", PQerrorMessage(conn->conn)); + if (!PQsendPipelineSync(conn->conn)) { + LIBRARY_ERROR("PQsendPipelineSync", PQerrorMessage(conn->conn)); return 1; } @@ -522,8 +522,8 @@ static void prepare_statements(db_conn_t *conn) iter = iter->next; } while (iter); - if (!PQsendSyncMessage(conn->conn)) { - LIBRARY_ERROR("PQsendSyncMessage", PQerrorMessage(conn->conn)); + if (!PQsendPipelineSync(conn->conn)) { + LIBRARY_ERROR("PQsendPipelineSync", PQerrorMessage(conn->conn)); on_database_connect_error(conn, false, DB_ERROR); return; } diff --git a/frameworks/C/h2o/src/handlers/world.c b/frameworks/C/h2o/src/handlers/world.c index da4188ca3eb..0a7aaf1d813 100644 --- a/frameworks/C/h2o/src/handlers/world.c +++ b/frameworks/C/h2o/src/handlers/world.c @@ -55,18 +55,18 @@ #define RANDOM_NUM_KEY "randomNumber" // MAX_UPDATE_QUERY_LEN must be updated whenever UPDATE_QUERY_BEGIN, UPDATE_QUERY_ELEM, -// and UPDATE_QUERY_END are changed. -#define UPDATE_QUERY_BEGIN \ - "UPDATE " WORLD_TABLE_NAME " SET randomNumber = v.randomNumber " \ - "FROM (VALUES(%" PRIu32 ", %" PRIu32 ")" - -#define UPDATE_QUERY_ELEM ", (%" PRIu32 ", %" PRIu32 ")" -#define UPDATE_QUERY_END ") AS v (id, randomNumber) WHERE " WORLD_TABLE_NAME ".id = v.id;" +// UPDATE_QUERY_MIDDLE, UPDATE_QUERY_ELEM2, and UPDATE_QUERY_END are changed. +#define UPDATE_QUERY_BEGIN "UPDATE " WORLD_TABLE_NAME " SET randomNumber = CASE id " +#define UPDATE_QUERY_ELEM "WHEN %" PRIu32 " THEN %" PRIu32 " " +#define UPDATE_QUERY_MIDDLE "ELSE randomNumber END WHERE id IN (%" PRIu32 +#define UPDATE_QUERY_ELEM2 ",%" PRIu32 +#define UPDATE_QUERY_END ");" #define MAX_UPDATE_QUERY_LEN(n) \ - (sizeof(UPDATE_QUERY_BEGIN) + sizeof(UPDATE_QUERY_END) - sizeof(UPDATE_QUERY_ELEM) + \ - (n) * (sizeof(UPDATE_QUERY_ELEM) - 1 + \ - 2 * (sizeof(MKSTR(MAX_ID)) - 1) - 2 * (sizeof(PRIu32) - 1) - 2)) + (sizeof(UPDATE_QUERY_BEGIN) + sizeof(UPDATE_QUERY_MIDDLE) + \ + sizeof(UPDATE_QUERY_END) - 1 - sizeof(UPDATE_QUERY_ELEM2) + \ + (n) * (sizeof(UPDATE_QUERY_ELEM) - 1 + sizeof(UPDATE_QUERY_ELEM2) - 1 + \ + 3 * (sizeof(MKSTR(MAX_ID)) - 1) - 3 * (sizeof(PRIu32) - 1) - 3)) #define USE_CACHE 2 #define WORLD_QUERY "SELECT * FROM " WORLD_TABLE_NAME " WHERE id = $1::integer;" @@ -336,13 +336,8 @@ static void do_updates(multiple_query_ctx_t *query_ctx) query_ctx->query_param->param.paramLengths = NULL; query_ctx->query_param->param.paramValues = NULL; query_ctx->query_param->param.flags = 0; - query_ctx->res->random_number = 1 + get_random_number(MAX_ID, &query_ctx->ctx->random_seed); - int c = snprintf(iter, - sz, - UPDATE_QUERY_BEGIN, - query_ctx->res->id, - query_ctx->res->random_number); + int c = snprintf(iter, sz, UPDATE_QUERY_BEGIN); if ((size_t) c >= sz) goto error; @@ -350,7 +345,7 @@ static void do_updates(multiple_query_ctx_t *query_ctx) iter += c; sz -= c; - for (size_t i = 1; i < query_ctx->num_result; i++) { + for (size_t i = 0; i < query_ctx->num_result; i++) { query_ctx->res[i].random_number = 1 + get_random_number(MAX_ID, &query_ctx->ctx->random_seed); c = snprintf(iter, @@ -366,6 +361,24 @@ static void do_updates(multiple_query_ctx_t *query_ctx) sz -= c; } + c = snprintf(iter, sz, UPDATE_QUERY_MIDDLE, query_ctx->res->id); + + if ((size_t) c >= sz) + goto error; + + iter += c; + sz -= c; + + for (size_t i = 1; i < query_ctx->num_result; i++) { + c = snprintf(iter, sz, UPDATE_QUERY_ELEM2, query_ctx->res[i].id); + + if ((size_t) c >= sz) + goto error; + + iter += c; + sz -= c; + } + c = snprintf(iter, sz, UPDATE_QUERY_END); if ((size_t) c >= sz) From 38feded9a18912043a6b797aef67121d8c9bab76 Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Tue, 28 Nov 2023 03:44:44 +0800 Subject: [PATCH 11/15] [xitca-web] add xitca-web-axum bench. (#8567) * [xitca-web] add xitca-web-axum bench. * revert to nightly toolchain. * avoid boxing response body. --- frameworks/Rust/xitca-web/Cargo.lock | 407 +++++++++++++++--- frameworks/Rust/xitca-web/Cargo.toml | 32 +- .../Rust/xitca-web/benchmark_config.json | 18 + frameworks/Rust/xitca-web/rust-toolchain.toml | 2 +- frameworks/Rust/xitca-web/src/main.rs | 39 +- frameworks/Rust/xitca-web/src/main_axum.rs | 189 ++++++++ frameworks/Rust/xitca-web/src/main_iou.rs | 21 +- frameworks/Rust/xitca-web/src/main_wasm.rs | 34 +- frameworks/Rust/xitca-web/src/util.rs | 2 + .../Rust/xitca-web/xitca-web-axum.dockerfile | 10 + .../Rust/xitca-web/xitca-web-wasm.dockerfile | 13 +- 11 files changed, 642 insertions(+), 125 deletions(-) create mode 100644 frameworks/Rust/xitca-web/src/main_axum.rs create mode 100644 frameworks/Rust/xitca-web/xitca-web-axum.dockerfile diff --git a/frameworks/Rust/xitca-web/Cargo.lock b/frameworks/Rust/xitca-web/Cargo.lock index 9859419378d..6a87ff4b1fb 100644 --- a/frameworks/Rust/xitca-web/Cargo.lock +++ b/frameworks/Rust/xitca-web/Cargo.lock @@ -17,6 +17,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atoi" version = "2.0.0" @@ -32,6 +43,55 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -49,9 +109,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bitflags" @@ -59,6 +119,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "block-buffer" version = "0.10.4" @@ -97,9 +163,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -155,11 +221,47 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-task" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] [[package]] name = "generic-array" @@ -173,9 +275,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -184,9 +286,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "hermit-abi" @@ -214,15 +316,32 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", "itoa", ] +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + [[package]] name = "httparse" version = "1.8.0" @@ -235,13 +354,36 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "io-uring" version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd1e1a01cfb924fd8c5c43b6827965db394f5a3a16c599ce03452266e1cf984c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", ] @@ -259,9 +401,9 @@ checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libmimalloc-sys" @@ -273,6 +415,18 @@ dependencies = [ "libc", ] +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "md-5" version = "0.10.6" @@ -298,6 +452,12 @@ dependencies = [ "libmimalloc-sys", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -309,8 +469,8 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" -source = "git+https://github.com/fakeshadow/mio.git?rev=eb67f6794edba8bc2e973ddef32e066b41ff812a#eb67f6794edba8bc2e973ddef32e066b41ff812a" +version = "0.8.9" +source = "git+https://github.com/fakeshadow/mio.git?rev=52b72d372bfe5807755b7f5e3e1edf282954d6ba#52b72d372bfe5807755b7f5e3e1edf282954d6ba" dependencies = [ "libc", "wasi", @@ -351,11 +511,37 @@ dependencies = [ "memchr", ] +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "pin-project-lite" @@ -363,6 +549,12 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "postgres-protocol" version = "0.6.6" @@ -400,9 +592,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -452,7 +644,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -461,6 +653,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" version = "1.0.15" @@ -469,9 +667,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sailfish" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7861181faa2e413410444757deca246c70959cee725fbfd8f736a94a660eb377" +checksum = "acd5f4680149b62b3478f6af08a8f1c37794bc1bc577e28874a4d0c70084d600" dependencies = [ "itoap", "ryu", @@ -481,9 +679,9 @@ dependencies = [ [[package]] name = "sailfish-compiler" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c38d77ced03b393e820ac70109857bd857f93e746f5d7d631829c9ee2e4f3fa" +checksum = "67087aca4a3886686a88cee6835089c53e6143a0b8c5be01e63e4fe2f6dfe7cb" dependencies = [ "filetime", "home", @@ -495,9 +693,9 @@ dependencies = [ [[package]] name = "sailfish-macros" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8f73db14456f861a5c89166ab6ac76afd94b4d2a9416638ae2952ae051089c5" +checksum = "e47e31910c5f9230e99992568d05a5968fe4f42a635c3f912c993e9f66a619a5" dependencies = [ "proc-macro2", "sailfish-compiler", @@ -511,18 +709,18 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -531,10 +729,32 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ + "form_urlencoded", "itoa", "ryu", "serde", @@ -571,9 +791,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -581,9 +801,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys", @@ -608,15 +828,21 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "tinyvec" version = "1.6.0" @@ -634,9 +860,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "libc", @@ -644,7 +870,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.5", "windows-sys", ] @@ -659,16 +885,63 @@ dependencies = [ "libc", "scoped-tls", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "bitflags 2.4.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-core", ] @@ -678,6 +951,15 @@ name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typenum" @@ -712,6 +994,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -809,7 +1100,7 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "xitca-http" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ "futures-core", "http", @@ -817,7 +1108,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.4", + "socket2 0.5.5", "tokio", "tokio-uring", "tracing", @@ -830,7 +1121,7 @@ dependencies = [ [[package]] name = "xitca-io" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ "bytes", "tokio", @@ -841,7 +1132,7 @@ dependencies = [ [[package]] name = "xitca-postgres" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ "fallible-iterator", "percent-encoding", @@ -857,7 +1148,7 @@ dependencies = [ [[package]] name = "xitca-router" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ "xitca-unsafe-collection", ] @@ -865,9 +1156,9 @@ dependencies = [ [[package]] name = "xitca-server" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ - "socket2 0.5.4", + "socket2 0.5.5", "tokio", "tokio-uring", "tracing", @@ -879,12 +1170,12 @@ dependencies = [ [[package]] name = "xitca-service" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" [[package]] name = "xitca-unsafe-collection" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ "bytes", ] @@ -894,31 +1185,37 @@ name = "xitca-web" version = "0.1.0" dependencies = [ "atoi", + "axum", "futures-core", + "http-body", "mimalloc", "nanorand", + "pin-project-lite", "sailfish", "serde", "serde_json", "tokio", + "tower", + "tower-http", "xitca-http", "xitca-io", "xitca-postgres", "xitca-server", "xitca-service", "xitca-unsafe-collection", - "xitca-web 0.1.0 (git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a)", + "xitca-web 0.1.0 (git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e)", ] [[package]] name = "xitca-web" version = "0.1.0" -source = "git+https://github.com/HFQR/xitca-web.git?rev=c0b85dfef6cb7917c36b8422de28a0beaaf4404a#c0b85dfef6cb7917c36b8422de28a0beaaf4404a" +source = "git+https://github.com/HFQR/xitca-web.git?rev=23ad63cbb3a853a548bd447cc59625a5d7c5833e#23ad63cbb3a853a548bd447cc59625a5d7c5833e" dependencies = [ "futures-core", "pin-project-lite", "serde", "serde_json", + "tokio", "xitca-http", "xitca-server", "xitca-service", diff --git a/frameworks/Rust/xitca-web/Cargo.toml b/frameworks/Rust/xitca-web/Cargo.toml index 8c585273bbe..10af08ac491 100644 --- a/frameworks/Rust/xitca-web/Cargo.toml +++ b/frameworks/Rust/xitca-web/Cargo.toml @@ -18,6 +18,11 @@ name = "xitca-web-wasm" path = "./src/main_wasm.rs" required-features = ["web"] +[[bin]] +name = "xitca-web-axum" +path = "./src/main_axum.rs" +required-features = ["axum", "io-uring"] + [features] # pg optional pg = ["xitca-postgres"] @@ -31,6 +36,8 @@ web = ["xitca-web"] template = ["sailfish"] # io-uring optional io-uring = ["xitca-http/io-uring", "xitca-server/io-uring"] +# axum optional +axum = ["dep:axum", "http-body", "pin-project-lite", "tower", "tower-http"] [dependencies] xitca-http = "0.1" @@ -52,6 +59,13 @@ xitca-postgres = { version = "0.1", features = ["single-thread"], optional = tru # template optional sailfish = { version = "0.8", default-features = false, features = ["derive", "perf-inline"], optional = true } +# axum optional +axum = { version = "0.6", optional = true } +http-body = { version = "0.4", optional = true } +pin-project-lite = { version = "0.2", optional = true } +tower = { version = "0.4", optional = true } +tower-http = { version = "0.4", features = ["set-header"], optional = true } + # stuff can not be used or not needed in wasi target [target.'cfg(not(target_family = "wasm"))'.dependencies] futures-core = { version = "0.3", default-features = false } @@ -66,13 +80,13 @@ codegen-units = 1 panic = "abort" [patch.crates-io] -xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-router = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } -xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "c0b85dfef6cb7917c36b8422de28a0beaaf4404a" } +xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-router = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } +xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "23ad63cbb3a853a548bd447cc59625a5d7c5833e" } -mio = { git = "https://github.com/fakeshadow/mio.git", rev = "eb67f6794edba8bc2e973ddef32e066b41ff812a" } +mio = { git = "https://github.com/fakeshadow/mio.git", rev = "52b72d372bfe5807755b7f5e3e1edf282954d6ba" } diff --git a/frameworks/Rust/xitca-web/benchmark_config.json b/frameworks/Rust/xitca-web/benchmark_config.json index 4c4ab0e4462..060cb47b354 100755 --- a/frameworks/Rust/xitca-web/benchmark_config.json +++ b/frameworks/Rust/xitca-web/benchmark_config.json @@ -63,6 +63,24 @@ "display_name": "xitca-web [wasm]", "notes": "", "versus": "" + }, + "axum": { + "json_url": "/json", + "plaintext_url": "/plaintext", + "port": 8080, + "approach": "Realistic", + "classification": "Micro", + "database": "none", + "framework": "axum [xitca]", + "language": "rust", + "orm": "raw", + "platform": "none", + "webserver": "xitca-server", + "os": "linux", + "database_os": "linux", + "display_name": "axum [xitca]", + "notes": "", + "versus": "" } } ] diff --git a/frameworks/Rust/xitca-web/rust-toolchain.toml b/frameworks/Rust/xitca-web/rust-toolchain.toml index 310b53dbfd1..3191ef83ece 100644 --- a/frameworks/Rust/xitca-web/rust-toolchain.toml +++ b/frameworks/Rust/xitca-web/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2023-10-19" +channel = "nightly-2023-11-24" diff --git a/frameworks/Rust/xitca-web/src/main.rs b/frameworks/Rust/xitca-web/src/main.rs index 0d4b226943e..2bc0d5fc720 100755 --- a/frameworks/Rust/xitca-web/src/main.rs +++ b/frameworks/Rust/xitca-web/src/main.rs @@ -8,7 +8,6 @@ mod util; use xitca_http::{ body::Once, bytes::Bytes, - config::HttpServiceConfig, h1::RequestBody, http::{ self, @@ -31,23 +30,19 @@ type Request = http::Request>; type Ctx<'a> = self::util::Ctx<'a, Request>; fn main() -> std::io::Result<()> { + let service = Router::new() + .insert("/plaintext", get(fn_service(plain_text))) + .insert("/json", get(fn_service(json))) + .insert("/db", get(fn_service(db))) + .insert("/fortunes", get(fn_service(fortunes))) + .insert("/queries", get(fn_service(queries))) + .insert("/updates", get(fn_service(updates))) + .enclosed_fn(middleware_fn) + .enclosed(context_mw()) + .enclosed(HttpServiceBuilder::h1().io_uring()); + xitca_server::Builder::new() - .bind("xitca-web", "0.0.0.0:8080", || { - Router::new() - .insert("/plaintext", get(fn_service(plain_text))) - .insert("/json", get(fn_service(json))) - .insert("/db", get(fn_service(db))) - .insert("/fortunes", get(fn_service(fortunes))) - .insert("/queries", get(fn_service(queries))) - .insert("/updates", get(fn_service(updates))) - .enclosed_fn(middleware_fn) - .enclosed(context_mw()) - .enclosed( - HttpServiceBuilder::h1() - .io_uring() - .config(HttpServiceConfig::new().max_request_headers::<8>()), - ) - })? + .bind("xitca-web", "0.0.0.0:8080", service)? .build() .wait() } @@ -57,17 +52,15 @@ where S: for<'c> Service, Response = Response, Error = E>, { service.call(req).await.map(|mut res| { - res.headers_mut().append(SERVER, SERVER_HEADER_VALUE); + res.headers_mut().insert(SERVER, SERVER_HEADER_VALUE); res }) } -const HELLO: Bytes = Bytes::from_static(b"Hello, World!"); - async fn plain_text(ctx: Ctx<'_>) -> HandleResult { let (req, _) = ctx.into_parts(); - let mut res = req.into_response(HELLO); - res.headers_mut().append(CONTENT_TYPE, TEXT); + let mut res = req.into_response(Bytes::from_static(b"Hello, World!")); + res.headers_mut().insert(CONTENT_TYPE, TEXT); Ok(res) } @@ -87,7 +80,7 @@ async fn fortunes(ctx: Ctx<'_>) -> HandleResult { use sailfish::TemplateOnce; let fortunes = state.client.tell_fortune().await?.render_once()?; let mut res = req.into_response(Bytes::from(fortunes)); - res.headers_mut().append(CONTENT_TYPE, TEXT_HTML_UTF8); + res.headers_mut().insert(CONTENT_TYPE, TEXT_HTML_UTF8); Ok(res) } diff --git a/frameworks/Rust/xitca-web/src/main_axum.rs b/frameworks/Rust/xitca-web/src/main_axum.rs new file mode 100644 index 00000000000..1345569126d --- /dev/null +++ b/frameworks/Rust/xitca-web/src/main_axum.rs @@ -0,0 +1,189 @@ +//! show case of axum running on proper thread per core server with io-uring enabled. + +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; + +mod ser; +mod util; + +use axum::{ + http::header::{HeaderValue, SERVER}, + response::IntoResponse, + routing::{get, Router}, + Json, +}; +use tower_http::set_header::SetResponseHeaderLayer; + +use crate::tower_compat::TowerHttp; + +fn main() -> std::io::Result<()> { + let service = TowerHttp::service(|| async { + Router::new() + .route("/plaintext", get(plain_text)) + .route("/json", get(json)) + .layer(SetResponseHeaderLayer::if_not_present( + SERVER, + HeaderValue::from_static("A"), + )) + }); + + xitca_server::Builder::new() + .bind("xitca-axum", "0.0.0.0:8080", service)? + .build() + .wait() +} + +async fn plain_text() -> &'static str { + "Hello, World!" +} + +async fn json() -> impl IntoResponse { + Json(ser::Message::new()) +} + +mod tower_compat { + use std::{ + cell::RefCell, + convert::Infallible, + error, fmt, + future::Future, + io, + marker::PhantomData, + net::SocketAddr, + pin::Pin, + task::{Context, Poll}, + }; + + use axum::extract::ConnectInfo; + use futures_core::stream::Stream; + use http_body::Body; + use pin_project_lite::pin_project; + use xitca_http::{ + body::none_body_hint, + bytes::Bytes, + h1::RequestBody, + http::{HeaderMap, Request, RequestExt, Response}, + BodyError, HttpServiceBuilder, + }; + use xitca_io::net::io_uring::TcpStream; + use xitca_service::{ + fn_build, middleware::UncheckedReady, ready::ReadyService, Service, ServiceExt, + }; + use xitca_unsafe_collection::fake_send_sync::FakeSend; + + pub struct TowerHttp { + service: RefCell, + _p: PhantomData, + } + + impl TowerHttp { + pub fn service( + service: F, + ) -> impl Service< + Response = impl ReadyService + Service<(TcpStream, SocketAddr)>, + Error = impl fmt::Debug, + > + where + F: Fn() -> Fut + Send + Sync + Clone, + Fut: Future, + S: tower::Service, Response = Response>, + S::Error: fmt::Debug, + B: Body + Send + 'static, + B::Error: error::Error + Send + Sync, + { + fn_build(move |_| { + let service = service.clone(); + async move { + let service = service().await; + Ok::<_, Infallible>(TowerHttp { + service: RefCell::new(service), + _p: PhantomData, + }) + } + }) + .enclosed(UncheckedReady) + .enclosed(HttpServiceBuilder::h1().io_uring()) + } + } + + impl Service>> for TowerHttp + where + S: tower::Service, Response = Response>, + B: Body + Send + 'static, + B::Error: error::Error + Send + Sync, + { + type Response = Response>; + type Error = S::Error; + + async fn call( + &self, + req: Request>, + ) -> Result { + let (parts, ext) = req.into_parts(); + let (ext, body) = ext.replace_body(()); + let body = _RequestBody { + body: FakeSend::new(body), + }; + let mut req = Request::from_parts(parts, body); + let _ = req.extensions_mut().insert(ConnectInfo(*ext.socket_addr())); + let fut = self.service.borrow_mut().call(req); + let (parts, body) = fut.await?.into_parts(); + let body = ResponseBody { body }; + let res = Response::from_parts(parts, body); + Ok(res) + } + } + + pub struct _RequestBody { + body: FakeSend, + } + + impl Body for _RequestBody { + type Data = Bytes; + type Error = io::Error; + + fn poll_data( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + Pin::new(&mut *self.get_mut().body).poll_next(cx) + } + + fn poll_trailers( + self: Pin<&mut Self>, + _: &mut Context<'_>, + ) -> Poll, Self::Error>> { + Poll::Ready(Ok(None)) + } + } + + pin_project! { + pub struct ResponseBody { + #[pin] + body: B + } + } + + impl Stream for ResponseBody + where + B: Body, + B::Error: error::Error + Send + Sync + 'static, + { + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project() + .body + .poll_data(cx) + .map_err(|e| BodyError::from(Box::new(e) as Box)) + } + + fn size_hint(&self) -> (usize, Option) { + if Body::is_end_stream(&self.body) { + return none_body_hint(); + } + let hint = Body::size_hint(&self.body); + (hint.lower() as _, hint.upper().map(|u| u as _)) + } + } +} diff --git a/frameworks/Rust/xitca-web/src/main_iou.rs b/frameworks/Rust/xitca-web/src/main_iou.rs index b119933e819..7aaa784cef1 100644 --- a/frameworks/Rust/xitca-web/src/main_iou.rs +++ b/frameworks/Rust/xitca-web/src/main_iou.rs @@ -38,18 +38,17 @@ type Request = http::Request>; type Response = http::Response>; fn main() -> io::Result<()> { + let service = fn_service(handler) + .enclosed(context_mw()) + .enclosed(fn_build(|service| async { + Ok::<_, Infallible>(Http1IOU { + service, + date: DateTimeService::new(), + }) + })) + .enclosed(UncheckedReady); xitca_server::Builder::new() - .bind("xitca-iou", "0.0.0.0:8080", || { - fn_service(handler) - .enclosed(context_mw()) - .enclosed(fn_build(|service| async { - Ok::<_, Infallible>(Http1IOU { - service, - date: DateTimeService::new(), - }) - })) - .enclosed(UncheckedReady) - })? + .bind("xitca-iou", "0.0.0.0:8080", service)? .build() .wait() } diff --git a/frameworks/Rust/xitca-web/src/main_wasm.rs b/frameworks/Rust/xitca-web/src/main_wasm.rs index cbae01e89c9..f9961afb6ce 100644 --- a/frameworks/Rust/xitca-web/src/main_wasm.rs +++ b/frameworks/Rust/xitca-web/src/main_wasm.rs @@ -10,7 +10,7 @@ use xitca_web::{ request::WebRequest, response::WebResponse, route::get, - App, HttpServer, + App, }; use self::util::SERVER_HEADER_VALUE; @@ -23,24 +23,20 @@ fn main() -> io::Result<()> { let listener = unsafe { TcpListener::from_raw_fd(fd) }; - HttpServer::new(|| { - App::new() - .at( - "/json", - get(handler_service(|| async { - Json::(ser::Message::new()) - })), - ) - .at( - "/plaintext", - get(handler_service(|| async { "Hello, World!" })), - ) - .enclosed_fn(middleware_fn) - .finish() - }) - .listen(listener)? - .run() - .wait() + App::new() + .at( + "/json", + get(handler_service(|| async { Json(ser::Message::new()) })), + ) + .at( + "/plaintext", + get(handler_service(|| async { "Hello, World!" })), + ) + .enclosed_fn(middleware_fn) + .serve() + .listen(listener)? + .run() + .wait() } async fn middleware_fn(service: &S, ctx: WebRequest<'_>) -> Result diff --git a/frameworks/Rust/xitca-web/src/util.rs b/frameworks/Rust/xitca-web/src/util.rs index 624b5dcfa95..e9bc8695bd0 100755 --- a/frameworks/Rust/xitca-web/src/util.rs +++ b/frameworks/Rust/xitca-web/src/util.rs @@ -30,6 +30,7 @@ pub type Error = Box; pub type HandleResult = Result; #[cfg(not(target_arch = "wasm32"))] +#[cfg(any(feature = "pg", feature = "pg-iou"))] mod non_wasm { use core::{cell::RefCell, future::Future, pin::Pin}; @@ -76,4 +77,5 @@ mod non_wasm { } #[cfg(not(target_arch = "wasm32"))] +#[cfg(any(feature = "pg", feature = "pg-iou"))] pub use non_wasm::*; diff --git a/frameworks/Rust/xitca-web/xitca-web-axum.dockerfile b/frameworks/Rust/xitca-web/xitca-web-axum.dockerfile new file mode 100644 index 00000000000..7c45bef27fb --- /dev/null +++ b/frameworks/Rust/xitca-web/xitca-web-axum.dockerfile @@ -0,0 +1,10 @@ +FROM rust:1.74 + +ADD ./ /xitca-web +WORKDIR /xitca-web + +RUN cargo build --release --bin xitca-web-axum --features axum,io-uring + +EXPOSE 8080 + +CMD ./target/release/xitca-web-axum diff --git a/frameworks/Rust/xitca-web/xitca-web-wasm.dockerfile b/frameworks/Rust/xitca-web/xitca-web-wasm.dockerfile index c11863f4443..08b43318c88 100644 --- a/frameworks/Rust/xitca-web/xitca-web-wasm.dockerfile +++ b/frameworks/Rust/xitca-web/xitca-web-wasm.dockerfile @@ -1,7 +1,7 @@ -ARG WASMTIME_VERSION=12.0.1 +ARG WASMTIME_VERSION=15.0.0 ARG WASM_TARGET=wasm32-wasi-preview1-threads -FROM rust:1.67 AS compile +FROM rust:1.74 AS compile ARG WASMTIME_VERSION ARG WASM_TARGET @@ -27,9 +27,8 @@ COPY --from=compile \ /opt/xitca-web-wasm/ EXPOSE 8080 -CMD /opt/xitca-web-wasm/wasmtime run /opt/xitca-web-wasm/xitca-web-wasm.wasm \ ---wasm-features=threads \ ---wasi-modules experimental-wasi-threads \ ---allow-precompiled \ +CMD /opt/xitca-web-wasm/wasmtime run \ +--wasm all-proposals=y \ +--wasi threads=y,tcplisten=0.0.0.0:8080 \ --env FD_COUNT=3 \ ---tcplisten 0.0.0.0:8080 +/opt/xitca-web-wasm/xitca-web-wasm.wasm From 428396717ff207b9bceff401c334278d3b336abd Mon Sep 17 00:00:00 2001 From: David Denton Date: Mon, 27 Nov 2023 23:22:09 +0000 Subject: [PATCH 12/15] Improve performance of update query in pgclient (#8564) --- .../src/main/kotlin/PostgresDatabase.kt | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/frameworks/Kotlin/http4k/core-pgclient/src/main/kotlin/PostgresDatabase.kt b/frameworks/Kotlin/http4k/core-pgclient/src/main/kotlin/PostgresDatabase.kt index 936dd020a7e..e9b55d4c177 100644 --- a/frameworks/Kotlin/http4k/core-pgclient/src/main/kotlin/PostgresDatabase.kt +++ b/frameworks/Kotlin/http4k/core-pgclient/src/main/kotlin/PostgresDatabase.kt @@ -1,4 +1,3 @@ -import io.vertx.core.CompositeFuture import io.vertx.core.Future import io.vertx.core.Vertx import io.vertx.core.VertxOptions @@ -46,17 +45,17 @@ class PostgresDatabase : Database { (1..count).map { queryPool.findWorld(random.world()) } ).toCompletionStage().toCompletableFuture().get().list() - override fun updateWorlds(count: Int) = - Future.all((1..count) - .map { queryPool.findWorld(random.world()) }) - .map>(CompositeFuture::list) - .toCompletionStage() - .thenCompose { worlds -> - updatePool.preparedQuery("UPDATE world SET randomnumber = $1 WHERE id = $2") - .executeBatch((1..count).map { Tuple.of(random.world(), random.world()) }) - .toCompletionStage() - .thenApply { worlds } - }.toCompletableFuture().get() + override fun updateWorlds(count: Int) = (1..count).map { + queryPool.findWorld(random.world()) + .flatMap { world -> + updatePool.preparedQuery("UPDATE world SET randomnumber = $1 WHERE id = $2") + .execute(Tuple.of(random.world(), world.first)) + .map { world } + } + .toCompletionStage() + .toCompletableFuture() + .get() + } override fun fortunes() = queryPool.preparedQuery("SELECT id, message FROM fortune") .execute() From 545483082be4d840459150405a6912963ce83a8d Mon Sep 17 00:00:00 2001 From: itrofimow Date: Tue, 28 Nov 2023 02:22:30 +0300 Subject: [PATCH 13/15] [C++] [userver] bump userver commit, optimize fortunes (#8549) * [C++] [userver] Do less logging-related work in PG queries * don't validate parameters in queries * optimizes fortunes: no need to copy strings, string_view would do * + clang-format * up userver commit * up userver commit --- frameworks/C++/userver/userver-bare.dockerfile | 2 +- frameworks/C++/userver/userver.dockerfile | 2 +- .../userver_benchmark/common/db_helpers.cpp | 7 +++++++ .../userver_benchmark/common/db_helpers.hpp | 9 +++++++-- .../controllers/fortunes/handler.cpp | 15 ++++++++------- .../controllers/updates/handler.cpp | 2 +- .../userver/userver_configs/static_config.yaml | 7 ++++--- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/frameworks/C++/userver/userver-bare.dockerfile b/frameworks/C++/userver/userver-bare.dockerfile index 1653e9d2da5..4b1210c8fe2 100644 --- a/frameworks/C++/userver/userver-bare.dockerfile +++ b/frameworks/C++/userver/userver-bare.dockerfile @@ -6,7 +6,7 @@ RUN apt update && \ WORKDIR /src RUN git clone https://github.com/userver-framework/userver.git && \ - cd userver && git checkout 73727ce95d24f18651fc018c45f50c492f858027 + cd userver && git checkout 781169b63bdbc012f7d98ed045bff75ff1b0b70d COPY userver_benchmark/ ./ RUN mkdir build && cd build && \ cmake -DUSERVER_IS_THE_ROOT_PROJECT=0 -DUSERVER_FEATURE_CRYPTOPP_BLAKE2=0 \ diff --git a/frameworks/C++/userver/userver.dockerfile b/frameworks/C++/userver/userver.dockerfile index a2a0df955ae..0c39abe0130 100644 --- a/frameworks/C++/userver/userver.dockerfile +++ b/frameworks/C++/userver/userver.dockerfile @@ -6,7 +6,7 @@ RUN apt update && \ WORKDIR /src RUN git clone https://github.com/userver-framework/userver.git && \ - cd userver && git checkout 73727ce95d24f18651fc018c45f50c492f858027 + cd userver && git checkout 781169b63bdbc012f7d98ed045bff75ff1b0b70d COPY userver_benchmark/ ./ RUN mkdir build && cd build && \ cmake -DUSERVER_IS_THE_ROOT_PROJECT=0 -DUSERVER_FEATURE_CRYPTOPP_BLAKE2=0 \ diff --git a/frameworks/C++/userver/userver_benchmark/common/db_helpers.cpp b/frameworks/C++/userver/userver_benchmark/common/db_helpers.cpp index 9aaa6cbc6ae..899a2aaa87c 100644 --- a/frameworks/C++/userver/userver_benchmark/common/db_helpers.cpp +++ b/frameworks/C++/userver/userver_benchmark/common/db_helpers.cpp @@ -27,6 +27,13 @@ int ParseFromQueryVal(std::string_view query_val) { } // namespace +userver::storages::postgres::Query CreateNonLoggingQuery( + std::string statement) { + return userver::storages::postgres::Query{ + statement, std::nullopt /* name */, + userver::storages::postgres::Query::LogMode::kNameOnly}; +} + int GenerateRandomId() { return userver::utils::RandRange(1, kMaxWorldRows + 1); } diff --git a/frameworks/C++/userver/userver_benchmark/common/db_helpers.hpp b/frameworks/C++/userver/userver_benchmark/common/db_helpers.hpp index ae31d13a226..a4325c3b0fa 100644 --- a/frameworks/C++/userver/userver_benchmark/common/db_helpers.hpp +++ b/frameworks/C++/userver/userver_benchmark/common/db_helpers.hpp @@ -8,11 +8,16 @@ namespace userver_techempower::db_helpers { +userver::storages::postgres::Query CreateNonLoggingQuery(std::string statement); + constexpr int kMaxWorldRows = 10000; -const userver::storages::postgres::Query kSelectRowQuery{ - "SELECT id, randomNumber FROM World WHERE id = $1"}; + +const userver::storages::postgres::Query kSelectRowQuery = + CreateNonLoggingQuery("SELECT id, randomNumber FROM World WHERE id = $1"); + constexpr auto kClusterHostType = userver::storages::postgres::ClusterHostType::kMaster; + constexpr std::string_view kDbComponentName = "hello-world-db"; struct WorldTableRow final { diff --git a/frameworks/C++/userver/userver_benchmark/controllers/fortunes/handler.cpp b/frameworks/C++/userver/userver_benchmark/controllers/fortunes/handler.cpp index 9c09939f0ab..4c7619bc86d 100644 --- a/frameworks/C++/userver/userver_benchmark/controllers/fortunes/handler.cpp +++ b/frameworks/C++/userver/userver_benchmark/controllers/fortunes/handler.cpp @@ -14,7 +14,7 @@ const std::string kContentTypeTextHtml{"text/html; charset=utf-8"}; struct Fortune final { int id; - std::string message; + std::string_view message; }; constexpr std::string_view kResultingHtmlHeader{ @@ -133,7 +133,8 @@ Handler::Handler(const userver::components::ComponentConfig& config, .FindComponent( db_helpers::kDbComponentName) .GetCluster()}, - select_all_fortunes_query_{"SELECT id, message FROM Fortune"}, + select_all_fortunes_query_{ + db_helpers::CreateNonLoggingQuery("SELECT id, message FROM Fortune")}, semaphore_{kBestConcurrencyWildGuess} {} std::string Handler::HandleRequestThrow( @@ -144,14 +145,14 @@ std::string Handler::HandleRequestThrow( } std::string Handler::GetResponse() const { - auto fortunes = [this] { + const auto pg_result = [this] { const auto lock = semaphore_.Acquire(); - return pg_ - ->Execute(db_helpers::kClusterHostType, select_all_fortunes_query_) - .AsContainer>( - userver::storages::postgres::kRowTag); + return pg_->Execute(db_helpers::kClusterHostType, + select_all_fortunes_query_); }(); + auto fortunes = pg_result.AsContainer>( + userver::storages::postgres::kRowTag); fortunes.push_back({0, "Additional fortune added at request time."}); std::sort(fortunes.begin(), fortunes.end(), diff --git a/frameworks/C++/userver/userver_benchmark/controllers/updates/handler.cpp b/frameworks/C++/userver/userver_benchmark/controllers/updates/handler.cpp index f5242bc333f..4bf62bf645e 100644 --- a/frameworks/C++/userver/userver_benchmark/controllers/updates/handler.cpp +++ b/frameworks/C++/userver/userver_benchmark/controllers/updates/handler.cpp @@ -30,7 +30,7 @@ Handler::Handler(const userver::components::ComponentConfig& config, pg_{context.FindComponent("hello-world-db") .GetCluster()}, query_arg_name_{"queries"}, - update_query_{kUpdateQueryStr}, + update_query_{db_helpers::CreateNonLoggingQuery(kUpdateQueryStr)}, semaphore_{kBestConcurrencyWildGuess} {} userver::formats::json::Value Handler::HandleRequestJsonThrow( diff --git a/frameworks/C++/userver/userver_configs/static_config.yaml b/frameworks/C++/userver/userver_configs/static_config.yaml index 996dfd387fd..b4fad14911f 100644 --- a/frameworks/C++/userver/userver_configs/static_config.yaml +++ b/frameworks/C++/userver/userver_configs/static_config.yaml @@ -17,7 +17,7 @@ components_manager: fs-task-processor: # Make a separate task processor for filesystem bound tasks. thread_name: fs-worker - worker_threads: 4 + worker_threads: 1 default_task_processor: main-task-processor @@ -49,8 +49,8 @@ components_manager: dynamic-config: # Dynamic config storage options, do nothing fs-cache-path: '' - dynamic-config-fallbacks: # Load options from file and push them into the dynamic config storage. - fallback-path: /app/dynamic_config_fallback.json + defaults-path: /app/dynamic_config_fallback.json + fs-task-processor: fs-task-processor testsuite-support: @@ -82,6 +82,7 @@ components_manager: max_pool_size: 260 max_queue_size: 512 connecting_limit: 15 + ignore_unused_query_params: true single-query-handler: path: /db From 95ddf9ddf788731459209db68b94b6531c5975f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 01:01:00 +0000 Subject: [PATCH 14/15] Bump aiohttp from 3.8.6 to 3.9.0 in /frameworks/Python/api_hour Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.6 to 3.9.0. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.6...v3.9.0) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- frameworks/Python/api_hour/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/api_hour/requirements.txt b/frameworks/Python/api_hour/requirements.txt index 9d8070bed79..8fb8905ca36 100644 --- a/frameworks/Python/api_hour/requirements.txt +++ b/frameworks/Python/api_hour/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.8.6 +aiohttp==3.9.0 -e git+https://github.com/Eyepea/aiohttp_jinja2.git@c9675e5c1e1ee7741b30aea8d8fbffcde016c7a0#egg=aiohttp_jinja2-master aiopg==0.7.0 -e git+https://github.com/Eyepea/API-Hour.git@577abbdcbb8cc2810dad46e260b338b15db4d0e3#egg=api_hour-master From 27881bbe5b3309fd5067904c7bb16f5df0678586 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 01:07:07 +0000 Subject: [PATCH 15/15] Bump aiohttp from 3.8.6 to 3.9.0 in /frameworks/Python/aiohttp Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.6 to 3.9.0. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.6...v3.9.0) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- frameworks/Python/aiohttp/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/Python/aiohttp/requirements.txt b/frameworks/Python/aiohttp/requirements.txt index 5763f8624a4..bb7f19ececa 100644 --- a/frameworks/Python/aiohttp/requirements.txt +++ b/frameworks/Python/aiohttp/requirements.txt @@ -1,4 +1,4 @@ -aiohttp==3.8.6 +aiohttp==3.9.0 asyncpg==0.25.0 cchardet==2.1.7 gunicorn==20.1