CommandLineToolkit
68 строк · 1.7 Кб
1/*
2* Copyright (c) Avito Tech LLC
3*/
4
5import Foundation
6import Socket
7import SocketModels
8
9// `LazySocketConnection` will connect socket on demand and reconnect it in case of link failure.
10public final class LazySocketConnection {
11public typealias SocketFactory = () throws -> Socket
12
13private let socketAddress: SocketAddress
14private let socketFactory: SocketFactory
15
16private var lazySocket: Socket?
17private var socket: Socket {
18get throws {
19if let socket = lazySocket {
20return socket
21}
22
23let newSocket = try makeConnectedSocket()
24lazySocket = newSocket
25return newSocket
26}
27}
28
29public init(
30socketAddress: SocketAddress,
31socketFactory: @escaping SocketFactory
32) {
33self.socketAddress = socketAddress
34self.socketFactory = socketFactory
35}
36
37public func send(data: Data, retriesLimit: Int = 1) throws {
38try send(data: data, tryNumber: 0, retriesLimit: retriesLimit)
39}
40
41public func close() {
42lazySocket?.close()
43lazySocket = nil
44}
45
46private func send(data: Data, tryNumber: Int, retriesLimit: Int) throws {
47do {
48try socket.write(from: data)
49} catch {
50lazySocket = nil
51
52if tryNumber < retriesLimit {
53try send(data: data, tryNumber: tryNumber + 1, retriesLimit: retriesLimit)
54} else {
55throw error
56}
57}
58}
59
60private func makeConnectedSocket() throws -> Socket {
61let socket = try socketFactory()
62try socket.connect(
63to: socketAddress.host,
64port: Int32(socketAddress.port.value)
65)
66return socket
67}
68}
69