From 2a100305cddbbf1e5b1736f652cddc2c77ec7431 Mon Sep 17 00:00:00 2001 From: Don Naegely Date: Sat, 31 Oct 2015 19:39:54 -0700 Subject: [PATCH 1/2] Add config option to enable async requests Setting this to default to false for now until model and UI support for async requests has been added Signed-off-by: Don Naegely --- src/js/cilantro/config.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/js/cilantro/config.js b/src/js/cilantro/config.js index 7c5658cb..2a916d00 100644 --- a/src/js/cilantro/config.js +++ b/src/js/cilantro/config.js @@ -17,7 +17,6 @@ define([ // The selector of the element views will be rendered within. main: '#cilantro-main', - /* * Sessions * @@ -84,13 +83,20 @@ define([ * concept names, operators and values to make filters more readable. */ styleFilters: false, - - /* + + /* * Automatically refresh count statistics for context when filters * change. */ distinctCountAutoRefresh: true, + /* + * When set to true, endpoints that support async requests will be + * used in an asynchronous fashion. When false, all endpoints will be + * used in their normal forms with blocking requests. + */ + useAsyncRequests: false, + /* * Timeouts * From 68a4623a6e4a8cfa55d307a513e8faf523ee15be Mon Sep 17 00:00:00 2001 From: Don Naegely Date: Sat, 31 Oct 2015 21:52:33 -0700 Subject: [PATCH 2/2] Set collections and UI elements based on async setting This PR adds a setting to Cilantro that will choose whether synchronous or asycnhronous endpoints are used. The setting also controls which type of collections and UI elements are used as there can be big differences in behavior between the synchronous and asynchronous versions. The async collections and UI elements are stubbed out here for completeness and will be implemented in upcomin work. Signed-off-by: Don Naegely --- src/js/cilantro/models/exporter.js | 16 +++++++++---- src/js/cilantro/models/results.js | 12 ++++++++-- src/js/cilantro/session.js | 30 ++++++++++++++++++++++--- src/js/cilantro/ui/exporter.js | 11 +++++++-- src/js/cilantro/ui/workflows/results.js | 12 +++++++--- src/js/cilantro/utils.js | 14 ++++++++++++ 6 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/js/cilantro/models/exporter.js b/src/js/cilantro/models/exporter.js index 30474d1b..c30233c5 100644 --- a/src/js/cilantro/models/exporter.js +++ b/src/js/cilantro/models/exporter.js @@ -2,8 +2,10 @@ define([ 'underscore', - './base' -], function(_, base) { + '../core', + '../utils', + './base', +], function(_, c, utils, base) { var parseTitle = function(uri) { if (!uri) return 'Untitled'; @@ -36,6 +38,9 @@ define([ }); + var AsyncExporterCollection = base.Collection.extend({}); + + var ExporterCollection = base.Collection.extend({ model: ExporterModel, @@ -57,8 +62,11 @@ define([ }); return { - ExporterModel: ExporterModel, - ExporterCollection: ExporterCollection + ExporterCollection: utils.chooseByRequestType( + AsyncExporterCollection, + ExporterCollection, + c.config.get('useAsyncRequests') + ) }; }); diff --git a/src/js/cilantro/models/results.js b/src/js/cilantro/models/results.js index 8baf34f1..22a810d3 100644 --- a/src/js/cilantro/models/results.js +++ b/src/js/cilantro/models/results.js @@ -6,8 +6,10 @@ define([ '../core', '../constants', '../structs', + '../utils', + './base', './paginator' -], function(_, Backbone, c, constants, structs, paginator) { +], function(_, Backbone, c, constants, structs, utils, base, paginator) { var ResultsPage = structs.Frame.extend({ idAttribute: 'page_num', @@ -161,8 +163,14 @@ define([ // Set the custom model for this Paginator. Results.prototype.model = ResultsPage; + var AsyncResults = base.Collection.extend({}); + return { - Results: Results + Results: utils.chooseByRequestType( + AsyncResults, + Results, + c.config.get('useAsyncRequests') + ) }; }); diff --git a/src/js/cilantro/session.js b/src/js/cilantro/session.js index 5111061d..89b57b3b 100644 --- a/src/js/cilantro/session.js +++ b/src/js/cilantro/session.js @@ -5,10 +5,9 @@ define([ 'underscore', 'backbone', './models', - './utils', './router', './core' -], function($, _, Backbone, models, utils, router, c) { +], function($, _, Backbone, models, router, c) { var events = { SESSION_OPENING: 'session:opening', @@ -144,13 +143,38 @@ define([ _parseLinks: function(model, xhr) { models.Model.prototype._parseLinks.call(this, model, xhr); - var Collection; // Iterate over the available resource links and initialize // the corresponding collection with the URL. this.data = {}; + var ASYNC_PREFIX = 'async_', + Collection; _.each(model.links, function(url, name) { + if (c.config.get('useAsyncRequests')) { + // If this is an asynchronous endpoint and we are using + // asynchronous requests then we should alter the name to + // match the synchronous name. This will guarantee that we + // are always construction this.data in a consistent format + // regarding naming no matter which request type we + // are using. + if (name.startsWith(ASYNC_PREFIX)) { + name = name.replace(ASYNC_PREFIX, ''); + } + // At this point, we know we are dealing with a synchronous + // endpoint and we are using asynchronous requests. If this + // named endpoint also exists in asynchronous form, we + // should ignore it. + else if (ASYNC_PREFIX + name in this.links) { + return; + } + } + else if (name.startsWith(ASYNC_PREFIX)) { + // If this named endpoint is asynchronous, then we should + // ignore it when using synchronous requests. + return; + } + if ((Collection = collectionLinkMap[name])) { this.data[name] = new Collection(); this.data[name].url = url; diff --git a/src/js/cilantro/ui/exporter.js b/src/js/cilantro/ui/exporter.js index 6af824b5..eddf0e1e 100644 --- a/src/js/cilantro/ui/exporter.js +++ b/src/js/cilantro/ui/exporter.js @@ -5,9 +5,10 @@ define([ 'underscore', 'backbone', 'marionette', + '../utils', './base', './core' -], function($, _, Backbone, Marionette, base, c) { +], function($, _, Backbone, Marionette, utils, base, c) { var ExportOption = Marionette.ItemView.extend({ tagName: 'label', @@ -399,8 +400,14 @@ define([ } }); + var AsyncExporterDialog = Marionette.Layout.extend({}); + return { - ExporterDialog: ExporterDialog + ExporterDialog: utils.chooseByRequestType( + AsyncExporterDialog, + ExporterDialog, + c.config.get('useAsyncRequests') + ) }; }); diff --git a/src/js/cilantro/ui/workflows/results.js b/src/js/cilantro/ui/workflows/results.js index db7c8097..8a9d156e 100644 --- a/src/js/cilantro/ui/workflows/results.js +++ b/src/js/cilantro/ui/workflows/results.js @@ -4,11 +4,12 @@ define([ 'jquery', 'underscore', 'marionette', + '../../utils', '../core', '../paginator', '../numbers', '../tables' -], function($, _, Marionette, c, paginator, numbers, tables) { +], function($, _, Marionette, utils, c, paginator, numbers, tables) { var ResultCount = Marionette.ItemView.extend({ @@ -295,8 +296,13 @@ define([ } }); + var AsyncResultsWorkflow = Marionette.Layout.extend({}); + return { - ResultCount: ResultCount, - ResultsWorkflow: ResultsWorkflow + ResultsWorkflow: utils.chooseByRequestType( + AsyncResultsWorkflow, + ResultsWorkflow, + c.config.get('useAsyncRequests') + ) }; }); diff --git a/src/js/cilantro/utils.js b/src/js/cilantro/utils.js index fcc9e95b..4d19ec2f 100644 --- a/src/js/cilantro/utils.js +++ b/src/js/cilantro/utils.js @@ -78,7 +78,21 @@ define([ console.log(JSON.stringify(obj, null, 4)); }; + // Returns the supplied async or sync parameter based on the value + // of the supplied `useAsyncRequests` param. When `useAsyncRequests` is + // true, the async parameter will be returned. When it is false, the sync + // parameter is returned. + var chooseByRequestType = function(async, sync, useAsyncRequests) { + if (useAsyncRequests) { + return async; + } + else { + return sync; + } + }; + mods.unshift({ + chooseByRequestType: chooseByRequestType, pprint: pprint, getDotProp: getDotProp, getCookie: getCookie,