Skip to content

Commit

Permalink
Add PromiseEvents. Closes #1939
Browse files Browse the repository at this point in the history
  • Loading branch information
brollb committed Oct 1, 2020
1 parent c259f9b commit 515174f
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 25 deletions.
4 changes: 4 additions & 0 deletions src/common/EventEmitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ define([
) {
class EventEmitter {
constructor() {
this.init();
}

init() {
this._handlers = {};
}

Expand Down
33 changes: 33 additions & 0 deletions src/common/PromiseEvents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*globals define*/
define([
'deepforge/EventEmitter',
'deepforge/utils',
], function(
EventEmitter,
utils,
) {
class PromiseEvents extends Promise {
constructor(fn) {
super(fn);
this.init();
}

static new(fn) {
let promise;
promise = new PromiseEvents(async function(resolve, reject) {
await utils.yield();
return fn.call(promise, resolve, reject);
});
return promise;
}
}

const methods = Object.getOwnPropertyNames(EventEmitter.prototype)
.filter(fn => !PromiseEvents.prototype[fn]);

methods.forEach(fn => {
PromiseEvents.prototype[fn] = EventEmitter.prototype[fn];
});

return PromiseEvents;
});
29 changes: 4 additions & 25 deletions src/common/compute/interactive/session.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/* globals define */
define([
'deepforge/utils',
'deepforge/PromiseEvents',
'deepforge/compute/interactive/task',
'deepforge/compute/interactive/message',
'deepforge/compute/interactive/errors',
'deepforge/gmeConfig',
], function(
utils,
PromiseEvents,
Task,
Message,
Errors,
Expand Down Expand Up @@ -167,8 +169,7 @@ define([
const address = gmeConfig.extensions.InteractiveComputeHost ||
getDefaultServerURL();

let createSession;
createSession = new PromiseEvents(function(resolve, reject) {
return PromiseEvents.new(function(resolve, reject) {
const ws = new WebSocket(address);
ws.onopen = () => {
ws.send(JSON.stringify([computeID, config, getGMEToken()]));
Expand All @@ -189,33 +190,11 @@ define([
const err = msg.data;
reject(err);
} else if (msg.type === Message.STATUS) {
createSession.emit('update', msg.data);
this.emit('update', msg.data);
}
};
};
});

return createSession;
}
}

class PromiseEvents extends Promise {
constructor(fn) {
super(fn);
this._handlers = {};
}

on(event, fn) {
if (!this._handlers[event]) {
this._handlers[event] = [];
}
this._handlers[event].push(fn);
}

emit(event) {
const handlers = this._handlers[event] || [];
const args = Array.prototype.slice.call(arguments, 1);
handlers.forEach(fn => fn.apply(null, args));
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@
return deferred.promise;
}

function yield() {
return sleep(0);
}

async function waitUntil(fn, interval=50) {
while (!await fn()) {
await sleep(interval);
Expand All @@ -167,6 +171,7 @@
withTimeout,
defer,
sleep,
yield,
waitUntil,
partition,
};
Expand Down
26 changes: 26 additions & 0 deletions test/unit/common/PromiseEvents.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
describe('PromiseEvents', function() {
const assert = require('assert');
const testFixture = require('../../globals');
const PromiseEvents = testFixture.requirejs('deepforge/PromiseEvents');

it('should resolve as a promise', async function() {
const five = await PromiseEvents.new(
resolve => setTimeout(() => resolve(5), 5)
);
assert.equal(five, 5);
});

it('should support updates', async function() {
const promise = PromiseEvents.new(function(resolve) {
for (let i = 1; i < 6; i++) {
this.emit('update', i);
}
resolve(6);
});
const events = [];
promise.on('update', status => events.push(status));
const six = await promise;
assert.equal(events.length, 5);
assert.equal(six, 6);
});
});

0 comments on commit 515174f

Please sign in to comment.