Skip to content

Commit

Permalink
removed NIO dependency and replaced with Lock.swift
Browse files Browse the repository at this point in the history
  • Loading branch information
bryce-b committed Dec 20, 2023
1 parent 3637130 commit e560170
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 29 deletions.
9 changes: 3 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,16 @@ let package = Package(
.target(name: "OpenTelemetryProtocolExporterCommon",
dependencies: ["OpenTelemetrySdk",
.product(name: "Logging", package: "swift-log"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "NIO", package: "swift-nio")],
.product(name: "SwiftProtobuf", package: "swift-protobuf")],
path: "Sources/Exporters/OpenTelemetryProtocolCommon"),
.target(name: "OpenTelemetryProtocolExporterHttp",
dependencies: ["OpenTelemetrySdk",
"OpenTelemetryProtocolExporterCommon",
.product(name: "NIO", package: "swift-nio")],
"OpenTelemetryProtocolExporterCommon"],
path: "Sources/Exporters/OpenTelemetryProtocolHttp"),
.target(name: "OpenTelemetryProtocolExporterGrpc",
dependencies: ["OpenTelemetrySdk",
"OpenTelemetryProtocolExporterCommon",
.product(name: "GRPC", package: "grpc-swift"),
.product(name: "NIO", package: "swift-nio")],
.product(name: "GRPC", package: "grpc-swift")],
path: "Sources/Exporters/OpenTelemetryProtocolGrpc"),
.target(name: "StdoutExporter",
dependencies: ["OpenTelemetrySdk"],
Expand Down
9 changes: 3 additions & 6 deletions Package@swift-5.6.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,16 @@ let package = Package(
.target(name: "OpenTelemetryProtocolExporterCommon",
dependencies: ["OpenTelemetrySdk",
.product(name: "Logging", package: "swift-log"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "NIO", package: "swift-nio")],
.product(name: "SwiftProtobuf", package: "swift-protobuf")],
path: "Sources/Exporters/OpenTelemetryProtocolCommon"),
.target(name: "OpenTelemetryProtocolExporterHttp",
dependencies: ["OpenTelemetrySdk",
"OpenTelemetryProtocolExporterCommon",
.product(name: "NIO", package: "swift-nio")],
"OpenTelemetryProtocolExporterCommon"],
path: "Sources/Exporters/OpenTelemetryProtocolHttp"),
.target(name: "OpenTelemetryProtocolExporterGrpc",
dependencies: ["OpenTelemetrySdk",
"OpenTelemetryProtocolExporterCommon",
.product(name: "GRPC", package: "grpc-swift"),
.product(name: "NIO", package: "swift-nio")],
.product(name: "GRPC", package: "grpc-swift")],
path: "Sources/Exporters/OpenTelemetryProtocolGrpc"),
.target(name: "StdoutExporter",
dependencies: ["OpenTelemetrySdk"],
Expand Down
6 changes: 2 additions & 4 deletions Package@swift-5.9.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,12 @@ let package = Package(
path: "Sources/Exporters/OpenTelemetryProtocolCommon"),
.target(name: "OpenTelemetryProtocolExporterHttp",
dependencies: ["OpenTelemetrySdk",
"OpenTelemetryProtocolExporterCommon",
.product(name: "NIO", package: "swift-nio")],
"OpenTelemetryProtocolExporterCommon"],
path: "Sources/Exporters/OpenTelemetryProtocolHttp"),
.target(name: "OpenTelemetryProtocolExporterGrpc",
dependencies: ["OpenTelemetrySdk",
"OpenTelemetryProtocolExporterCommon",
.product(name: "GRPC", package: "grpc-swift"),
.product(name: "NIO", package: "swift-nio")],
.product(name: "GRPC", package: "grpc-swift")],
path: "Sources/Exporters/OpenTelemetryProtocolGrpc"),
.target(name: "StdoutExporter",
dependencies: ["OpenTelemetrySdk"],
Expand Down
198 changes: 198 additions & 0 deletions Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Metrics API open source project
//
// Copyright (c) 2018-2019 Apple Inc. and the Swift Metrics API project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift Metrics API project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
import Darwin
#else
import Glibc
#endif

/// A threading lock based on `libpthread` instead of `libdispatch`.
///
/// This object provides a lock on top of a single `pthread_mutex_t`. This kind
/// of lock is safe to use with `libpthread`-based threading models, such as the
/// one used by NIO.
internal final class Lock {
fileprivate let mutex: UnsafeMutablePointer<pthread_mutex_t> = UnsafeMutablePointer.allocate(capacity: 1)

/// Create a new lock.
public init() {
let err = pthread_mutex_init(self.mutex, nil)
precondition(err == 0, "pthread_mutex_init failed with error \(err)")
}

deinit {
let err = pthread_mutex_destroy(self.mutex)
precondition(err == 0, "pthread_mutex_destroy failed with error \(err)")
self.mutex.deallocate()
}

/// Acquire the lock.
///
/// Whenever possible, consider using `withLock` instead of this method and
/// `unlock`, to simplify lock handling.
public func lock() {
let err = pthread_mutex_lock(self.mutex)
precondition(err == 0, "pthread_mutex_lock failed with error \(err)")
}

/// Release the lock.
///
/// Whenever possible, consider using `withLock` instead of this method and
/// `lock`, to simplify lock handling.
public func unlock() {
let err = pthread_mutex_unlock(self.mutex)
precondition(err == 0, "pthread_mutex_unlock failed with error \(err)")
}
}

extension Lock {
/// Acquire the lock for the duration of the given block.
///
/// This convenience method should be preferred to `lock` and `unlock` in
/// most situations, as it ensures that the lock will be released regardless
/// of how `body` exits.
///
/// - Parameter body: The block to execute while holding the lock.
/// - Returns: The value returned by the block.
@inlinable
internal func withLock<T>(_ body: () throws -> T) rethrows -> T {
self.lock()
defer {
self.unlock()
}
return try body()
}

// specialise Void return (for performance)
@inlinable
internal func withLockVoid(_ body: () throws -> Void) rethrows {
try self.withLock(body)
}
}

/// A threading lock based on `libpthread` instead of `libdispatch`.
///
/// This object provides a lock on top of a single `pthread_mutex_t`. This kind
/// of lock is safe to use with `libpthread`-based threading models, such as the
/// one used by NIO.
internal final class ReadWriteLock {
fileprivate let rwlock: UnsafeMutablePointer<pthread_rwlock_t> = UnsafeMutablePointer.allocate(capacity: 1)

Check warning on line 110 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L110

Added line #L110 was not covered by tests

/// Create a new lock.
public init() {
let err = pthread_rwlock_init(self.rwlock, nil)
precondition(err == 0, "pthread_rwlock_init failed with error \(err)")
}

Check warning on line 116 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L113-L116

Added lines #L113 - L116 were not covered by tests

deinit {
let err = pthread_rwlock_destroy(self.rwlock)
precondition(err == 0, "pthread_rwlock_destroy failed with error \(err)")
self.rwlock.deallocate()
}

Check warning on line 122 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L118-L122

Added lines #L118 - L122 were not covered by tests

/// Acquire a reader lock.
///
/// Whenever possible, consider using `withLock` instead of this method and
/// `unlock`, to simplify lock handling.
public func lockRead() {
let err = pthread_rwlock_rdlock(self.rwlock)
precondition(err == 0, "pthread_rwlock_rdlock failed with error \(err)")
}

Check warning on line 131 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L128-L131

Added lines #L128 - L131 were not covered by tests

/// Acquire a writer lock.
///
/// Whenever possible, consider using `withLock` instead of this method and
/// `unlock`, to simplify lock handling.
public func lockWrite() {
let err = pthread_rwlock_wrlock(self.rwlock)
precondition(err == 0, "pthread_rwlock_wrlock failed with error \(err)")
}

Check warning on line 140 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L137-L140

Added lines #L137 - L140 were not covered by tests

/// Release the lock.
///
/// Whenever possible, consider using `withLock` instead of this method and
/// `lock`, to simplify lock handling.
public func unlock() {
let err = pthread_rwlock_unlock(self.rwlock)
precondition(err == 0, "pthread_rwlock_unlock failed with error \(err)")
}

Check warning on line 149 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L146-L149

Added lines #L146 - L149 were not covered by tests
}

extension ReadWriteLock {
/// Acquire the reader lock for the duration of the given block.
///
/// This convenience method should be preferred to `lock` and `unlock` in
/// most situations, as it ensures that the lock will be released regardless
/// of how `body` exits.
///
/// - Parameter body: The block to execute while holding the lock.
/// - Returns: The value returned by the block.
@inlinable
internal func withReaderLock<T>(_ body: () throws -> T) rethrows -> T {
self.lockRead()
defer {
self.unlock()
}
return try body()
}

Check warning on line 168 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L162-L168

Added lines #L162 - L168 were not covered by tests

/// Acquire the writer lock for the duration of the given block.
///
/// This convenience method should be preferred to `lock` and `unlock` in
/// most situations, as it ensures that the lock will be released regardless
/// of how `body` exits.
///
/// - Parameter body: The block to execute while holding the lock.
/// - Returns: The value returned by the block.
@inlinable
internal func withWriterLock<T>(_ body: () throws -> T) rethrows -> T {
self.lockWrite()
defer {
self.unlock()
}
return try body()
}

Check warning on line 185 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L179-L185

Added lines #L179 - L185 were not covered by tests

// specialise Void return (for performance)
@inlinable
internal func withReaderLockVoid(_ body: () throws -> Void) rethrows {
try self.withReaderLock(body)
}

Check warning on line 191 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L189-L191

Added lines #L189 - L191 were not covered by tests

// specialise Void return (for performance)
@inlinable
internal func withWriterLockVoid(_ body: () throws -> Void) rethrows {
try self.withWriterLock(body)
}

Check warning on line 197 in Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Exporters/OpenTelemetryProtocolHttp/Lock.swift#L195-L197

Added lines #L195 - L197 were not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import Foundation
import OpenTelemetrySdk
import OpenTelemetryProtocolExporterCommon
import NIO
import NIOConcurrencyHelpers

public func defaultOltpHttpLoggingEndpoint() -> URL {
URL(string: "http://localhost:4318/v1/logs")!
Expand All @@ -16,7 +14,7 @@ public func defaultOltpHttpLoggingEndpoint() -> URL {
public class OtlpHttpLogExporter : OtlpHttpExporterBase, LogRecordExporter {

var pendingLogRecords: [ReadableLogRecord] = []
private let exporterLock = NIOLock()
private let exporterLock = Lock()
override public init(endpoint: URL = defaultOltpHttpLoggingEndpoint(),
config: OtlpConfiguration = OtlpConfiguration(),
useSession: URLSession? = nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@
import OpenTelemetrySdk
import OpenTelemetryProtocolExporterCommon
import Foundation
import NIO
import NIOConcurrencyHelpers


public func defaultOltpHTTPMetricsEndpoint() -> URL {
URL(string: "http://localhost:4318/v1/metrics")!
}

public class OtlpHttpMetricExporter: OtlpHttpExporterBase, MetricExporter {
var pendingMetrics: [Metric] = []
private let exporterLock = NIOLock()
private let exporterLock = Lock()

override
public init(endpoint: URL = defaultOltpHTTPMetricsEndpoint(), config : OtlpConfiguration = OtlpConfiguration(), useSession: URLSession? = nil, envVarHeaders: [(String,String)]? = EnvVarHeaders.attributes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import Foundation
import OpenTelemetrySdk
import OpenTelemetryProtocolExporterCommon
import NIO
import NIOConcurrencyHelpers

public func defaultStableOtlpHTTPMetricsEndpoint() -> URL {
URL(string: "http://localhost:4318/v1/metrics")!
Expand All @@ -18,7 +16,7 @@ public class StableOtlpHTTPMetricExporter: StableOtlpHTTPExporterBase, StableMet
var defaultAggregationSelector: DefaultAggregationSelector

var pendingMetrics: [StableMetricData] = []
private let exporterLock = NIOLock()
private let exporterLock = Lock()

// MARK: - Init

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import Foundation
import OpenTelemetrySdk
import OpenTelemetryProtocolExporterCommon
import NIO
import NIOConcurrencyHelpers

public func defaultOltpHttpTracesEndpoint() -> URL {
URL(string: "http://localhost:4318/v1/traces")!
Expand All @@ -17,7 +15,7 @@ public class OtlpHttpTraceExporter: OtlpHttpExporterBase, SpanExporter {


var pendingSpans: [SpanData] = []
private let exporterLock = NIOLock()
private let exporterLock = Lock()
override
public init(endpoint: URL = defaultOltpHttpTracesEndpoint(), config: OtlpConfiguration = OtlpConfiguration(),
useSession: URLSession? = nil, envVarHeaders: [(String,String)]? = EnvVarHeaders.attributes) {
Expand Down

0 comments on commit e560170

Please sign in to comment.