CommandLineToolkit

Форк
0
/
StatsdClientImpl.swift 
96 строк · 2.4 Кб
1
import AtomicModels
2
import Dispatch
3
import Foundation
4
import Socket
5
import SocketModels
6

7
public final class StatsdClientImpl: StatsdClient {
8
    private let statsdSocketAddress: SocketAddress
9
    private let group = DispatchGroup()
10
    private let tornDown = AtomicValue(false)
11
    
12
    public struct InvalidSocketAddressError: Error, CustomStringConvertible {
13
        public let address: SocketAddress
14
        
15
        public var description: String {
16
            "Invalid socket address: \(address)"
17
        }
18
    }
19
    
20
    public init(
21
        statsdSocketAddress: SocketAddress
22
    ) {
23
        self.statsdSocketAddress = statsdSocketAddress
24
    }
25
    
26
    public func send(
27
        content: Data,
28
        queue: DispatchQueue,
29
        completion: @escaping (Error?) -> ()
30
    ) {
31
        guard tornDown.currentValue() == false else {
32
            return
33
        }
34
        
35
        guard let address = Socket.createAddress(
36
            for: statsdSocketAddress.host,
37
            on: Int32(statsdSocketAddress.port.value)
38
        ) else {
39
            queue.async { [statsdSocketAddress] in
40
                completion(InvalidSocketAddressError(address: statsdSocketAddress))
41
            }
42
            return
43
        }
44
        
45
        queue.async { [group] in
46
            group.enter()
47
            defer {
48
                group.leave()
49
            }
50
            
51
            do {
52
                let socket = try Socket.create(
53
                    type: .datagram,
54
                    proto: .udp
55
                )
56
                defer {
57
                    socket.close()
58
                }
59
                
60
                try socket.write(
61
                    from: content,
62
                    to: address
63
                )
64
                completion(nil)
65
            } catch {
66
                completion(error)
67
            }
68
        }
69
    }
70
    
71
    public func tearDown(
72
        queue: DispatchQueue,
73
        timeout: TimeInterval,
74
        completion: @escaping () -> ()
75
    ) {
76
        self.tornDown.set(true)
77
        
78
        let tearDownCompleted = AtomicValue(false)
79
        
80
        let complete = {
81
            tearDownCompleted.withExclusiveAccess {
82
                if $0 == false {
83
                    $0 = true
84
                    completion()
85
                }
86
            }
87
        }
88
        
89
        group.notify(queue: queue) {
90
            complete()
91
        }
92
        queue.asyncAfter(deadline: .now() + timeout) {
93
            complete()
94
        }
95
    }
96
}
97

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.