diff --git a/kbase-extension/static/kbase/js/common/data.js b/kbase-extension/static/kbase/js/common/data.js index 396369dd34..c9cb37b13e 100644 --- a/kbase-extension/static/kbase/js/common/data.js +++ b/kbase-extension/static/kbase/js/common/data.js @@ -3,6 +3,7 @@ define(['kb_service/client/workspace', 'kb_service/utils', 'common/runtime'], ( ServiceUtils, Runtime ) => { + 'use strict'; function filterObjectInfoByType(objects, types) { return objects .map((objectInfo) => { @@ -16,26 +17,6 @@ define(['kb_service/client/workspace', 'kb_service/utils', 'common/runtime'], ( }); } - // function getObjectsByTypes(types, bus, onUpdated) { - // return bus.channel('data').when('workspace-data-updated') - // .then(function(message) { - // if (onUpdated) { - // bus.channel('data').on('workspace-data-updated', function(message) { - // var result = { - // data: filterObjectInfoByType(message.objectInfo, types), - // timestamp: message.timestamp - // } - // onUpdated(result); - // }); - // } - // var result = { - // data: filterObjectInfoByType(message.objectInfo, types), - // timestamp: message.timestamp - // } - // return result; - // }) - // } - function getObjectsByTypes(types, connection, onUpdated) { const listener = connection.channel('data').plisten({ key: { @@ -50,11 +31,10 @@ define(['kb_service/client/workspace', 'kb_service/utils', 'common/runtime'], ( }, }); return listener.promise.then((message) => { - const result = { + return { data: filterObjectInfoByType(message.objectInfo, types), timestamp: message.timestamp, }; - return result; }); } @@ -71,9 +51,8 @@ define(['kb_service/client/workspace', 'kb_service/utils', 'common/runtime'], ( }); // assume (for now) that the refs are valid and not random strings or numbers or objects. - const refList = []; - refs.forEach((ref) => { - refList.push({ ref: ref }); + const refList = refs.map((ref) => { + return { ref }; }); return workspace.get_object_info_new({ objects: refList }).then((infos) => { const objInfos = {}; @@ -89,7 +68,7 @@ define(['kb_service/client/workspace', 'kb_service/utils', 'common/runtime'], ( } return { - getObjectsByTypes: getObjectsByTypes, - getObjectsByRef: getObjectsByRef, + getObjectsByTypes, + getObjectsByRef, }; }); diff --git a/kbase-extension/static/kbase/js/common/iframe/messages.js b/kbase-extension/static/kbase/js/common/iframe/messages.js index 16f42810c1..2929533814 100644 --- a/kbase-extension/static/kbase/js/common/iframe/messages.js +++ b/kbase-extension/static/kbase/js/common/iframe/messages.js @@ -1,13 +1,13 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { - function factory(config) { - const root = config.root; - const name = config.name; + 'use strict'; + function factory(config) { + const { root, name } = config; const serviceId = new Uuid(4).format(); let lastId = 0; //: number; - let sentCount; //: number; - let receivedCount; //: number; + // let sentCount; //: number; + // let receivedCount; //: number; const partners = {}; // Map; const listeners = {}; //Map>; const awaitingResponse = {}; //: Map; @@ -17,8 +17,8 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { return 'msg_' + String(lastId); } - function addPartner(config) { - partners[config.name] = config; + function addPartner(_config) { + partners[_config.name] = _config; } function listen(listener) { @@ -29,12 +29,10 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { } function receive(event) { - let origin = event.origin || event.originalEvent.origin, - message = event.data, - listener, - response; + const message = event.data; + let response; - receivedCount += 1; + // receivedCount += 1; if (!message.address && !message.address.to) { console.warn('Message without address.to - ignored (iframe)', message); @@ -42,7 +40,6 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { } if (message.address.to !== serviceId) { - // console.log('not for us (iframe) ... ignoring', message, serviceId); return; } @@ -58,9 +55,9 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { } if (listeners[message.name]) { - listeners[message.name].forEach((listener) => { + listeners[message.name].forEach((_listener) => { try { - listener.handler(message); + _listener.handler(message); return; } catch (ex) { console.error('Error handling listener for message ', message, ex); @@ -69,11 +66,11 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { } } - function getPartner(name) { - if (!partners[name]) { - throw new Error('Partner ' + name + ' not registered'); + function getPartner(_name) { + if (!partners[_name]) { + throw new Error('Partner ' + _name + ' not registered'); } - return partners[name]; + return partners[_name]; } function send(partnerName, message) { @@ -83,7 +80,7 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { to: partner.serviceId, from: serviceId, }; - sentCount += 1; + // sentCount += 1; partner.window.postMessage(message, partner.host); } @@ -98,7 +95,7 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { } function request(partnerName, message) { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { sendRequest(partnerName, message, (response) => { resolve(response); }); @@ -114,14 +111,14 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { } return Object.freeze({ - start: start, - stop: stop, - send: send, - request: request, - receive: receive, - listen: listen, - addPartner: addPartner, - serviceId: serviceId, + start, + stop, + send, + request, + receive, + listen, + addPartner, + serviceId, }); } diff --git a/kbase-extension/static/kbase/js/common/jobCommChannel.js b/kbase-extension/static/kbase/js/common/jobCommChannel.js index dc1c32971c..4e4daee02a 100644 --- a/kbase-extension/static/kbase/js/common/jobCommChannel.js +++ b/kbase-extension/static/kbase/js/common/jobCommChannel.js @@ -16,17 +16,19 @@ * request. * 2. This gets captured by one of the callbacks in handleBusMessages() * 3. These all invoke sendCommMessage(). This builds a message packet and sends it across the - * comm channel where it gets heard by a capturing function in biokbase.narrative.jobmanager. - * ...that's it. These messages are asynchronous by design. They're meant to be requests that - * get responses eventually. + * comm channel where it gets heard by a capturing function in biokbase.narrative.jobs.jobcomm + * + * These messages are asynchronous by design. They're meant to be requests that get responses + * eventually. * * From the back end to the front, the flow is slightly different. On Comm channel creation time, * the handleCommMessages function is set up as the callback for anything that comes across the * channel to the front end. Each of these has a message type associated with it. - * 1. The type is interepreted (a big ol' switch statement) and responded to. - * 2. Most responses (job status updates, log messages) are parceled out to the App Cells that - * invoked them. Or, really, anything listening on the appropriate channel (either the cell, - * or the job id) + * + * 1. The type is interpreted (a big ol' switch statement) and responded to. + * 2. Responses (job status updates, log messages) are "addressed" using either a job or a cell + * ID and a message type. Any frontend component with a listener of the appropriate type on + * the appropriate channel can pick up and act upon the content of the messages. */ define([ 'bluebird', @@ -116,7 +118,7 @@ define([ /** * Sends a message over the bus. The channel should have a single key of either - * cell or jobId. + * cell or job ID. * @param {string} channelType - either CELL or JOB * @param {string} channelId - id for the channel * @param {string} msgType - one of the msg types @@ -136,9 +138,9 @@ define([ } /** - * Registers callbacks for handling bus messages. This listens to the global runtime bus. - * Mostly, it relays bus messages into comm channel requests that are satisfied by the - * kernel. + * Registers callbacks for handling bus messages. This listens to the global runtime + * bus, and relays requests from frontend components to the narrative backend to be + * completed by the kernel. */ handleBusMessages() { const bus = this.runtime.bus(); @@ -192,11 +194,12 @@ define([ * If no arguments are supplied to sendCommMessage, the stored messages (if any) * will be sent. * - * @param {string} msgType - message type; will be one of the - * values in the REQUESTS object (optional) + * @param {string} msgType - message type; will be one of the + * values in the REQUESTS object (optional) * - * @param {object} msgData - additional parameters for the request, - * such as jobId or jobIdList, or an 'options' object (optional) + * @param {object} msgData - additional parameters for the request, + * such as one of the values in the PARAMS object or + * a request-specific param (optional) */ sendCommMessage(msgType, msgData) { if (msgType && msgData) { @@ -244,9 +247,7 @@ define([ * } * } * } - * Where msg_type is one of: - * start, new_job, job_status, job_status_all, job_comm_err, job_init_err, job_init_lookup_err, - * or any of the values of RESPONSES + * where msg_type is one of the values of RESPONSES * * @param {object} msg */ diff --git a/kbase-extension/static/kbase/js/common/jobManager.js b/kbase-extension/static/kbase/js/common/jobManager.js index 98d40126d9..c6fc4181b5 100644 --- a/kbase-extension/static/kbase/js/common/jobManager.js +++ b/kbase-extension/static/kbase/js/common/jobManager.js @@ -284,6 +284,7 @@ define([ channelObject = { [jcm.CHANNELS.CELL]: channel }; } + // listen for job-related bus messages this.listeners[channel][type] = this.bus.listen({ channel: channelObject, key: { diff --git a/kbase-extension/static/kbase/js/util/jobLogViewer.js b/kbase-extension/static/kbase/js/util/jobLogViewer.js index 19bd7b4825..8f6edeb7e6 100644 --- a/kbase-extension/static/kbase/js/util/jobLogViewer.js +++ b/kbase-extension/static/kbase/js/util/jobLogViewer.js @@ -1263,6 +1263,7 @@ define([ Object.keys(handlers).forEach((type) => { // ensure that the correct `this` context is bound const handle = handlers[type].bind(this); + // listen for job-related bus messages this.listenersByType[jcm.RESPONSES[type]] = this.bus.listen({ channel: { [jcm.CHANNELS.JOB]: this.jobId }, key: { type: jcm.RESPONSES[type] }, diff --git a/kbase-extension/static/kbase/js/util/jobStateViewer.js b/kbase-extension/static/kbase/js/util/jobStateViewer.js index 8f24c7aafb..6d014bf23f 100644 --- a/kbase-extension/static/kbase/js/util/jobStateViewer.js +++ b/kbase-extension/static/kbase/js/util/jobStateViewer.js @@ -371,6 +371,7 @@ define([ */ function listenForJobStatus() { listeners.push( + // listen for job-related bus messages runtime.bus().listen({ channel: { [jcm.CHANNELS.JOB]: jobId, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/customWidgetWrapper.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/customWidgetWrapper.js index 88c4dac950..523cd5efbb 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/customWidgetWrapper.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/customWidgetWrapper.js @@ -76,6 +76,7 @@ define(['bluebird', 'jquery', 'base/js/namespace', 'common/runtime', 'common/job }, } ); + // listen for cell-related bus messages runtime.bus().listen({ channel: { [jcm.CHANNELS.CELL]: cellId, diff --git a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeJobStatus.js b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeJobStatus.js index f3a02f7414..c6ba67520b 100644 --- a/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeJobStatus.js +++ b/kbase-extension/static/kbase/js/widgets/narrative_core/kbaseNarrativeJobStatus.js @@ -141,6 +141,7 @@ define([ Semaphore.make() .when('comm', 'ready', Config.get('comm_wait_timeout')) .then(() => { + // listen for job-related bus messages this.busConnection.listen({ channel: { [jcm.CHANNELS.JOB]: this.jobId, @@ -153,6 +154,7 @@ define([ }.bind(this), }); + // listen for job-related bus messages this.busConnection.listen({ channel: { [jcm.CHANNELS.JOB]: this.jobId, diff --git a/nbextensions/appCell2/widgets/appCellWidget.js b/nbextensions/appCell2/widgets/appCellWidget.js index 641fd9a561..49d9f50d43 100644 --- a/nbextensions/appCell2/widgets/appCellWidget.js +++ b/nbextensions/appCell2/widgets/appCellWidget.js @@ -1410,6 +1410,7 @@ define( function startListeningForJobMessages(jobId) { jobListeners.push( + // listen for job-related bus messages runtime.bus().listen({ channel: { jobId, diff --git a/nbextensions/appCell2/widgets/tabs/status/jobInputParams.js b/nbextensions/appCell2/widgets/tabs/status/jobInputParams.js index fe37a81011..61d8651054 100644 --- a/nbextensions/appCell2/widgets/tabs/status/jobInputParams.js +++ b/nbextensions/appCell2/widgets/tabs/status/jobInputParams.js @@ -56,6 +56,7 @@ define([ } function startParamsListener() { + // listen for job-related bus messages paramsListener = runtime.bus().listen({ channel: { [jcm.CHANNELS.JOB]: jobId, diff --git a/nbextensions/appCell2/widgets/tabs/status/jobStateList.js b/nbextensions/appCell2/widgets/tabs/status/jobStateList.js index 3c84164676..db7053b960 100644 --- a/nbextensions/appCell2/widgets/tabs/status/jobStateList.js +++ b/nbextensions/appCell2/widgets/tabs/status/jobStateList.js @@ -66,6 +66,7 @@ define([ } function startParentListener() { + // listen for job-related bus messages parentListener = runtime.bus().listen({ channel: { [jcm.CHANNELS.JOB]: parentJobId, diff --git a/package-lock.json b/package-lock.json index e68cd6eb5a..615d07dd18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2390,9 +2390,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001286", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001286.tgz", - "integrity": "sha512-zaEMRH6xg8ESMi2eQ3R4eZ5qw/hJiVsO/HlLwniIwErij0JDr9P+8V4dtx1l+kLq6j3yy8l8W4fst1lBnat5wQ==", + "version": "1.0.30001300", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz", + "integrity": "sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA==", "dev": true, "funding": { "type": "opencollective", @@ -18000,9 +18000,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001286", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001286.tgz", - "integrity": "sha512-zaEMRH6xg8ESMi2eQ3R4eZ5qw/hJiVsO/HlLwniIwErij0JDr9P+8V4dtx1l+kLq6j3yy8l8W4fst1lBnat5wQ==", + "version": "1.0.30001300", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz", + "integrity": "sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA==", "dev": true }, "center-align": { diff --git a/package.json b/package.json index 007b8cbba5..0e750857ee 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,10 @@ "*.js": [ "eslint --fix", "prettier --ignore-unknown --write" + ], + "*.py": [ + "npm run flake8", + "npm run black" ] }, "dependencies": { diff --git a/test/unit/spec/common/jobCommChannel-spec.js b/test/unit/spec/common/jobCommChannel-spec.js index e311804b14..b456385d25 100644 --- a/test/unit/spec/common/jobCommChannel-spec.js +++ b/test/unit/spec/common/jobCommChannel-spec.js @@ -5,7 +5,8 @@ define([ '/test/data/jobsData', 'testUtil', 'narrativeMocks', -], (JobComms, Jupyter, Runtime, JobsData, TestUtil, Mocks) => { + 'json!/src/biokbase/narrative/tests/data/response_data.json', +], (JobComms, Jupyter, Runtime, JobsData, TestUtil, Mocks, ResponseData) => { 'use strict'; // allow spies to be overwritten @@ -553,11 +554,8 @@ define([ { // info multiple jobs type: jcm.RESPONSES.INFO, - message: JobsData.example.Info.valid.reduce((acc, curr) => { - acc[curr.job_id] = curr; - return acc; - }, {}), - expectedMultiple: JobsData.example.Info.valid.map((info) => { + message: ResponseData[jcm.RESPONSES.INFO], + expectedMultiple: Object.values(ResponseData[jcm.RESPONSES.INFO]).map((info) => { return [ info, { @@ -847,6 +845,25 @@ define([ }, ]; + Object.keys(ResponseData).forEach((respType) => { + busTests.push({ + type: respType, + message: ResponseData[respType], + expectedMultiple: Object.values(ResponseData[respType]).map((response) => { + if (response.jobState) { + response.job_id = response.jobState.job_id; + } + return [ + response, + { + channel: { [JOB_CHANNEL]: response.job_id }, + key: { type: respType }, + }, + ]; + }), + }); + }); + busTests.forEach((test) => { it(`should send a ${test.type} message to the bus`, () => { const msg = makeCommMsg(test.type, test.message),