Repository: tez Updated Branches: refs/heads/master cd44c906f -> daa8d3db0
TEZ-3619. Tez UI: Improve DAG Data download (sree) Project: http://git-wip-us.apache.org/repos/asf/tez/repo Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/daa8d3db Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/daa8d3db Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/daa8d3db Branch: refs/heads/master Commit: daa8d3db0639ca93085072543dec2baac803e427 Parents: cd44c90 Author: Sreenath Somarajapuram <[email protected]> Authored: Wed Feb 15 21:32:21 2017 +0530 Committer: Sreenath Somarajapuram <[email protected]> Committed: Wed Feb 15 21:32:21 2017 +0530 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../webapp/app/components/zip-download-modal.js | 2 +- .../webapp/app/styles/zip-download-modal.less | 13 +++- .../templates/components/zip-download-modal.hbs | 12 ++-- .../main/webapp/app/utils/download-dag-zip.js | 75 ++++++++++++++++++-- .../components/zip-download-modal-test.js | 52 +++++++++++++- 6 files changed, 140 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tez/blob/daa8d3db/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 337b394..31e141c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -195,6 +195,7 @@ ALL CHANGES: TEZ-3598. Tez UI: Text formatting changes TEZ-3602. Tez UI: Query Name field is not required TEZ-3615. Tez UI: Table changes + TEZ-3619. Tez UI: Improve DAG Data download Release 0.8.5: Unreleased http://git-wip-us.apache.org/repos/asf/tez/blob/daa8d3db/tez-ui/src/main/webapp/app/components/zip-download-modal.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/components/zip-download-modal.js b/tez-ui/src/main/webapp/app/components/zip-download-modal.js index c55b34e..528c84e 100644 --- a/tez-ui/src/main/webapp/app/components/zip-download-modal.js +++ b/tez-ui/src/main/webapp/app/components/zip-download-modal.js @@ -23,7 +23,7 @@ export default Ember.Component.extend({ content: null, _onSuccess: Ember.observer("content.downloader.succeeded", function () { - if(this.get("content.downloader.succeeded")) { + if(this.get("content.downloader.succeeded") && !this.get("content.downloader.partial")) { Ember.run.later(this, "close"); } }), http://git-wip-us.apache.org/repos/asf/tez/blob/daa8d3db/tez-ui/src/main/webapp/app/styles/zip-download-modal.less ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/styles/zip-download-modal.less b/tez-ui/src/main/webapp/app/styles/zip-download-modal.less index 4ed0fd2..49b5245 100644 --- a/tez-ui/src/main/webapp/app/styles/zip-download-modal.less +++ b/tez-ui/src/main/webapp/app/styles/zip-download-modal.less @@ -20,11 +20,22 @@ .message { padding: 10px 15px; + i { + margin-right: 5px; + } + .fa-spinner { color: green; } - .fa-exclamation-circle { + .error { color: red; } + .warning { + color: orange; + } + + .progress { + margin: 5px 0 5px 0; + } } } http://git-wip-us.apache.org/repos/asf/tez/blob/daa8d3db/tez-ui/src/main/webapp/app/templates/components/zip-download-modal.hbs ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/templates/components/zip-download-modal.hbs b/tez-ui/src/main/webapp/app/templates/components/zip-download-modal.hbs index 03b820e..937722c 100644 --- a/tez-ui/src/main/webapp/app/templates/components/zip-download-modal.hbs +++ b/tez-ui/src/main/webapp/app/templates/components/zip-download-modal.hbs @@ -18,17 +18,21 @@ <div class="message"> {{#if content.downloader.failed}} - <i class="fa fa-lg fa-exclamation-circle"></i> + <i class="fa fa-lg fa-exclamation-circle error"></i> Error downloading data! + {{else}}{{#if (and content.downloader.partial content.downloader.succeeded)}} + <i class="fa fa-lg fa-exclamation-circle warning"></i> + Data downloaded might be incomplete. Please check the zip! {{else}} - <i class="fa fa-lg fa-spinner fa-spin"></i> Downloading data for dag: <b>{{content.dag.entityID}}</b> - {{/if}} + {{em-progress value=content.downloader.percent striped=true}} + {{content.downloader.message}} + {{/if}}{{/if}} </div> <div class="form-actions"> - {{#if content.downloader.failed}} + {{#if (or content.downloader.failed content.downloader.partial)}} <button type="button" class="btn btn-primary" data-dismiss="modal" aria-label="Close">Ok</button> {{else}} <button type="button" class="btn" data-dismiss="modal" aria-label="Close" {{action "cancel"}}>Cancel</button> http://git-wip-us.apache.org/repos/asf/tez/blob/daa8d3db/tez-ui/src/main/webapp/app/utils/download-dag-zip.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/app/utils/download-dag-zip.js b/tez-ui/src/main/webapp/app/utils/download-dag-zip.js index 9c91a92..8f10bde 100644 --- a/tez-ui/src/main/webapp/app/utils/download-dag-zip.js +++ b/tez-ui/src/main/webapp/app/utils/download-dag-zip.js @@ -110,6 +110,10 @@ var IO = { var reqID = getRequestId(); pendingRequests[reqID] = xhr; + if(item.onFetch) { + item.onFetch(item.context); + } + xhr.done(function(data/*, statusText, xhr*/) { delete pendingRequests[reqID]; @@ -129,8 +133,17 @@ var IO = { }).fail(function(xhr, statusText/*, errorObject*/) { delete pendingRequests[reqID]; inProgress--; - if(item.onItemFail) { - item.onItemFail(); + + if(item.retryCount) { + itemList.unshift(item); + item.retryCount--; + if(item.onRetry) { + item.onRetry(item.context); + } + Ember.run.later(processNext, 3000 + Math.random() * 3000); + } + else if(item.onItemFail) { + item.onItemFail(xhr, item.context); processNext(); } else { @@ -286,27 +299,47 @@ export default function downloadDagZip(dag, options) { { url: getUrl('TEZ_APPLICATION', 'tez_' + dag.get("appID")), context: { name: 'application', type: 'TEZ_APPLICATION' }, - onItemFetched: processSingleItem + onFetch: onFetch, + onRetry: onRetry, + onItemFetched: processSingleItem, + onItemFail: processFailure, + retryCount: 3, }, { url: getUrl('TEZ_DAG_ID', dagID), context: { name: 'dag', type: 'TEZ_DAG_ID' }, - onItemFetched: processSingleItem + onFetch: onFetch, + onRetry: onRetry, + onItemFetched: processSingleItem, + onItemFail: processFailure, + retryCount: 3, }, { url: getUrl('TEZ_VERTEX_ID', null, dagID), context: { name: 'vertices', type: 'TEZ_VERTEX_ID', part: 0 }, - onItemFetched: processMultipleItems + onFetch: onFetch, + onRetry: onRetry, + onItemFetched: processMultipleItems, + onItemFail: processFailure, + retryCount: 3, }, { url: getUrl('TEZ_TASK_ID', null, dagID), context: { name: 'tasks', type: 'TEZ_TASK_ID', part: 0 }, - onItemFetched: processMultipleItems + onFetch: onFetch, + onRetry: onRetry, + onItemFetched: processMultipleItems, + onItemFail: processFailure, + retryCount: 3, }, { url: getUrl('TEZ_TASK_ATTEMPT_ID', null, dagID), context: { name: 'task_attempts', type: 'TEZ_TASK_ATTEMPT_ID', part: 0 }, - onItemFetched: processMultipleItems + onFetch: onFetch, + onRetry: onRetry, + onItemFetched: processMultipleItems, + onItemFail: processFailure, + retryCount: 3, } ]; @@ -334,7 +367,9 @@ export default function downloadDagZip(dag, options) { }), downloaderProxy = Ember.Object.create({ percent: 0, + message: "", succeeded: false, + partial: false, failed: false, cancel: function() { downloader.cancel(); @@ -353,6 +388,7 @@ export default function downloadDagZip(dag, options) { url = `${url}&fromId=${fromID}`; } } + return url; } @@ -367,6 +403,30 @@ export default function downloadDagZip(dag, options) { } } + function onFetch(context) { + downloaderProxy.set("message", `Fetching ${context.name} data.`); + } + + function onRetry(context) { + downloaderProxy.set("message", `Downloading ${context.name} data failed. Retrying!`); + } + + function processFailure(data, context) { + var obj = {}; + try { + obj[context.name] = JSON.parse(data.responseText); + } + catch(e) { + obj[context.name] = data.responseText; + } + + downloaderProxy.set("partial", true); + downloaderProxy.set("message", `Downloading ${context.name} data failed!`); + + zipHelper.addFile({name: `error.${context.name}.json`, data: JSON.stringify(obj, null, 2)}); + checkIfAllDownloaded(); + } + function processSingleItem(data, context) { var obj = {}; obj[context.name] = data; @@ -415,6 +475,7 @@ export default function downloadDagZip(dag, options) { zipHelper.then(function(zippedBlob) { saveAs(zippedBlob, `${dagID}.zip`); + downloaderProxy.set("message", `Download complete.`); downloaderProxy.set("succeeded", true); }, function() { Ember.Logger.error('zip Failed'); http://git-wip-us.apache.org/repos/asf/tez/blob/daa8d3db/tez-ui/src/main/webapp/tests/integration/components/zip-download-modal-test.js ---------------------------------------------------------------------- diff --git a/tez-ui/src/main/webapp/tests/integration/components/zip-download-modal-test.js b/tez-ui/src/main/webapp/tests/integration/components/zip-download-modal-test.js index cd9a61a..8326054 100644 --- a/tez-ui/src/main/webapp/tests/integration/components/zip-download-modal-test.js +++ b/tez-ui/src/main/webapp/tests/integration/components/zip-download-modal-test.js @@ -34,7 +34,7 @@ test('Basic creation test', function(assert) { }); this.render(hbs`{{zip-download-modal content=content}}`); - assert.equal(this.$(".message").text().trim(), expectedMessage); + assert.equal(this.$(".message").text().trim().indexOf(expectedMessage), 0); // Template block usage:" + EOL + this.render(hbs` @@ -42,5 +42,53 @@ test('Basic creation test', function(assert) { template block text {{/zip-download-modal}} `); - assert.equal(this.$(".message").text().trim(), expectedMessage); + assert.equal(this.$(".message").text().trim().indexOf(expectedMessage), 0); }); + +test('progress test', function(assert) { + this.set("content", { + downloader: { + percent: 0.5 + } + }); + + this.render(hbs`{{zip-download-modal content=content}}`); + let text = this.$(".message").text().trim(); + assert.equal(text.substr(-3), "50%"); + + assert.equal(this.$(".btn").length, 1); + assert.equal(this.$(".btn-primary").length, 0); +}); + +test('failed test', function(assert) { + var expectedMessage = "Error downloading data!"; + + this.set("content", { + downloader: { + failed: true + } + }); + + this.render(hbs`{{zip-download-modal content=content}}`); + assert.equal(this.$(".message").text().trim().indexOf(expectedMessage), 0); + + assert.equal(this.$(".btn").length, 1); + assert.equal(this.$(".btn-primary").length, 1); +}); + +test('partial test', function(assert) { + var expectedMessage = "Data downloaded might be incomplete. Please check the zip!"; + + this.set("content", { + downloader: { + succeeded: true, + partial: true + } + }); + + this.render(hbs`{{zip-download-modal content=content}}`); + assert.equal(this.$(".message").text().trim().indexOf(expectedMessage), 0); + + assert.equal(this.$(".btn").length, 1); + assert.equal(this.$(".btn-primary").length, 1); +}); \ No newline at end of file
