Compare commits
1 Commits
master
...
performanc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36366e8649 |
4
.github/workflows/abidiff.yaml
vendored
4
.github/workflows/abidiff.yaml
vendored
@ -5,10 +5,6 @@ name: abidiff
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh
|
||||
|
||||
6
.github/workflows/cifuzz.yaml
vendored
6
.github/workflows/cifuzz.yaml
vendored
@ -1,11 +1,5 @@
|
||||
name: CIFuzz
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
45
.github/workflows/test.yaml
vendored
45
.github/workflows/test.yaml
vendored
@ -20,10 +20,6 @@ on:
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
GTEST_FILTER: ${{ github.event.inputs.gtest_filter || '*' }}
|
||||
|
||||
@ -79,14 +75,6 @@ jobs:
|
||||
(github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name) ||
|
||||
(github.event_name == 'workflow_dispatch' && github.event.inputs.test_windows == 'true')
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- with_ssl: false
|
||||
name: without SSL
|
||||
- with_ssl: true
|
||||
name: with SSL
|
||||
name: windows ${{ matrix.config.name }}
|
||||
steps:
|
||||
- name: Prepare Git for Checkout on Windows
|
||||
run: |
|
||||
@ -102,25 +90,24 @@ jobs:
|
||||
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||
- name: Setup msbuild on windows
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
- name: Install vcpkg dependencies
|
||||
run: vcpkg install gtest curl zlib brotli
|
||||
- name: Install OpenSSL
|
||||
if: ${{ matrix.config.with_ssl }}
|
||||
run: choco install openssl
|
||||
- name: Configure CMake ${{ matrix.config.name }}
|
||||
run: >
|
||||
cmake -B build -S .
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
|
||||
-DHTTPLIB_TEST=ON
|
||||
-DHTTPLIB_REQUIRE_ZLIB=ON
|
||||
-DHTTPLIB_REQUIRE_BROTLI=ON
|
||||
-DHTTPLIB_REQUIRE_OPENSSL=${{ matrix.config.with_ssl && 'ON' || 'OFF' }}
|
||||
- name: Build ${{ matrix.config.name }}
|
||||
run: cmake --build build --config Release -- /v:m /clp:ShowCommandLine
|
||||
- name: Run tests ${{ matrix.config.name }}
|
||||
- name: Install libraries
|
||||
run: |
|
||||
vcpkg install gtest curl zlib brotli
|
||||
choco install openssl
|
||||
|
||||
- name: Configure CMake with SSL
|
||||
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON
|
||||
- name: Build with with SSL
|
||||
run: cmake --build build --config Release
|
||||
- name: Run tests with SSL
|
||||
run: ctest --output-on-failure --test-dir build -C Release
|
||||
|
||||
- name: Configure CMake without SSL
|
||||
run: cmake -B build-no-ssl -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=OFF -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON
|
||||
- name: Build without SSL
|
||||
run: cmake --build build-no-ssl --config Release
|
||||
- name: Run tests without SSL
|
||||
run: ctest --output-on-failure --test-dir build-no-ssl -C Release
|
||||
env:
|
||||
VCPKG_ROOT: "C:/vcpkg"
|
||||
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||
|
||||
10
httplib.h
10
httplib.h
@ -7333,16 +7333,6 @@ inline ClientImpl::ClientImpl(const std::string &host, int port,
|
||||
client_cert_path_(client_cert_path), client_key_path_(client_key_path) {}
|
||||
|
||||
inline ClientImpl::~ClientImpl() {
|
||||
// Wait until all the requests in flight are handled.
|
||||
size_t retry_count = 10;
|
||||
while (retry_count-- > 0) {
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(socket_mutex_);
|
||||
if (socket_requests_in_flight_ == 0) { break; }
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{1});
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(socket_mutex_);
|
||||
shutdown_socket(socket_);
|
||||
close_socket(socket_);
|
||||
|
||||
108
test/test.cc
108
test/test.cc
@ -8352,85 +8352,61 @@ TEST(MaxTimeoutTest, ContentStreamSSL) {
|
||||
}
|
||||
#endif
|
||||
|
||||
class EventDispatcher {
|
||||
public:
|
||||
EventDispatcher() {}
|
||||
|
||||
void wait_event(DataSink *sink) {
|
||||
unique_lock<mutex> lk(m_);
|
||||
int id = id_;
|
||||
cv_.wait(lk, [&] { return cid_ == id; });
|
||||
sink->write(message_.data(), message_.size());
|
||||
}
|
||||
|
||||
void send_event(const string &message) {
|
||||
lock_guard<mutex> lk(m_);
|
||||
cid_ = id_++;
|
||||
message_ = message;
|
||||
cv_.notify_all();
|
||||
}
|
||||
|
||||
private:
|
||||
mutex m_;
|
||||
condition_variable cv_;
|
||||
atomic_int id_{0};
|
||||
atomic_int cid_{-1};
|
||||
string message_;
|
||||
};
|
||||
|
||||
TEST(ClientInThreadTest, Issue2068) {
|
||||
EventDispatcher ed;
|
||||
void performance_test(const char *host) {
|
||||
auto port = 1234;
|
||||
|
||||
Server svr;
|
||||
svr.Get("/event1", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_chunked_content_provider("text/event-stream",
|
||||
[&](size_t /*offset*/, DataSink &sink) {
|
||||
ed.wait_event(&sink);
|
||||
return true;
|
||||
});
|
||||
svr.Get("/test", [&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("hello world!", "text/plain");
|
||||
});
|
||||
|
||||
auto listen_thread = std::thread([&svr]() { svr.listen(HOST, PORT); });
|
||||
|
||||
svr.wait_until_ready();
|
||||
|
||||
thread event_thread([&] {
|
||||
int id = 0;
|
||||
while (svr.is_running()) {
|
||||
this_thread::sleep_for(chrono::milliseconds(500));
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "data: " << id << "\n\n";
|
||||
ed.send_event(ss.str());
|
||||
id++;
|
||||
}
|
||||
});
|
||||
auto thread = std::thread([&]() { svr.listen(host, port); });
|
||||
|
||||
auto se = detail::scope_exit([&] {
|
||||
svr.stop();
|
||||
|
||||
listen_thread.join();
|
||||
event_thread.join();
|
||||
|
||||
thread.join();
|
||||
ASSERT_FALSE(svr.is_running());
|
||||
});
|
||||
|
||||
{
|
||||
auto client = detail::make_unique<Client>(HOST, PORT);
|
||||
client->set_read_timeout(std::chrono::minutes(10));
|
||||
svr.wait_until_ready();
|
||||
|
||||
std::atomic<bool> stop{false};
|
||||
// Measure the get req/res time
|
||||
Client cli(host, port);
|
||||
|
||||
std::thread t([&] {
|
||||
client->Get("/event1",
|
||||
[&](const char *, size_t) -> bool { return !stop; });
|
||||
});
|
||||
const int n = 10;
|
||||
long long total_time = 0;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
stop = true;
|
||||
client->stop();
|
||||
client.reset();
|
||||
for (int i = 0; i < n; i++) {
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto res = cli.Get("/test");
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
auto elapsed_time = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
end_time - start_time)
|
||||
.count();
|
||||
|
||||
t.join();
|
||||
// Verify response
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_TRUE(res != nullptr);
|
||||
EXPECT_EQ(httplib::StatusCode::OK_200, res->status);
|
||||
EXPECT_EQ(httplib::Error::Success, res.error());
|
||||
EXPECT_EQ("hello world!", res->body);
|
||||
|
||||
// Verify elapsed time
|
||||
std::cout << "elapsed_time: " << elapsed_time << "us" << std::endl;
|
||||
EXPECT_LE(elapsed_time, 3000);
|
||||
|
||||
total_time += elapsed_time;
|
||||
}
|
||||
|
||||
auto average_time = total_time / n;
|
||||
std::cout << "average_time: " << average_time << "us" << std::endl;
|
||||
|
||||
// Verify average elapsed time
|
||||
ASSERT_LE(average_time, 3000);
|
||||
}
|
||||
|
||||
TEST(PerformanceTest, localhost) { performance_test("localhost"); }
|
||||
|
||||
TEST(PerformanceTest, IPv4) { performance_test("127.0.0.1"); }
|
||||
|
||||
TEST(PerformanceTest, IPv6) { performance_test("::1"); }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user