Skip to content

Commit

Permalink
Refactor queue logic
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreyBelym committed May 17, 2017
1 parent 6a5c45d commit ffbc6eb
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 34 deletions.
47 changes: 14 additions & 33 deletions src/browser/connection/gateway.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import Promise from 'pinkie';
import promisifyEvent from 'promisify-event';
import timeLimit from 'time-limit-promise';
import { readSync as read } from 'read-file-relative';
import { respond404, respond500, respondWithJSON, redirect, preventCaching } from '../../utils/http';
import RemotesQueue from './remotes-queue';


// Const
const IDLE_PAGE_SCRIPT = read('../../client/browser/idle-page/index.js');
const IDLE_PAGE_STYLE = read('../../client/browser/idle-page/styles.css');
const IDLE_PAGE_LOGO = read('../../client/browser/idle-page/logo.svg', true);

const REMOTE_REDIRECT_TIMEOUT = 10000;

// Gateway
export default class BrowserConnectionGateway {
constructor (proxy) {
this.connections = {};
this.pendingRemotesPromise = Promise.resolve({});
this.domain = proxy.server1Info.domain;
this.connections = {};
this.remotesQueue = new RemotesQueue();
this.domain = proxy.server1Info.domain;

this.connectUrl = `${this.domain}/browser/connect`;

Expand Down Expand Up @@ -122,44 +118,29 @@ export default class BrowserConnectionGateway {
}

async _connectNextRemoteBrowser (req, res) {
var pendingRemotes = await this.pendingRemotesPromise;
var pendingId = Object.keys(pendingRemotes)[0];

if (!pendingId)
return;
preventCaching(res);

this.pendingRemotesPromise = timeLimit(pendingRemotes[pendingId], REMOTE_REDIRECT_TIMEOUT)
.then(() => pendingRemotes);
var remoteConnection = await this.remotesQueue.shift();

redirect(res, this.connections[pendingId].url);
if (remoteConnection)
redirect(res, remoteConnection.url);
else
respond500(res, 'There are no available connections to establish.');
}

// API
startServingConnection (connection) {
this.connections[connection.id] = connection;

if (connection.browserInfo.providerName === 'remote') {
this.pendingRemotesPromise = this.pendingRemotesPromise
.then(pendingRemotes => {
pendingRemotes[connection.id] = promisifyEvent(connection, 'ready')
.then(() => delete pendingRemotes[connection.id]);

return pendingRemotes;
});
}
if (connection.browserInfo.providerName === 'remote')
this.remotesQueue.add(connection);
}

stopServingConnection (connection) {
delete this.connections[connection.id];

if (connection.browserInfo.providerName === 'remote') {
this.pendingRemotesPromise = this.pendingRemotesPromise
.then(pendingRemotes => {
delete pendingRemotes[connection.id];

return pendingRemotes;
});
}
if (connection.browserInfo.providerName === 'remote')
this.remotesQueue.remove(connection);
}

close () {
Expand Down
54 changes: 54 additions & 0 deletions src/browser/connection/remotes-queue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Promise from 'pinkie';
import { EventEmitter } from 'events';
import promisifyEvent from 'promisify-event';
import timeLimit from 'time-limit-promise';


const REMOTE_REDIRECT_TIMEOUT = 10000;
const ADDING_CONNECTION_WAITING_TIMEOUT = 10000;

export default class RemotesQueue {
constructor () {
this.events = new EventEmitter();
this.shiftingTimeout = Promise.resolve();
this.pendingConnections = {};
}

add (remoteConnection) {
var connectionReadyPromise = promisifyEvent(remoteConnection, 'ready')
.then(() => this.remove(remoteConnection));

this.pendingConnections[remoteConnection.id] = {
connection: remoteConnection,
readyPromise: connectionReadyPromise
};

this.events.emit('connection-added', remoteConnection.id);
}

remove (remoteConnection) {
delete this.pendingConnections[remoteConnection.id];
}

shift () {
var shiftingPromise = this.shiftingTimeout
.then(async () => {
var headId = Object.keys(this.pendingConnections)[0];

if (!headId)
headId = await timeLimit(promisifyEvent(this.events, 'connection-added'), ADDING_CONNECTION_WAITING_TIMEOUT);

return headId ? this.pendingConnections[headId].connection : null;
});

this.shiftingTimeout = shiftingPromise
.then(connection => {
if (!connection)
return Promise.resolve();

return timeLimit(this.pendingConnections[connection.id].readyPromise, REMOTE_REDIRECT_TIMEOUT);
});

return shiftingPromise;
}
}
2 changes: 1 addition & 1 deletion src/cli/remotes-wizard.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default async function (testCafe, remoteCount, showQRCode) {

var description = dedent(`
Connecting ${remoteCount} remote browser(s)...
Navigate to the appropriate URL from each of the remote browsers.
Navigate to the following URL from each of the remote browsers.
`);

log.write(description);
Expand Down

0 comments on commit ffbc6eb

Please sign in to comment.