Socket request timeout handling, with retries.
parent
b0e57756cb
commit
0f184a3a29
|
|
@ -37,7 +37,8 @@ var config =
|
||||||
'opera'
|
'opera'
|
||||||
],
|
],
|
||||||
// Socket.io request timeout
|
// Socket.io request timeout
|
||||||
requestTimeout : 10000,
|
requestTimeout : 20000,
|
||||||
|
requestRetries : 3,
|
||||||
transportOptions :
|
transportOptions :
|
||||||
{
|
{
|
||||||
tcp : true
|
tcp : true
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import Logger from './Logger';
|
import Logger from './Logger';
|
||||||
import hark from 'hark';
|
import hark from 'hark';
|
||||||
import { getSignalingUrl } from './urlFactory';
|
import { getSignalingUrl } from './urlFactory';
|
||||||
|
import { SocketTimeoutError } from './utils';
|
||||||
import * as requestActions from './actions/requestActions';
|
import * as requestActions from './actions/requestActions';
|
||||||
import * as meActions from './actions/meActions';
|
import * as meActions from './actions/meActions';
|
||||||
import * as roomActions from './actions/roomActions';
|
import * as roomActions from './actions/roomActions';
|
||||||
|
|
@ -574,7 +575,7 @@ export default class RoomClient
|
||||||
if (called)
|
if (called)
|
||||||
return;
|
return;
|
||||||
called = true;
|
called = true;
|
||||||
callback(new Error('Request timeout.'));
|
callback(new SocketTimeoutError('Request timed out'));
|
||||||
},
|
},
|
||||||
ROOM_OPTIONS.requestTimeout
|
ROOM_OPTIONS.requestTimeout
|
||||||
);
|
);
|
||||||
|
|
@ -590,13 +591,13 @@ export default class RoomClient
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest(method, data)
|
_sendRequest(method, data)
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
{
|
{
|
||||||
if (!this._signalingSocket)
|
if (!this._signalingSocket)
|
||||||
{
|
{
|
||||||
reject('No socket connection.');
|
reject('No socket connection');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -606,19 +607,42 @@ export default class RoomClient
|
||||||
this.timeoutCallback((err, response) =>
|
this.timeoutCallback((err, response) =>
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
{
|
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendRequest(method, data)
|
||||||
|
{
|
||||||
|
logger.debug('sendRequest() [method:"%s", data:"%o"]', method, data);
|
||||||
|
|
||||||
|
const {
|
||||||
|
requestRetries = 3
|
||||||
|
} = window.config;
|
||||||
|
|
||||||
|
for (let tries = 0; tries < requestRetries; tries++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await this._sendRequest(method, data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
error instanceof SocketTimeoutError &&
|
||||||
|
tries < requestRetries
|
||||||
|
)
|
||||||
|
logger.warn('sendRequest() | timeout, retrying [attempt:"%s"]', tries);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async changeDisplayName(displayName)
|
async changeDisplayName(displayName)
|
||||||
{
|
{
|
||||||
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,21 @@ export const idle = (callback, delay) =>
|
||||||
handle = setTimeout(callback, delay);
|
handle = setTimeout(callback, delay);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error produced when a socket request has a timeout.
|
||||||
|
*/
|
||||||
|
export class SocketTimeoutError extends Error
|
||||||
|
{
|
||||||
|
constructor(message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'SocketTimeoutError';
|
||||||
|
|
||||||
|
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
|
||||||
|
Error.captureStackTrace(this, SocketTimeoutError);
|
||||||
|
else
|
||||||
|
this.stack = (new Error(message)).stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -276,6 +276,10 @@ module.exports =
|
||||||
// maxUsersPerRoom : 20,
|
// maxUsersPerRoom : 20,
|
||||||
// Room size before spreading to new router
|
// Room size before spreading to new router
|
||||||
routerScaleSize : 40,
|
routerScaleSize : 40,
|
||||||
|
// Socket timout value
|
||||||
|
requestTimeout : 20000,
|
||||||
|
// Socket retries when timeout
|
||||||
|
requestRetries : 3,
|
||||||
// Mediasoup settings
|
// Mediasoup settings
|
||||||
mediasoup :
|
mediasoup :
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const AwaitQueue = require('awaitqueue');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const Logger = require('./Logger');
|
const Logger = require('./Logger');
|
||||||
const Lobby = require('./Lobby');
|
const Lobby = require('./Lobby');
|
||||||
|
const { SocketTimeoutError } = require('./errors');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const userRoles = require('../userRoles');
|
const userRoles = require('../userRoles');
|
||||||
|
|
@ -1759,9 +1760,9 @@ class Room extends EventEmitter
|
||||||
if (called)
|
if (called)
|
||||||
return;
|
return;
|
||||||
called = true;
|
called = true;
|
||||||
callback(new Error('Request timeout.'));
|
callback(new SocketTimeoutError('Request timed out'));
|
||||||
},
|
},
|
||||||
10000
|
config.requestTimeout || 20000
|
||||||
);
|
);
|
||||||
|
|
||||||
return (...args) =>
|
return (...args) =>
|
||||||
|
|
@ -1775,7 +1776,7 @@ class Room extends EventEmitter
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_request(socket, method, data = {})
|
_sendRequest(socket, method, data = {})
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
{
|
{
|
||||||
|
|
@ -1797,6 +1798,33 @@ class Room extends EventEmitter
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _request(socket, method, data)
|
||||||
|
{
|
||||||
|
logger.debug('_request() [method:"%s", data:"%o"]', method, data);
|
||||||
|
|
||||||
|
const {
|
||||||
|
requestRetries = 3
|
||||||
|
} = config;
|
||||||
|
|
||||||
|
for (let tries = 0; tries < requestRetries; tries++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await this._sendRequest(socket, method, data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
error instanceof SocketTimeoutError &&
|
||||||
|
tries < requestRetries
|
||||||
|
)
|
||||||
|
logger.warn('_request() | timeout, retrying [attempt:"%s"]', tries);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_notification(socket, method, data = {}, broadcast = false, includeSender = false)
|
_notification(socket, method, data = {}, broadcast = false, includeSender = false)
|
||||||
{
|
{
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* Error produced when a socket request has a timeout.
|
||||||
|
*/
|
||||||
|
class SocketTimeoutError extends Error
|
||||||
|
{
|
||||||
|
constructor(message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'SocketTimeoutError';
|
||||||
|
|
||||||
|
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
|
||||||
|
Error.captureStackTrace(this, SocketTimeoutError);
|
||||||
|
else
|
||||||
|
this.stack = (new Error(message)).stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
{
|
||||||
|
SocketTimeoutError
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue