@@ -12,30 +12,14 @@ import ipaddr = require('ipaddr.js');
1212import logging = require( '../logging/logging' ) ;
1313import net = require( '../net/net.types' ) ;
1414import PassThrough = require( '../transformers/passthrough' ) ;
15+ import promises = require( '../promises/promises' ) ;
1516import protean = require( '../transformers/protean' ) ;
1617import sequence = require( '../transformers/byteSequenceShaper' ) ;
1718
1819import Socket = freedom . UdpSocket . Socket ;
1920
2021var log :logging . Log = new logging . Log ( 'churn-pipe' ) ;
2122
22- // Retry an async function with exponential backoff for up to 2 seconds
23- // before failing.
24- var retry_ = < T > ( func :( ) => Promise < T > , delayMs ?:number ) : Promise < T > => {
25- delayMs = delayMs || 10 ;
26- return func ( ) . catch ( ( err ) => {
27- delayMs *= 2 ;
28- if ( delayMs > 2000 ) {
29- return Promise . reject ( err ) ;
30- }
31- return new Promise < T > ( ( F , R ) => {
32- setTimeout ( ( ) => {
33- retry_ ( func , delayMs ) . then ( F , R ) ;
34- } , delayMs ) ;
35- } ) ;
36- } ) ;
37- }
38-
3923// Maps transformer names to class constructors.
4024var transformers :{ [ name :string ] : new ( ) => Transformer } = {
4125 'caesar' : caesar . CaesarCipher ,
@@ -47,6 +31,10 @@ var transformers :{[name:string] : new() => Transformer} = {
4731 'sequenceShaper' : sequence . ByteSequenceShaper
4832} ;
4933
34+ // Local socket rebinding retry timing (see bindLocal)
35+ const INITIAL_REBIND_INTERVAL_MS = 10 ;
36+ const MAX_REBIND_INTERVAL_MS = 2000 ;
37+
5038interface MirrorSet {
5139 // If true, these mirrors represent a remote endpoint that has been
5240 // explicitly signaled to us.
@@ -198,13 +186,13 @@ class Pipe {
198186 // This retry is needed because the browser releases the UDP port
199187 // asynchronously after we call close() on the RTCPeerConnection, so
200188 // this call to bind() may initially fail, until the port is released.
201- portPromise = retry_ ( ( ) => {
189+ portPromise = promises . retryWithExponentialBackoff ( ( ) => {
202190 log . debug ( '%1: trying to bind public endpoint: %2' ,
203191 this . name_ , publicEndpoint ) ;
204192 // TODO: Once https://github.com/freedomjs/freedom/issues/283 is
205193 // fixed, catch here, and only retry on an ALREADY_BOUND error.
206194 return socket . bind ( anyInterface , publicEndpoint . port ) ;
207- } ) . then ( ( ) => {
195+ } , MAX_REBIND_INTERVAL_MS , INITIAL_REBIND_INTERVAL_MS ) . then ( ( ) => {
208196 log . debug ( '%1: successfully bound public endpoint: %2' ,
209197 this . name_ , publicEndpoint ) ;
210198 socket . on ( 'onData' , ( recvFromInfo :freedom . UdpSocket . RecvFromInfo ) => {
0 commit comments