Skip to content

Commit

Permalink
feat: Add fetch_metrics() for HTTP connection managers (#273)
Browse files Browse the repository at this point in the history
Co-authored-by: Steven Yuan <yuasteve@amazon.com>
Co-authored-by: Dengke Tang <815825145@qq.com>
  • Loading branch information
3 people authored Jul 3, 2024
1 parent 9d6d175 commit 0829d20
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 7 deletions.
6 changes: 5 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ awsCCommonPlatformExcludes.append("source/arch/arm")
#if !os(Windows)
awsCCommonPlatformExcludes.append("source/windows")
#endif
let cSettingsCommon: [CSetting] = [
.headerSearchPath("source/external/libcbor"),
.define("DEBUG_BUILD", .when(configuration: .debug))
]

//////////////////////////////////////////////////////////////////////
/// aws-c-cal
Expand Down Expand Up @@ -198,7 +202,7 @@ packageTargets.append(contentsOf: [
dependencies: ["AwsCPlatformConfig"],
path: "aws-common-runtime/aws-c-common",
exclude: awsCCommonPlatformExcludes,
cSettings: cSettings
cSettings: cSettingsCommon
),
.target(
name: "AwsCSdkUtils",
Expand Down
11 changes: 11 additions & 0 deletions Source/AwsCommonRuntimeKit/http/HTTP2StreamManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ public class HTTP2StreamManager {
})
}

/// Fetch the current manager metrics from connection manager.
public func fetchMetrics() -> HTTPClientConnectionManagerMetrics {
var cManagerMetrics = aws_http_manager_metrics()
aws_http2_stream_manager_fetch_metrics(rawValue, &cManagerMetrics)
return HTTPClientConnectionManagerMetrics(
availableConcurrency: cManagerMetrics.available_concurrency,
pendingConcurrencyAcquires: cManagerMetrics.pending_concurrency_acquires,
leasedConcurrency: cManagerMetrics.leased_concurrency
)
}

deinit {
aws_http2_stream_manager_release(rawValue)
}
Expand Down
11 changes: 11 additions & 0 deletions Source/AwsCommonRuntimeKit/http/HTTPClientConnectionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ public class HTTPClientConnectionManager {
}
}

/// Fetch the current manager metrics from connection manager.
public func fetchMetrics() -> HTTPClientConnectionManagerMetrics {
var cManagerMetrics = aws_http_manager_metrics()
aws_http_connection_manager_fetch_metrics(rawValue, &cManagerMetrics)
return HTTPClientConnectionManagerMetrics(
availableConcurrency: cManagerMetrics.available_concurrency,
pendingConcurrencyAcquires: cManagerMetrics.pending_concurrency_acquires,
leasedConcurrency: cManagerMetrics.leased_concurrency
)
}

