-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: segregate retry decision for read and write APIs (#1465)
* chore: add tests for retry strategies * feat: segregate retry decision for read and write APIs * chore: retry all idempotent operations on cancelled errors * chore: add comment for why cancelled is retryable
- Loading branch information
1 parent
3337744
commit 2e66ed6
Showing
2 changed files
with
111 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
packages/client-sdk-nodejs/test/unit/config/retry/default-eligibility-strategy.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { | ||
DefaultEligibilityStrategy, | ||
DefaultMomentoLoggerFactory, | ||
} from '../../../../src'; | ||
import {Status} from '@grpc/grpc-js/build/src/constants'; | ||
import {Metadata, StatusObject} from '@grpc/grpc-js'; | ||
import {ClientMethodDefinition} from '@grpc/grpc-js/build/src/make-client'; | ||
|
||
describe('DefaultEligibilityStrategy', () => { | ||
const testLoggerFactory = new DefaultMomentoLoggerFactory(); | ||
const eligibilityStrategy = new DefaultEligibilityStrategy(testLoggerFactory); | ||
|
||
it('should return true for INTERNAL status code and GET request path', () => { | ||
const grpcStatus = {code: Status.INTERNAL} as StatusObject; | ||
const grpcRequest = { | ||
path: '/cache_client.Scs/Get', | ||
} as ClientMethodDefinition<unknown, unknown>; | ||
const requestMetadata = new Metadata(); | ||
|
||
const isEligible = eligibilityStrategy.isEligibleForRetry({ | ||
grpcStatus, | ||
grpcRequest, | ||
requestMetadata, | ||
}); | ||
|
||
expect(isEligible).toBe(true); | ||
}); | ||
|
||
it('should return false for UNKNOWN status code and GET request path', () => { | ||
const grpcStatus = {code: Status.UNKNOWN} as StatusObject; | ||
const grpcRequest = { | ||
path: '/cache_client.Scs/Get', | ||
} as ClientMethodDefinition<unknown, unknown>; | ||
const requestMetadata = new Metadata(); | ||
|
||
const isEligible = eligibilityStrategy.isEligibleForRetry({ | ||
grpcStatus, | ||
grpcRequest, | ||
requestMetadata, | ||
}); | ||
|
||
expect(isEligible).toBe(false); | ||
}); | ||
|
||
it('should return true for UNAVAILABLE status code and SET request path', () => { | ||
const grpcStatus = {code: Status.UNAVAILABLE} as StatusObject; | ||
const grpcRequest = { | ||
path: '/cache_client.Scs/Set', | ||
} as ClientMethodDefinition<unknown, unknown>; | ||
const requestMetadata = new Metadata(); | ||
|
||
const isEligible = eligibilityStrategy.isEligibleForRetry({ | ||
grpcStatus, | ||
grpcRequest, | ||
requestMetadata, | ||
}); | ||
|
||
expect(isEligible).toBe(true); | ||
}); | ||
|
||
it('should return true for CANCELLED status code and GET request path', () => { | ||
const grpcStatus = {code: Status.CANCELLED} as StatusObject; | ||
const grpcRequest = { | ||
path: '/cache_client.Scs/Get', | ||
} as ClientMethodDefinition<unknown, unknown>; | ||
const requestMetadata = new Metadata(); | ||
|
||
const isEligible = eligibilityStrategy.isEligibleForRetry({ | ||
grpcStatus, | ||
grpcRequest, | ||
requestMetadata, | ||
}); | ||
|
||
expect(isEligible).toBe(true); | ||
}); | ||
|
||
it('should return true for CANCELLED status code and SET request path', () => { | ||
const grpcStatus = {code: Status.CANCELLED} as StatusObject; | ||
const grpcRequest = { | ||
path: '/cache_client.Scs/Set', | ||
} as ClientMethodDefinition<unknown, unknown>; | ||
const requestMetadata = new Metadata(); | ||
|
||
const isEligible = eligibilityStrategy.isEligibleForRetry({ | ||
grpcStatus, | ||
grpcRequest, | ||
requestMetadata, | ||
}); | ||
|
||
expect(isEligible).toBe(true); | ||
}); | ||
|
||
it('should return false for CANCELLED status code and dictionary increment request path', () => { | ||
const grpcStatus = {code: Status.CANCELLED} as StatusObject; | ||
const grpcRequest = { | ||
path: '/cache_client.Scs/DictionaryIncrement', | ||
} as ClientMethodDefinition<unknown, unknown>; | ||
const requestMetadata = new Metadata(); | ||
|
||
const isEligible = eligibilityStrategy.isEligibleForRetry({ | ||
grpcStatus, | ||
grpcRequest, | ||
requestMetadata, | ||
}); | ||
|
||
expect(isEligible).toBe(false); | ||
}); | ||
}); |