|
@@ -15,10 +15,11 @@
|
|
|
// limitations under the License.
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
import apiHelper from 'api/apiHelper';
|
|
import apiHelper from 'api/apiHelper';
|
|
|
-import { ExecutionResult } from 'apps/notebook2/execution/executionResult';
|
|
|
|
|
|
|
+import ExecutionResult from 'apps/notebook2/execution/executionResult';
|
|
|
import hueAnalytics from 'utils/hueAnalytics';
|
|
import hueAnalytics from 'utils/hueAnalytics';
|
|
|
import huePubSub from 'utils/huePubSub';
|
|
import huePubSub from 'utils/huePubSub';
|
|
|
import sessionManager from 'apps/notebook2/execution/sessionManager';
|
|
import sessionManager from 'apps/notebook2/execution/sessionManager';
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
*
|
|
*
|
|
|
* @type {{running: string, canceling: string, canceled: string, expired: string, waiting: string, success: string, ready: string, available: string, closed: string, starting: string}}
|
|
* @type {{running: string, canceling: string, canceled: string, expired: string, waiting: string, success: string, ready: string, available: string, closed: string, starting: string}}
|
|
@@ -37,7 +38,7 @@ export const EXECUTION_STATUS = {
|
|
|
closed: 'closed'
|
|
closed: 'closed'
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const EXECUTABLE_UPDATED_EVENT = 'hue.executable.updated';
|
|
|
|
|
|
|
+export const EXECUTABLE_UPDATED_EVENT = 'hue.executable.updated';
|
|
|
|
|
|
|
|
export default class Executable {
|
|
export default class Executable {
|
|
|
/**
|
|
/**
|
|
@@ -48,18 +49,21 @@ export default class Executable {
|
|
|
* @param {string} [options.statement] - Either supply a statement or a parsedStatement
|
|
* @param {string} [options.statement] - Either supply a statement or a parsedStatement
|
|
|
* @param {SqlStatementsParserResult} [options.parsedStatement] - Either supply a statement or a parsedStatement
|
|
* @param {SqlStatementsParserResult} [options.parsedStatement] - Either supply a statement or a parsedStatement
|
|
|
* @param {string} [options.database]
|
|
* @param {string} [options.database]
|
|
|
|
|
+ * @param {Executor} options.executor
|
|
|
* @param {Session[]} [options.sessions]
|
|
* @param {Session[]} [options.sessions]
|
|
|
*/
|
|
*/
|
|
|
constructor(options) {
|
|
constructor(options) {
|
|
|
this.compute = options.compute;
|
|
this.compute = options.compute;
|
|
|
this.namespace = options.namespace;
|
|
this.namespace = options.namespace;
|
|
|
this.sourceType = options.sourceType;
|
|
this.sourceType = options.sourceType;
|
|
|
|
|
+ this.executor = options.executor;
|
|
|
|
|
|
|
|
this.handle = {
|
|
this.handle = {
|
|
|
statement_id: 0 // TODO: Get rid of need for initial handle in the backend
|
|
statement_id: 0 // TODO: Get rid of need for initial handle in the backend
|
|
|
};
|
|
};
|
|
|
this.status = EXECUTION_STATUS.ready;
|
|
this.status = EXECUTION_STATUS.ready;
|
|
|
this.progress = 0;
|
|
this.progress = 0;
|
|
|
|
|
+ this.result = undefined;
|
|
|
|
|
|
|
|
this.lastCancellable = undefined;
|
|
this.lastCancellable = undefined;
|
|
|
this.notifyThrottle = -1;
|
|
this.notifyThrottle = -1;
|
|
@@ -87,55 +91,6 @@ export default class Executable {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let statusCheckCount = 0;
|
|
|
|
|
- let checkStatusTimeout = -1;
|
|
|
|
|
-
|
|
|
|
|
- const checkStatus = () =>
|
|
|
|
|
- new Promise((statusResolve, statusReject) => {
|
|
|
|
|
- statusCheckCount++;
|
|
|
|
|
- this.lastCancellable = apiHelper
|
|
|
|
|
- .checkExecutionStatus({ executable: this })
|
|
|
|
|
- .done(queryStatus => {
|
|
|
|
|
- switch (this.status) {
|
|
|
|
|
- case EXECUTION_STATUS.success:
|
|
|
|
|
- this.setStatus(queryStatus);
|
|
|
|
|
- this.setProgress(99); // TODO: why 99 here (from old code)?
|
|
|
|
|
- statusResolve();
|
|
|
|
|
- break;
|
|
|
|
|
- case EXECUTION_STATUS.available:
|
|
|
|
|
- this.setStatus(queryStatus);
|
|
|
|
|
- this.setProgress(100);
|
|
|
|
|
- statusResolve();
|
|
|
|
|
- break;
|
|
|
|
|
- case EXECUTION_STATUS.expired:
|
|
|
|
|
- this.setStatus(queryStatus);
|
|
|
|
|
- statusReject();
|
|
|
|
|
- break;
|
|
|
|
|
- case EXECUTION_STATUS.running:
|
|
|
|
|
- case EXECUTION_STATUS.starting:
|
|
|
|
|
- case EXECUTION_STATUS.waiting:
|
|
|
|
|
- this.setStatus(queryStatus);
|
|
|
|
|
- checkStatusTimeout = window.setTimeout(
|
|
|
|
|
- () => {
|
|
|
|
|
- checkStatus()
|
|
|
|
|
- .then(statusResolve)
|
|
|
|
|
- .catch(statusReject);
|
|
|
|
|
- },
|
|
|
|
|
- statusCheckCount > 45 ? 5000 : 1000
|
|
|
|
|
- );
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- console.warn('Got unknown status ' + queryStatus);
|
|
|
|
|
- statusReject();
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- .fail(statusReject);
|
|
|
|
|
-
|
|
|
|
|
- this.lastCancellable.onCancel(() => {
|
|
|
|
|
- window.clearTimeout(checkStatusTimeout);
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
this.setStatus(EXECUTION_STATUS.running);
|
|
this.setStatus(EXECUTION_STATUS.running);
|
|
|
this.setProgress(0);
|
|
this.setProgress(0);
|
|
|
|
|
|
|
@@ -143,14 +98,65 @@ export default class Executable {
|
|
|
const session = await sessionManager.getSession({ type: this.sourceType });
|
|
const session = await sessionManager.getSession({ type: this.sourceType });
|
|
|
hueAnalytics.log('notebook', 'execute/' + this.sourceType);
|
|
hueAnalytics.log('notebook', 'execute/' + this.sourceType);
|
|
|
this.handle = await this.internalExecute(session);
|
|
this.handle = await this.internalExecute(session);
|
|
|
- await checkStatus();
|
|
|
|
|
- this.result = new ExecutionResult(this);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (this.handle.has_result_set && this.handle.sync) {
|
|
|
|
|
+ this.result = new ExecutionResult(this);
|
|
|
|
|
+ if (this.handle.sync) {
|
|
|
|
|
+ this.result.fetchRows();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.checkStatus();
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
this.setStatus(EXECUTION_STATUS.failed);
|
|
this.setStatus(EXECUTION_STATUS.failed);
|
|
|
throw err;
|
|
throw err;
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return this.result;
|
|
|
|
|
|
|
+ checkStatus(statusCheckCount) {
|
|
|
|
|
+ if (!statusCheckCount) {
|
|
|
|
|
+ statusCheckCount = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ statusCheckCount++;
|
|
|
|
|
+ let checkStatusTimeout = -1;
|
|
|
|
|
+ this.lastCancellable = apiHelper
|
|
|
|
|
+ .checkExecutionStatus({ executable: this })
|
|
|
|
|
+ .done(queryStatus => {
|
|
|
|
|
+ switch (this.status) {
|
|
|
|
|
+ case EXECUTION_STATUS.success:
|
|
|
|
|
+ this.setStatus(queryStatus);
|
|
|
|
|
+ this.setProgress(99); // TODO: why 99 here (from old code)?
|
|
|
|
|
+ break;
|
|
|
|
|
+ case EXECUTION_STATUS.available:
|
|
|
|
|
+ this.setStatus(queryStatus);
|
|
|
|
|
+ this.setProgress(100);
|
|
|
|
|
+ if (!this.result && this.handle.has_result_set) {
|
|
|
|
|
+ this.result = new ExecutionResult(this);
|
|
|
|
|
+ this.result.fetchRows();
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case EXECUTION_STATUS.expired:
|
|
|
|
|
+ this.setStatus(queryStatus);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case EXECUTION_STATUS.running:
|
|
|
|
|
+ case EXECUTION_STATUS.starting:
|
|
|
|
|
+ case EXECUTION_STATUS.waiting:
|
|
|
|
|
+ this.setStatus(queryStatus);
|
|
|
|
|
+ checkStatusTimeout = window.setTimeout(
|
|
|
|
|
+ () => {
|
|
|
|
|
+ this.checkStatus(statusCheckCount);
|
|
|
|
|
+ },
|
|
|
|
|
+ statusCheckCount > 45 ? 5000 : 1000
|
|
|
|
|
+ );
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ console.warn('Got unknown status ' + queryStatus);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.lastCancellable.onCancel(() => {
|
|
|
|
|
+ window.clearTimeout(checkStatusTimeout);
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
setLastCancellable(lastCancellable) {
|
|
setLastCancellable(lastCancellable) {
|