@streamr/dht 100.2.5-beta.1 → 101.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +7 -7
- package/dist/src/connection/ConnectionLockRpcLocal.d.ts +3 -3
- package/dist/src/connection/ConnectionLockRpcLocal.js +8 -8
- package/dist/src/connection/ConnectionLockRpcLocal.js.map +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +4 -6
- package/dist/src/connection/ConnectionManager.js +128 -103
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.d.ts +15 -14
- package/dist/src/connection/ConnectorFacade.js +70 -52
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/Handshaker.d.ts +9 -2
- package/dist/src/connection/Handshaker.js +117 -27
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/ManagedConnection.d.ts +13 -38
- package/dist/src/connection/ManagedConnection.js +31 -252
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/OutputBuffer.d.ts +9 -0
- package/dist/src/connection/OutputBuffer.js +26 -0
- package/dist/src/connection/OutputBuffer.js.map +1 -0
- package/dist/src/connection/PendingConnection.d.ts +19 -0
- package/dist/src/connection/PendingConnection.js +59 -0
- package/dist/src/connection/PendingConnection.js.map +1 -0
- package/dist/src/connection/connectivityChecker.js +3 -3
- package/dist/src/connection/connectivityChecker.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.js +2 -2
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/simulator/Simulator.d.ts +1 -3
- package/dist/src/connection/simulator/Simulator.js +1 -4
- package/dist/src/connection/simulator/Simulator.js.map +1 -1
- package/dist/src/connection/simulator/SimulatorConnection.js +1 -2
- package/dist/src/connection/simulator/SimulatorConnection.js.map +1 -1
- package/dist/src/connection/simulator/SimulatorConnector.d.ts +3 -3
- package/dist/src/connection/simulator/SimulatorConnector.js +28 -21
- package/dist/src/connection/simulator/SimulatorConnector.js.map +1 -1
- package/dist/src/connection/webrtc/NodeWebrtcConnection.d.ts +1 -6
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +3 -20
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.d.ts +11 -6
- package/dist/src/connection/webrtc/WebrtcConnector.js +57 -42
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +8 -10
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +21 -44
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.js +8 -2
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.js.map +1 -1
- package/dist/src/connection/websocket/AutoCertifierClientFacade.d.ts +3 -3
- package/dist/src/connection/websocket/AutoCertifierClientFacade.js +8 -8
- package/dist/src/connection/websocket/AutoCertifierClientFacade.js.map +1 -1
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js +1 -1
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketClientConnector.d.ts +26 -0
- package/dist/src/connection/websocket/WebsocketClientConnector.js +86 -0
- package/dist/src/connection/websocket/WebsocketClientConnector.js.map +1 -0
- package/dist/src/connection/websocket/WebsocketClientConnectorRpcLocal.d.ts +19 -0
- package/dist/src/connection/websocket/WebsocketClientConnectorRpcLocal.js +23 -0
- package/dist/src/connection/websocket/WebsocketClientConnectorRpcLocal.js.map +1 -0
- package/dist/src/connection/websocket/WebsocketClientConnectorRpcRemote.d.ts +5 -0
- package/dist/src/connection/websocket/{WebsocketConnectorRpcRemote.js → WebsocketClientConnectorRpcRemote.js} +4 -4
- package/dist/src/connection/websocket/WebsocketClientConnectorRpcRemote.js.map +1 -0
- package/dist/src/connection/websocket/WebsocketServer.d.ts +8 -5
- package/dist/src/connection/websocket/WebsocketServer.js +11 -11
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/connection/websocket/{WebsocketConnector.d.ts → WebsocketServerConnector.d.ts} +16 -21
- package/dist/src/connection/websocket/{WebsocketConnector.js → WebsocketServerConnector.js} +112 -160
- package/dist/src/connection/websocket/WebsocketServerConnector.js.map +1 -0
- package/dist/src/dht/DhtNode.d.ts +4 -4
- package/dist/src/dht/DhtNode.js +85 -84
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +3 -3
- package/dist/src/dht/DhtNodeRpcLocal.js +9 -9
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +3 -3
- package/dist/src/dht/ExternalApiRpcLocal.js +5 -5
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.js +2 -2
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +4 -4
- package/dist/src/dht/PeerManager.js +22 -22
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/SortedContactList.d.ts +3 -3
- package/dist/src/dht/contact/SortedContactList.js +9 -9
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/discovery/DiscoverySession.d.ts +3 -3
- package/dist/src/dht/discovery/DiscoverySession.js +21 -21
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +3 -3
- package/dist/src/dht/discovery/PeerDiscovery.js +46 -44
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +3 -3
- package/dist/src/dht/discovery/RingDiscoverySession.js +19 -19
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +3 -3
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +33 -33
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.d.ts +3 -3
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js +8 -8
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcLocal.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.d.ts +4 -4
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +24 -24
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.d.ts +4 -4
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js +5 -5
- package/dist/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +3 -3
- package/dist/src/dht/routing/Router.js +20 -20
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +3 -3
- package/dist/src/dht/routing/RouterRpcLocal.js +16 -16
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +3 -3
- package/dist/src/dht/routing/RoutingSession.js +24 -24
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/StoreManager.d.ts +3 -3
- package/dist/src/dht/store/StoreManager.js +25 -25
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/dht/store/StoreRpcLocal.d.ts +3 -3
- package/dist/src/dht/store/StoreRpcLocal.js +12 -12
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/exports.d.ts +3 -0
- package/dist/src/exports.js +5 -1
- package/dist/src/exports.js.map +1 -1
- package/dist/src/proto/google/protobuf/any.d.ts +5 -8
- package/dist/src/proto/google/protobuf/any.js.map +1 -1
- package/dist/src/proto/google/protobuf/empty.d.ts +1 -0
- package/dist/src/proto/google/protobuf/empty.js.map +1 -1
- package/dist/src/proto/google/protobuf/timestamp.d.ts +1 -10
- package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +4 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +8 -8
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +3 -3
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +4 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +2 -2
- package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
- package/dist/src/transport/ListeningRpcCommunicator.d.ts +2 -2
- package/dist/src/transport/ListeningRpcCommunicator.js +2 -2
- package/dist/src/transport/ListeningRpcCommunicator.js.map +1 -1
- package/dist/src/transport/RoutingRpcCommunicator.d.ts +2 -2
- package/dist/src/transport/RoutingRpcCommunicator.js +2 -2
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/package.json +7 -7
- package/protos/DhtRpc.proto +1 -1
- package/src/connection/ConnectionLockRpcLocal.ts +9 -9
- package/src/connection/ConnectionLockRpcRemote.ts +1 -1
- package/src/connection/ConnectionManager.ts +153 -111
- package/src/connection/ConnectorFacade.ts +84 -61
- package/src/connection/Handshaker.ts +131 -27
- package/src/connection/ManagedConnection.ts +41 -304
- package/src/connection/OutputBuffer.ts +28 -0
- package/src/connection/PendingConnection.ts +68 -0
- package/src/connection/connectivityChecker.ts +2 -2
- package/src/connection/connectivityRequestHandler.ts +1 -1
- package/src/connection/simulator/Simulator.ts +1 -5
- package/src/connection/simulator/SimulatorConnection.ts +1 -2
- package/src/connection/simulator/SimulatorConnector.ts +34 -33
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -6
- package/src/connection/webrtc/NodeWebrtcConnection.ts +3 -24
- package/src/connection/webrtc/WebrtcConnector.ts +73 -62
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +26 -56
- package/src/connection/websocket/AbstractWebsocketClientConnection.ts +8 -2
- package/src/connection/websocket/AutoCertifierClientFacade.ts +11 -11
- package/src/connection/websocket/NodeWebsocketClientConnection.ts +1 -1
- package/src/connection/websocket/WebsocketClientConnector.ts +119 -0
- package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +39 -0
- package/src/connection/websocket/{WebsocketConnectorRpcRemote.ts → WebsocketClientConnectorRpcRemote.ts} +2 -2
- package/src/connection/websocket/WebsocketServer.ts +18 -14
- package/src/connection/websocket/{WebsocketConnector.ts → WebsocketServerConnector.ts} +128 -205
- package/src/dht/DhtNode.ts +90 -89
- package/src/dht/DhtNodeRpcLocal.ts +11 -11
- package/src/dht/ExternalApiRpcLocal.ts +6 -6
- package/src/dht/ExternalApiRpcRemote.ts +2 -2
- package/src/dht/PeerManager.ts +24 -24
- package/src/dht/contact/SortedContactList.ts +10 -10
- package/src/dht/discovery/DiscoverySession.ts +24 -24
- package/src/dht/discovery/PeerDiscovery.ts +47 -45
- package/src/dht/discovery/RingDiscoverySession.ts +23 -23
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +36 -36
- package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +9 -9
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +25 -25
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +7 -7
- package/src/dht/routing/Router.ts +21 -21
- package/src/dht/routing/RouterRpcLocal.ts +17 -17
- package/src/dht/routing/RoutingSession.ts +26 -26
- package/src/dht/store/StoreManager.ts +27 -27
- package/src/dht/store/StoreRpcLocal.ts +13 -13
- package/src/exports.ts +3 -0
- package/src/proto/google/protobuf/any.ts +6 -9
- package/src/proto/google/protobuf/empty.ts +2 -1
- package/src/proto/google/protobuf/timestamp.ts +2 -11
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +9 -9
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +3 -3
- package/src/proto/packages/dht/protos/DhtRpc.ts +4 -4
- package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
- package/src/transport/ListeningRpcCommunicator.ts +3 -3
- package/src/transport/RoutingRpcCommunicator.ts +3 -3
- package/test/end-to-end/Layer0Webrtc.test.ts +0 -10
- package/test/integration/ConnectionManager.test.ts +3 -2
- package/test/integration/GeoIpConnectivityChecking.test.ts +1 -1
- package/test/integration/SimultaneousConnections.test.ts +2 -2
- package/test/integration/WebrtcConnectionManagement.test.ts +2 -10
- package/test/integration/{WebsocketConnectorRpc.test.ts → WebsocketClientConnectorRpc.test.ts} +9 -9
- package/test/integration/WebsocketConnectionManagement.test.ts +11 -29
- package/test/unit/ConnectionManager.test.ts +64 -0
- package/test/unit/DiscoverySession.test.ts +1 -1
- package/test/unit/Handshaker.test.ts +169 -0
- package/test/unit/ManagedConnection.test.ts +58 -0
- package/test/unit/PendingConnection.test.ts +57 -0
- package/test/unit/WebrtcConnector.test.ts +56 -0
- package/test/unit/{WebsocketConnector.test.ts → WebsocketClientConnector.test.ts} +56 -11
- package/test/unit/WebsocketServerConnector.test.ts +102 -0
- package/test/utils/FakeConnectorFacade.ts +41 -0
- package/test/utils/mock/MockConnection.ts +26 -0
- package/test/utils/utils.ts +2 -2
- package/dist/src/connection/IConnectionSource.d.ts +0 -4
- package/dist/src/connection/IConnectionSource.js +0 -3
- package/dist/src/connection/IConnectionSource.js.map +0 -1
- package/dist/src/connection/webrtc/ManagedWebrtcConnection.d.ts +0 -7
- package/dist/src/connection/webrtc/ManagedWebrtcConnection.js +0 -20
- package/dist/src/connection/webrtc/ManagedWebrtcConnection.js.map +0 -1
- package/dist/src/connection/websocket/WebsocketConnector.js.map +0 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +0 -19
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +0 -23
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +0 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +0 -5
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +0 -1
- package/src/connection/IConnectionSource.ts +0 -6
- package/src/connection/webrtc/ManagedWebrtcConnection.ts +0 -27
- package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +0 -39
|
@@ -19,14 +19,16 @@ import { ConnectionLockStates, LockID } from './ConnectionLockStates'
|
|
|
19
19
|
import { ConnectorFacade } from './ConnectorFacade'
|
|
20
20
|
import { ManagedConnection, Events as ManagedConnectionEvents } from './ManagedConnection'
|
|
21
21
|
import { ConnectionLockRpcRemote } from './ConnectionLockRpcRemote'
|
|
22
|
-
import { WEBRTC_CLEANUP } from './webrtc/NodeWebrtcConnection'
|
|
23
22
|
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
24
23
|
import { ConnectionLockRpcLocal } from './ConnectionLockRpcLocal'
|
|
25
24
|
import { DhtAddress, areEqualPeerDescriptors, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
26
25
|
import { getOfferer } from '../helpers/offering'
|
|
27
26
|
import { ConnectionsView } from './ConnectionsView'
|
|
27
|
+
import { OutputBuffer } from './OutputBuffer'
|
|
28
|
+
import { IConnection } from './IConnection'
|
|
29
|
+
import { PendingConnection } from './PendingConnection'
|
|
28
30
|
|
|
29
|
-
export interface
|
|
31
|
+
export interface ConnectionManagerOptions {
|
|
30
32
|
maxConnections?: number
|
|
31
33
|
metricsContext: MetricsContext
|
|
32
34
|
createConnectorFacade: () => ConnectorFacade
|
|
@@ -75,6 +77,24 @@ export interface TlsCertificate {
|
|
|
75
77
|
certFileName: string
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
interface ConnectingEndpoint {
|
|
81
|
+
connected: false
|
|
82
|
+
// TODO: Handle PendingConnections in ConnectorFacade only? ConnectionManager knows buffer and reacts to events from below.
|
|
83
|
+
// Difficulties arise from duplicate connection handling. Sometimes a connected connection is replaced as duplicate in which case
|
|
84
|
+
// a managed connection has to be replaced in the ConnectionManager.
|
|
85
|
+
connection: PendingConnection
|
|
86
|
+
// Could the buffer be in the PendingConnection or encapsulated endpoint?
|
|
87
|
+
buffer: OutputBuffer
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface ConnectedEndpoint {
|
|
91
|
+
connected: true
|
|
92
|
+
connection: ManagedConnection
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// TODO: Could encapsulate all endpoint logic to its own module
|
|
96
|
+
type Endpoint = ConnectedEndpoint | ConnectingEndpoint
|
|
97
|
+
|
|
78
98
|
const INTERNAL_SERVICE_ID = 'system/connection-manager'
|
|
79
99
|
|
|
80
100
|
// Form an string representation from a peer description which can be undefined. This output
|
|
@@ -96,25 +116,25 @@ export const getNodeIdOrUnknownFromPeerDescriptor = (peerDescriptor: PeerDescrip
|
|
|
96
116
|
|
|
97
117
|
export class ConnectionManager extends EventEmitter<TransportEvents> implements ITransport, ConnectionsView, ConnectionLocker {
|
|
98
118
|
|
|
99
|
-
private
|
|
119
|
+
private options: ConnectionManagerOptions
|
|
100
120
|
private readonly metricsContext: MetricsContext
|
|
101
|
-
// TODO use
|
|
121
|
+
// TODO use options option or named constant?
|
|
102
122
|
private readonly duplicateMessageDetector: DuplicateDetector = new DuplicateDetector(10000)
|
|
103
123
|
private readonly metrics: ConnectionManagerMetrics
|
|
104
124
|
private locks = new ConnectionLockStates()
|
|
105
|
-
private
|
|
125
|
+
private endpoints: Map<DhtAddress, Endpoint> = new Map()
|
|
106
126
|
private readonly connectorFacade: ConnectorFacade
|
|
107
127
|
private rpcCommunicator?: RoutingRpcCommunicator
|
|
108
128
|
private disconnectorIntervalRef?: NodeJS.Timeout
|
|
109
129
|
private state = ConnectionManagerState.IDLE
|
|
110
130
|
|
|
111
|
-
constructor(
|
|
131
|
+
constructor(options: ConnectionManagerOptions) {
|
|
112
132
|
super()
|
|
113
|
-
this.
|
|
133
|
+
this.options = options
|
|
114
134
|
this.onData = this.onData.bind(this)
|
|
115
135
|
this.send = this.send.bind(this)
|
|
116
136
|
this.onNewConnection = this.onNewConnection.bind(this)
|
|
117
|
-
this.metricsContext = this.
|
|
137
|
+
this.metricsContext = this.options.metricsContext ?? new MetricsContext()
|
|
118
138
|
this.metrics = {
|
|
119
139
|
sendMessagesPerSecond: new RateMetric(),
|
|
120
140
|
sendBytesPerSecond: new RateMetric(),
|
|
@@ -124,10 +144,10 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
124
144
|
connectionTotalFailureCount: new CountMetric()
|
|
125
145
|
}
|
|
126
146
|
this.metricsContext.addMetrics('node', this.metrics)
|
|
127
|
-
this.connectorFacade = this.
|
|
147
|
+
this.connectorFacade = this.options.createConnectorFacade()
|
|
128
148
|
this.send = this.send.bind(this)
|
|
129
149
|
this.rpcCommunicator = new RoutingRpcCommunicator(INTERNAL_SERVICE_ID, this.send, {
|
|
130
|
-
rpcRequestTimeout: 10000 // TODO use
|
|
150
|
+
rpcRequestTimeout: 10000 // TODO use options option or named constant?
|
|
131
151
|
})
|
|
132
152
|
const lockRpcLocal = new ConnectionLockRpcLocal({
|
|
133
153
|
addRemoteLocked: (id: DhtAddress, lockId: LockID) => this.locks.addRemoteLocked(id, lockId),
|
|
@@ -151,21 +171,24 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
151
171
|
* which hasn't been used within maxIdleTime.
|
|
152
172
|
*/
|
|
153
173
|
public garbageCollectConnections(maxConnections: number, maxIdleTime: number): void {
|
|
154
|
-
if (this.
|
|
174
|
+
if (this.endpoints.size <= maxConnections) {
|
|
155
175
|
return
|
|
156
176
|
}
|
|
157
177
|
const disconnectionCandidates = new SortedContactList<ManagedConnection>({
|
|
158
178
|
referenceId: getNodeIdFromPeerDescriptor(this.getLocalPeerDescriptor()),
|
|
159
|
-
maxSize: 100000, // TODO use
|
|
179
|
+
maxSize: 100000, // TODO use options option or named constant?
|
|
160
180
|
allowToContainReferenceId: false
|
|
161
181
|
})
|
|
162
|
-
this.
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
|
|
182
|
+
this.endpoints.forEach((endpoint) => {
|
|
183
|
+
if (endpoint.connected) {
|
|
184
|
+
const connection = endpoint.connection
|
|
185
|
+
if (!this.locks.isLocked(connection.getNodeId()) && Date.now() - connection.getLastUsedTimestamp() > maxIdleTime) {
|
|
186
|
+
logger.trace('disconnecting in timeout interval: ' + getNodeIdOrUnknownFromPeerDescriptor(connection.getPeerDescriptor()))
|
|
187
|
+
disconnectionCandidates.addContact(connection)
|
|
188
|
+
}
|
|
166
189
|
}
|
|
167
190
|
})
|
|
168
|
-
const disconnectables = disconnectionCandidates.getFurthestContacts(this.
|
|
191
|
+
const disconnectables = disconnectionCandidates.getFurthestContacts(this.endpoints.size - maxConnections)
|
|
169
192
|
for (const disconnectable of disconnectables) {
|
|
170
193
|
const peerDescriptor = disconnectable.getPeerDescriptor()!
|
|
171
194
|
logger.trace('garbageCollecting ' + getNodeIdFromPeerDescriptor(peerDescriptor))
|
|
@@ -180,7 +203,7 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
180
203
|
this.state = ConnectionManagerState.RUNNING
|
|
181
204
|
logger.trace(`Starting ConnectionManager...`)
|
|
182
205
|
await this.connectorFacade.start(
|
|
183
|
-
(connection:
|
|
206
|
+
(connection: PendingConnection) => this.onNewConnection(connection),
|
|
184
207
|
(nodeId: DhtAddress) => this.hasConnection(nodeId),
|
|
185
208
|
this
|
|
186
209
|
)
|
|
@@ -188,8 +211,8 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
188
211
|
this.disconnectorIntervalRef = setInterval(() => {
|
|
189
212
|
logger.trace('disconnectorInterval')
|
|
190
213
|
const LAST_USED_LIMIT = 20000
|
|
191
|
-
this.garbageCollectConnections(this.
|
|
192
|
-
}, 5000) // TODO use
|
|
214
|
+
this.garbageCollectConnections(this.options.maxConnections ?? 80, LAST_USED_LIMIT)
|
|
215
|
+
}, 5000) // TODO use options option or named constant?
|
|
193
216
|
}
|
|
194
217
|
|
|
195
218
|
public async stop(): Promise<void> {
|
|
@@ -203,23 +226,25 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
203
226
|
}
|
|
204
227
|
await this.connectorFacade.stop()
|
|
205
228
|
|
|
206
|
-
await Promise.all(Array.from(this.
|
|
207
|
-
if (
|
|
229
|
+
await Promise.all(Array.from(this.endpoints.values()).map(async (endpoint) => {
|
|
230
|
+
if (endpoint.connected) {
|
|
208
231
|
try {
|
|
209
|
-
await this.gracefullyDisconnectAsync(
|
|
232
|
+
await this.gracefullyDisconnectAsync(endpoint.connection.getPeerDescriptor()!, DisconnectMode.LEAVING)
|
|
210
233
|
} catch (e) {
|
|
211
234
|
logger.error(e)
|
|
212
235
|
}
|
|
213
236
|
} else {
|
|
237
|
+
const connection = endpoint.connection
|
|
214
238
|
logger.trace('handshake of connection not completed, force-closing')
|
|
215
|
-
// TODO use
|
|
216
|
-
const eventReceived = waitForEvent3
|
|
239
|
+
// TODO use options option or named constant?
|
|
240
|
+
const eventReceived = waitForEvent3(connection as any, 'disconnected', 2000)
|
|
217
241
|
// TODO should we have some handling for this floating promise?
|
|
218
|
-
|
|
242
|
+
connection.close(true)
|
|
219
243
|
try {
|
|
220
244
|
await eventReceived
|
|
221
245
|
logger.trace('resolving after receiving disconnected event from non-handshaked connection')
|
|
222
246
|
} catch (e) {
|
|
247
|
+
endpoint.buffer.reject()
|
|
223
248
|
logger.trace('force-closing non-handshaked connection timed out ' + e)
|
|
224
249
|
}
|
|
225
250
|
}
|
|
@@ -230,10 +255,6 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
230
255
|
this.duplicateMessageDetector.clear()
|
|
231
256
|
this.locks.clear()
|
|
232
257
|
this.removeAllListeners()
|
|
233
|
-
// TODO would it make sense to move this call to WebrtcConnector#stop()?
|
|
234
|
-
// - but note that we should call this only after connections have been closed
|
|
235
|
-
// (i.e the this.gracefullyDisconnectAsync() calls above)
|
|
236
|
-
WEBRTC_CLEANUP.cleanUp()
|
|
237
258
|
}
|
|
238
259
|
|
|
239
260
|
public getLocalLockedConnectionCount(): number {
|
|
@@ -262,7 +283,7 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
262
283
|
...message,
|
|
263
284
|
sourceDescriptor: this.getLocalPeerDescriptor()
|
|
264
285
|
}
|
|
265
|
-
let connection = this.
|
|
286
|
+
let connection = this.endpoints.get(nodeId)?.connection
|
|
266
287
|
if (!connection && opts.connect) {
|
|
267
288
|
connection = this.connectorFacade.createConnection(peerDescriptor)
|
|
268
289
|
this.onNewConnection(connection)
|
|
@@ -272,7 +293,12 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
272
293
|
const binary = Message.toBinary(message)
|
|
273
294
|
this.metrics.sendBytesPerSecond.record(binary.byteLength)
|
|
274
295
|
this.metrics.sendMessagesPerSecond.record(1)
|
|
275
|
-
|
|
296
|
+
|
|
297
|
+
if (this.endpoints.get(nodeId)!.connected) {
|
|
298
|
+
return (connection as ManagedConnection).send(binary)
|
|
299
|
+
} else {
|
|
300
|
+
return (this.endpoints.get(nodeId)! as ConnectingEndpoint).buffer.push(binary)
|
|
301
|
+
}
|
|
276
302
|
}
|
|
277
303
|
|
|
278
304
|
private isConnectionToSelf(peerDescriptor: PeerDescriptor): boolean {
|
|
@@ -289,10 +315,6 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
289
315
|
}
|
|
290
316
|
}
|
|
291
317
|
|
|
292
|
-
public getConnection(nodeId: DhtAddress): ManagedConnection | undefined {
|
|
293
|
-
return this.connections.get(nodeId)
|
|
294
|
-
}
|
|
295
|
-
|
|
296
318
|
public getLocalPeerDescriptor(): PeerDescriptor {
|
|
297
319
|
return this.connectorFacade.getLocalPeerDescriptor()!
|
|
298
320
|
}
|
|
@@ -358,32 +380,47 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
358
380
|
}
|
|
359
381
|
}
|
|
360
382
|
|
|
361
|
-
private onConnected(connection:
|
|
362
|
-
const
|
|
383
|
+
private onConnected(peerDescriptor: PeerDescriptor, connection: IConnection) {
|
|
384
|
+
const managedConnection = new ManagedConnection(peerDescriptor, connection)
|
|
385
|
+
managedConnection.on('managedData', this.onData)
|
|
386
|
+
managedConnection.once('disconnected', (gracefulLeave: boolean) => this.onDisconnected(peerDescriptor, gracefulLeave))
|
|
387
|
+
|
|
388
|
+
const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
|
|
389
|
+
const endpoint = this.endpoints.get(nodeId)! as ConnectingEndpoint
|
|
390
|
+
const outputBuffer = endpoint.buffer
|
|
391
|
+
const pendingConnection = endpoint.connection
|
|
392
|
+
const buffer = outputBuffer.getBuffer()
|
|
393
|
+
while (buffer.length > 0) {
|
|
394
|
+
logger.trace('emptying buffer')
|
|
395
|
+
managedConnection.send(buffer.shift()!)
|
|
396
|
+
}
|
|
397
|
+
outputBuffer.resolve()
|
|
398
|
+
pendingConnection.destroy()
|
|
399
|
+
this.endpoints.set(nodeId, {
|
|
400
|
+
connected: true,
|
|
401
|
+
connection: managedConnection
|
|
402
|
+
})
|
|
363
403
|
this.emit('connected', peerDescriptor)
|
|
364
|
-
logger.trace(getNodeIdFromPeerDescriptor(peerDescriptor) + ' onConnected() ' + connection.connectionType)
|
|
365
404
|
this.onConnectionCountChange()
|
|
366
405
|
}
|
|
367
406
|
|
|
368
|
-
private onDisconnected(
|
|
369
|
-
const nodeId = getNodeIdFromPeerDescriptor(
|
|
407
|
+
private onDisconnected(peerDescriptor: PeerDescriptor, gracefulLeave: boolean) {
|
|
408
|
+
const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
|
|
370
409
|
logger.trace(nodeId + ' onDisconnected() gracefulLeave: ' + gracefulLeave)
|
|
371
|
-
const
|
|
372
|
-
if (
|
|
410
|
+
const endpoint = this.endpoints.get(nodeId)
|
|
411
|
+
if (endpoint) {
|
|
373
412
|
this.locks.clearAllLocks(nodeId)
|
|
374
|
-
|
|
413
|
+
if (endpoint.connected === false) {
|
|
414
|
+
endpoint.buffer.reject()
|
|
415
|
+
}
|
|
416
|
+
this.endpoints.delete(nodeId)
|
|
375
417
|
logger.trace(nodeId + ' deleted connection in onDisconnected() gracefulLeave: ' + gracefulLeave)
|
|
376
|
-
this.emit('disconnected',
|
|
418
|
+
this.emit('disconnected', peerDescriptor, gracefulLeave)
|
|
377
419
|
this.onConnectionCountChange()
|
|
378
|
-
} else {
|
|
379
|
-
logger.trace(nodeId + ' onDisconnected() did nothing, no such connection in connectionManager')
|
|
380
|
-
if (storedConnection) {
|
|
381
|
-
logger.trace(nodeId + ' connectionIds do not match ' + storedConnection.connectionId + ' ' + connection.connectionId.toString())
|
|
382
|
-
}
|
|
383
420
|
}
|
|
384
421
|
}
|
|
385
422
|
|
|
386
|
-
private onNewConnection(connection:
|
|
423
|
+
private onNewConnection(connection: PendingConnection): boolean {
|
|
387
424
|
if (this.state === ConnectionManagerState.STOPPED) {
|
|
388
425
|
return false
|
|
389
426
|
}
|
|
@@ -391,44 +428,44 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
391
428
|
if (!this.acceptNewConnection(connection)) {
|
|
392
429
|
return false
|
|
393
430
|
}
|
|
394
|
-
connection.
|
|
395
|
-
connection.
|
|
396
|
-
this.onDisconnected(connection, gracefulLeave)
|
|
397
|
-
})
|
|
398
|
-
if (connection.isHandshakeCompleted()) {
|
|
399
|
-
this.onConnected(connection)
|
|
400
|
-
} else {
|
|
401
|
-
connection.once('handshakeCompleted', () => {
|
|
402
|
-
this.onConnected(connection)
|
|
403
|
-
})
|
|
404
|
-
}
|
|
431
|
+
connection.once('connected', (peerDescriptor: PeerDescriptor, connection: IConnection) => this.onConnected(peerDescriptor, connection))
|
|
432
|
+
connection.once('disconnected', (gracefulLeave: boolean) => this.onDisconnected(connection.getPeerDescriptor(), gracefulLeave))
|
|
405
433
|
return true
|
|
406
434
|
}
|
|
407
435
|
|
|
408
|
-
private acceptNewConnection(newConnection:
|
|
409
|
-
const nodeId = getNodeIdFromPeerDescriptor(newConnection.getPeerDescriptor()
|
|
410
|
-
logger.trace(nodeId + '
|
|
411
|
-
if (this.
|
|
436
|
+
private acceptNewConnection(newConnection: PendingConnection): boolean {
|
|
437
|
+
const nodeId = getNodeIdFromPeerDescriptor(newConnection.getPeerDescriptor())
|
|
438
|
+
logger.trace(nodeId + ' acceptNewConnection()')
|
|
439
|
+
if (this.endpoints.has(nodeId)) {
|
|
412
440
|
if (getOfferer(getNodeIdFromPeerDescriptor(this.getLocalPeerDescriptor()), nodeId) === 'remote') {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
441
|
+
let buffer: OutputBuffer | undefined
|
|
442
|
+
const endpoint = this.endpoints.get(nodeId)!
|
|
443
|
+
// This is a rare occurance but it does happen from time to time.
|
|
444
|
+
// Could be related to WS client connections not realizing that they have been disconnected.
|
|
445
|
+
// Makes refactoring duplicate connection handling to the connectors very difficult.
|
|
446
|
+
if (this.endpoints.get(nodeId)!.connected) {
|
|
447
|
+
logger.debug('replacing connected connection', { nodeId })
|
|
448
|
+
buffer = new OutputBuffer()
|
|
449
|
+
} else {
|
|
450
|
+
buffer = (endpoint as ConnectingEndpoint).buffer
|
|
421
451
|
}
|
|
452
|
+
const oldConnection = endpoint.connection
|
|
453
|
+
logger.trace('replaced: ' + nodeId)
|
|
422
454
|
|
|
423
|
-
oldConnection.
|
|
424
|
-
|
|
455
|
+
oldConnection.replaceAsDuplicate()
|
|
456
|
+
this.endpoints.set(nodeId, { connected: false, connection: newConnection, buffer: buffer })
|
|
457
|
+
return true
|
|
425
458
|
} else {
|
|
426
459
|
return false
|
|
427
460
|
}
|
|
428
461
|
}
|
|
429
462
|
|
|
430
|
-
logger.trace(nodeId + ' added to connections at
|
|
431
|
-
this.
|
|
463
|
+
logger.trace(nodeId + ' added to connections at acceptNewConnection')
|
|
464
|
+
this.endpoints.set(nodeId, {
|
|
465
|
+
connected: false,
|
|
466
|
+
buffer: new OutputBuffer(),
|
|
467
|
+
connection: newConnection
|
|
468
|
+
})
|
|
432
469
|
|
|
433
470
|
return true
|
|
434
471
|
}
|
|
@@ -437,12 +474,11 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
437
474
|
const nodeId = getNodeIdFromPeerDescriptor(peerDescriptor)
|
|
438
475
|
logger.trace(nodeId + ' ' + 'closeConnection() ' + reason)
|
|
439
476
|
this.locks.clearAllLocks(nodeId)
|
|
440
|
-
if (this.
|
|
441
|
-
const connectionToClose = this.
|
|
477
|
+
if (this.endpoints.has(nodeId)) {
|
|
478
|
+
const connectionToClose = this.endpoints.get(nodeId)!.connection
|
|
442
479
|
await connectionToClose.close(gracefulLeave)
|
|
443
|
-
|
|
444
480
|
} else {
|
|
445
|
-
logger.trace(nodeId + ' ' + 'closeConnection() this.
|
|
481
|
+
logger.trace(nodeId + ' ' + 'closeConnection() this.endpoints did not have the id')
|
|
446
482
|
this.emit('disconnected', peerDescriptor, false)
|
|
447
483
|
}
|
|
448
484
|
}
|
|
@@ -476,7 +512,7 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
476
512
|
this.rpcCommunicator!,
|
|
477
513
|
ConnectionLockRpcClient
|
|
478
514
|
)
|
|
479
|
-
if (this.
|
|
515
|
+
if (this.endpoints.has(nodeId)) {
|
|
480
516
|
rpcRemote.unlockRequest(lockId)
|
|
481
517
|
}
|
|
482
518
|
}
|
|
@@ -496,35 +532,40 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
496
532
|
}
|
|
497
533
|
|
|
498
534
|
private async gracefullyDisconnectAsync(targetDescriptor: PeerDescriptor, disconnectMode: DisconnectMode): Promise<void> {
|
|
535
|
+
const endpoint = this.endpoints.get(getNodeIdFromPeerDescriptor(targetDescriptor))
|
|
499
536
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (!connection) {
|
|
537
|
+
if (!endpoint) {
|
|
503
538
|
logger.debug('gracefullyDisconnectedAsync() tried on a non-existing connection')
|
|
504
539
|
return
|
|
505
540
|
}
|
|
506
541
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
logger.trace('force-closing connection after timeout ' + e)
|
|
515
|
-
// TODO should we have some handling for this floating promise?
|
|
516
|
-
connection.close(true)
|
|
542
|
+
if (endpoint.connected) {
|
|
543
|
+
const connection = endpoint.connection
|
|
544
|
+
const promise = new Promise<void>((resolve, _reject) => {
|
|
545
|
+
// TODO use options option or named constant?
|
|
546
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
547
|
+
waitForEvent3<ManagedConnectionEvents>(connection, 'disconnected', 2000).then(() => {
|
|
548
|
+
logger.trace('disconnected event received in gracefullyDisconnectAsync()')
|
|
517
549
|
})
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
550
|
+
.catch((e) => {
|
|
551
|
+
logger.trace('force-closing connection after timeout ' + e)
|
|
552
|
+
// TODO should we have some handling for this floating promise?
|
|
553
|
+
connection.close(true)
|
|
554
|
+
})
|
|
555
|
+
.finally(() => {
|
|
556
|
+
logger.trace('resolving after receiving disconnected event')
|
|
557
|
+
resolve()
|
|
558
|
+
})
|
|
559
|
+
})
|
|
560
|
+
|
|
561
|
+
await Promise.all([
|
|
562
|
+
promise,
|
|
563
|
+
this.doGracefullyDisconnectAsync(targetDescriptor, disconnectMode)
|
|
564
|
+
])
|
|
565
|
+
} else {
|
|
566
|
+
endpoint.connection.close(true)
|
|
567
|
+
}
|
|
568
|
+
|
|
528
569
|
}
|
|
529
570
|
|
|
530
571
|
private async doGracefullyDisconnectAsync(targetDescriptor: PeerDescriptor, disconnectMode: DisconnectMode): Promise<void> {
|
|
@@ -544,14 +585,15 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
544
585
|
}
|
|
545
586
|
|
|
546
587
|
public getConnections(): PeerDescriptor[] {
|
|
547
|
-
return Array.from(this.
|
|
588
|
+
return Array.from(this.endpoints.values())
|
|
589
|
+
.map((endpoint) => endpoint)
|
|
548
590
|
// TODO is this filtering needed? (if it is, should we do the same filtering e.g.
|
|
549
|
-
// in getConnection() or in other methods which access this.
|
|
550
|
-
.filter((
|
|
551
|
-
.map((
|
|
591
|
+
// in getConnection() or in other methods which access this.endpoints directly?)
|
|
592
|
+
.filter((endpoint) => endpoint.connected)
|
|
593
|
+
.map((endpoint) => endpoint.connection.getPeerDescriptor()!)
|
|
552
594
|
}
|
|
553
595
|
|
|
554
596
|
private onConnectionCountChange() {
|
|
555
|
-
this.metrics.connectionAverageCount.record(this.
|
|
597
|
+
this.metrics.connectionAverageCount.record(this.endpoints.size)
|
|
556
598
|
}
|
|
557
599
|
}
|