deinit {
aws_http_connection_manager_release(rawValue)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0.

public struct HTTPClientConnectionManagerMetrics {
/// The number of additional concurrent requests that can be supported by the HTTP manager without needing to
/// establish additional connections to the target server.
///
/// For connection manager, it equals to connections that's idle.
/// For stream manager, it equals to the number of streams that are possible to be made without creating new
/// connection, although the implementation can create new connection without fully filling it.
public var availableConcurrency: Int
/// The number of requests that are awaiting concurrency to be made available from the HTTP manager.
public var pendingConcurrencyAcquires: Int
/// The number of connections (HTTP/1.1) or streams (for HTTP/2 via. stream manager) currently vended to user.
public var leasedConcurrency: Int

public init(
availableConcurrency: Int,
pendingConcurrencyAcquires: Int,
leasedConcurrency: Int
) {
self.availableConcurrency = availableConcurrency
self.pendingConcurrencyAcquires = pendingConcurrencyAcquires
self.leasedConcurrency = leasedConcurrency
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ class HTT2StreamManagerTests: HTTPClientTestFixture {

let stream = try await streamManager.acquireStream(requestOptions: http2RequestOptions)
XCTAssertFalse(onCompleteCalled)
let metrics = streamManager.fetchMetrics()
XCTAssertTrue(metrics.availableConcurrency > 0)
XCTAssertTrue(metrics.leasedConcurrency > 0)
let data = TEST_DOC_LINE.data(using: .utf8)!
for chunk in data.chunked(into: 5) {
try await stream.writeChunk(chunk: chunk, endOfStream: false)
Expand Down
9 changes: 6 additions & 3 deletions Test/AwsCommonRuntimeKitTests/http/HTTPTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class HTTPTests: HTTPClientTestFixture {
_ = try await sendHTTPRequest(method: "GET", endpoint: host, path: getPath, connectionManager: connectionManager)
_ = try await sendHTTPRequest(method: "GET", endpoint: host, path: "/delete", expectedStatus: 404, connectionManager: connectionManager)
}

func testGetHTTPSRequestWithUtf8Header() async throws {
let connectionManager = try await getHttpConnectionManager(endpoint: host, ssh: true, port: 443)
let utf8Header = HTTPHeader(name: "TestHeader", value: "TestValueWithEmoji🤯")
Expand Down Expand Up @@ -64,6 +64,9 @@ class HTTPTests: HTTPClientTestFixture {
let streamBase = try connection.makeRequest(requestOptions: httpRequestOptions)
try streamBase.activate()
XCTAssertFalse(onCompleteCalled)
let metrics = connectionManager.fetchMetrics()
XCTAssertTrue(metrics.leasedConcurrency > 0)

let data = TEST_DOC_LINE.data(using: .utf8)!
for chunk in data.chunked(into: 5) {
try await streamBase.writeChunk(chunk: chunk, endOfStream: false)
Expand Down Expand Up @@ -118,7 +121,7 @@ class HTTPTests: HTTPClientTestFixture {
// Sleep for 5 seconds to make sure onComplete is not triggerred
try await Task.sleep(nanoseconds: 5_000_000_000)
XCTAssertFalse(onCompleteCalled)

let lastChunkData = Data("last chunk data".utf8)
try await streamBase.writeChunk(chunk: lastChunkData, endOfStream: true)
semaphore.wait()
Expand All @@ -135,7 +138,7 @@ class HTTPTests: HTTPClientTestFixture {
XCTAssertEqual(body.data, TEST_DOC_LINE + String(decoding: lastChunkData, as: UTF8.self))
}


func testHTTPStreamIsReleasedIfNotActivated() async throws {
do {
let httpRequestOptions = try getHTTPRequestOptions(method: "GET", endpoint: host, path: getPath)
Expand Down
2 changes: 1 addition & 1 deletion aws-common-runtime/aws-c-common
Submodule aws-c-common updated 83 files
+1 −1 .clang-tidy
+4 −7 .github/workflows/clang-format.yml
+6 −5 .github/workflows/proof_ci_resources/config.yaml
+10 −1 CMakeLists.txt
+26 −0 THIRD-PARTY-LICENSES.txt
+47 −0 format-check.py
+0 −24 format-check.sh
+2 −4 include/aws/common/atomics.h
+1 −1 include/aws/common/byte_buf.h
+449 −0 include/aws/common/cbor.h
+2 −4 include/aws/common/condition_variable.h
+7 −2 include/aws/common/error.h
+3 −2 include/aws/common/logging.h
+19 −1 include/aws/common/macros.h
+2 −4 include/aws/common/mutex.h
+19 −0 include/aws/common/private/byte_buf.h
+7 −3 include/aws/common/private/external_module_impl.h
+2 −4 include/aws/common/rw_lock.h
+1 −1 include/aws/common/statistics.h
+1 −2 include/aws/common/thread.h
+129 −0 scripts/import_libcbor.py
+8 −3 scripts/latest_submodules.py
+1 −1 source/allocator.c
+3 −1 source/android/logging.c
+19 −0 source/byte_buf.c
+647 −0 source/cbor.c
+12 −2 source/common.c
+19 −0 source/external/libcbor/allocators.c
+425 −0 source/external/libcbor/cbor.c
+74 −0 source/external/libcbor/cbor.h
+131 −0 source/external/libcbor/cbor/arrays.c
+137 −0 source/external/libcbor/cbor/arrays.h
+119 −0 source/external/libcbor/cbor/bytestrings.c
+150 −0 source/external/libcbor/cbor/bytestrings.h
+121 −0 source/external/libcbor/cbor/callbacks.c
+189 −0 source/external/libcbor/cbor/callbacks.h
+14 −0 source/external/libcbor/cbor/cbor_export.h
+163 −0 source/external/libcbor/cbor/common.c
+339 −0 source/external/libcbor/cbor/common.h
+46 −0 source/external/libcbor/cbor/configuration.h
+264 −0 source/external/libcbor/cbor/data.h
+200 −0 source/external/libcbor/cbor/encoding.c
+140 −0 source/external/libcbor/cbor/encoding.h
+189 −0 source/external/libcbor/cbor/floats_ctrls.c
+240 −0 source/external/libcbor/cbor/floats_ctrls.h
+422 −0 source/external/libcbor/cbor/internal/builder_callbacks.c
+85 −0 source/external/libcbor/cbor/internal/builder_callbacks.h
+98 −0 source/external/libcbor/cbor/internal/encoders.c
+41 −0 source/external/libcbor/cbor/internal/encoders.h
+80 −0 source/external/libcbor/cbor/internal/loaders.c
+43 −0 source/external/libcbor/cbor/internal/loaders.h
+57 −0 source/external/libcbor/cbor/internal/memory_utils.c
+50 −0 source/external/libcbor/cbor/internal/memory_utils.h
+33 −0 source/external/libcbor/cbor/internal/stack.c
+53 −0 source/external/libcbor/cbor/internal/stack.h
+95 −0 source/external/libcbor/cbor/internal/unicode.c
+33 −0 source/external/libcbor/cbor/internal/unicode.h
+190 −0 source/external/libcbor/cbor/ints.c
+211 −0 source/external/libcbor/cbor/ints.h
+125 −0 source/external/libcbor/cbor/maps.c
+121 −0 source/external/libcbor/cbor/maps.h
+368 −0 source/external/libcbor/cbor/serialization.c
+168 −0 source/external/libcbor/cbor/serialization.h
+600 −0 source/external/libcbor/cbor/streaming.c
+37 −0 source/external/libcbor/cbor/streaming.h
+142 −0 source/external/libcbor/cbor/strings.c
+183 −0 source/external/libcbor/cbor/strings.h
+46 −0 source/external/libcbor/cbor/tags.c
+74 −0 source/external/libcbor/cbor/tags.h
+1 −1 source/json.c
+1 −1 source/posix/clock.c
+1 −1 source/priority_queue.c
+1 −0 source/windows/thread.c
+11 −0 tests/CMakeLists.txt
+2 −0 tests/assert_test.c
+58 −1 tests/byte_buf_test.c
+489 −0 tests/cbor_test.c
+18 −14 tests/condition_variable_test.c
+9 −7 tests/error_test.c
+87 −0 tests/fuzz/cbor_decoding_transitive.c
+66 −0 tests/fuzz/cbor_double_encode_decode.c
+0 −1 verification/cbmc/proofs/Makefile.common
+4 −1 verification/cbmc/sources/utils.c
2 changes: 1 addition & 1 deletion aws-common-runtime/s2n
Submodule s2n updated 343 files

0 comments on commit 0829d20

Please sign in to comment.