Skip to content

Commit 2961a44

Browse files
[PECO-319] Pending status should not be considered error (#59)
* [PECO-319] PENDING_STATE should not trigger error Signed-off-by: Levko Kravets <levko.ne@gmail.com> * Add slight delay between requests when waiting for query completion Signed-off-by: Levko Kravets <levko.ne@gmail.com> Signed-off-by: Levko Kravets <levko.ne@gmail.com>
1 parent f481f61 commit 2961a44

File tree

2 files changed

+38
-25
lines changed

2 files changed

+38
-25
lines changed

lib/DBSQLOperation/OperationStatusHelper.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import StatusFactory from '../factory/StatusFactory';
44
import { OperationStatusCallback } from '../contracts/IOperation';
55
import OperationStateError from '../errors/OperationStateError';
66

7+
async function delay(ms?: number): Promise<void> {
8+
return new Promise((resolve) => {
9+
setTimeout(() => {
10+
resolve();
11+
}, ms);
12+
});
13+
}
14+
715
export default class OperationStatusHelper {
816
private driver: HiveDriver;
917

@@ -32,6 +40,7 @@ export default class OperationStatusHelper {
3240
private isInProgress(response: TGetOperationStatusResp) {
3341
switch (response.operationState) {
3442
case TOperationState.INITIALIZED_STATE:
43+
case TOperationState.PENDING_STATE:
3544
case TOperationState.RUNNING_STATE:
3645
return true;
3746
default:
@@ -77,6 +86,8 @@ export default class OperationStatusHelper {
7786
switch (response.operationState) {
7887
case TOperationState.INITIALIZED_STATE:
7988
return false;
89+
case TOperationState.PENDING_STATE:
90+
return false;
8091
case TOperationState.RUNNING_STATE:
8192
return false;
8293
case TOperationState.FINISHED_STATE:
@@ -87,8 +98,6 @@ export default class OperationStatusHelper {
8798
throw new OperationStateError('The operation was closed by a client', response);
8899
case TOperationState.ERROR_STATE:
89100
throw new OperationStateError('The operation failed due to an error', response);
90-
case TOperationState.PENDING_STATE:
91-
throw new OperationStateError('The operation is in a pending state', response);
92101
case TOperationState.TIMEDOUT_STATE:
93102
throw new OperationStateError('The operation is in a timed out state', response);
94103
case TOperationState.UKNOWN_STATE:
@@ -103,6 +112,7 @@ export default class OperationStatusHelper {
103112
}
104113
const isReady = await this.isReady(progress, callback);
105114
if (!isReady) {
115+
await delay(100); // add some delay between status requests
106116
return this.waitUntilReady(progress, callback);
107117
}
108118
}

tests/unit/DBSQLOperation.test.js

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -404,30 +404,34 @@ describe('DBSQLOperation', () => {
404404
});
405405

406406
describe('finished', () => {
407-
it('should wait for finished state', async () => {
408-
const attemptsUntilFinished = 3;
409-
410-
const handle = new OperationHandleMock();
411-
const driver = new DriverMock();
412-
driver.getOperationStatusResp.operationState = TOperationState.RUNNING_STATE;
413-
sinon
414-
.stub(driver, 'getOperationStatus')
415-
.callThrough()
416-
.onCall(attemptsUntilFinished - 1) // count is zero-based
417-
.callsFake((...args) => {
418-
driver.getOperationStatusResp.operationState = TOperationState.FINISHED_STATE;
419-
return driver.getOperationStatus.wrappedMethod.apply(driver, args);
420-
});
421-
422-
const operation = new DBSQLOperation(driver, handle);
423-
424-
expect(operation._status.state).to.equal(TOperationState.INITIALIZED_STATE);
407+
[TOperationState.INITIALIZED_STATE, TOperationState.RUNNING_STATE, TOperationState.PENDING_STATE].forEach(
408+
(operationState) => {
409+
it(`should wait for finished state starting from TOperationState.${TOperationState[operationState]}`, async () => {
410+
const attemptsUntilFinished = 3;
411+
412+
const handle = new OperationHandleMock();
413+
const driver = new DriverMock();
414+
driver.getOperationStatusResp.operationState = operationState;
415+
sinon
416+
.stub(driver, 'getOperationStatus')
417+
.callThrough()
418+
.onCall(attemptsUntilFinished - 1) // count is zero-based
419+
.callsFake((...args) => {
420+
driver.getOperationStatusResp.operationState = TOperationState.FINISHED_STATE;
421+
return driver.getOperationStatus.wrappedMethod.apply(driver, args);
422+
});
423+
424+
const operation = new DBSQLOperation(driver, handle);
425+
426+
expect(operation._status.state).to.equal(TOperationState.INITIALIZED_STATE);
425427

426-
await operation.finished();
428+
await operation.finished();
427429

428-
expect(driver.getOperationStatus.callCount).to.be.equal(attemptsUntilFinished);
429-
expect(operation._status.state).to.equal(TOperationState.FINISHED_STATE);
430-
});
430+
expect(driver.getOperationStatus.callCount).to.be.equal(attemptsUntilFinished);
431+
expect(operation._status.state).to.equal(TOperationState.FINISHED_STATE);
432+
});
433+
},
434+
);
431435

432436
it('should pick up finished state from directResults', async () => {
433437
const handle = new OperationHandleMock();
@@ -473,7 +477,6 @@ describe('DBSQLOperation', () => {
473477
TOperationState.CLOSED_STATE,
474478
TOperationState.ERROR_STATE,
475479
TOperationState.UKNOWN_STATE,
476-
TOperationState.PENDING_STATE,
477480
TOperationState.TIMEDOUT_STATE,
478481
].forEach((operationState) => {
479482
it(`should throw an error in case of a TOperationState.${TOperationState[operationState]}`, async () => {

0 commit comments

Comments
 (0)