feat(parameters): added BaseProvider class - #1168
Conversation
| } | ||
|
|
||
| abstract class BaseProvider implements BaseProviderInterface { | ||
| public store: Map<string, ExpirableValue> = new Map; |
There was a problem hiding this comment.
Question: Should this be public or private?
There was a problem hiding this comment.
I'll go with private first and broaden later if needed.
There was a problem hiding this comment.
If I use private I'm not sure how to test around it. So I went with private and extended the class in the tests, similar to what done in the Idempotency utility.
If you have any better way to do it that also allows a pure private let me know.
There was a problem hiding this comment.
That should be good for now. I would expect that the tests cover all privates variable from the public methods.
| */ | ||
| public async get(name: string, options?: GetOptionsInterface): Promise<undefined | string | Record<string, unknown>> { | ||
| const configs = new GetOptions(options); | ||
| const key = [ name, configs.transform ].toString(); |
There was a problem hiding this comment.
I couldn't think of a more elegant way of constructing this key.
For context:
- Python uses a Tuple, which are not supported in JS (only stage 2)
- I was initially using objects like
{ name: string, transform: TransformOptions }since we are using aMap, but given thatMap.hasandMap.getuse object identity to compare the key it would never return a match - also it's not possible to extend/customize the equality function used by aMap Sethave the same limitations described above and that apply toMap- I briefly considered using external modules like
immutable-jsor custom implementations ofSet, but opted not to in order to avoid introducing a dependency over this otherwise limited usage.
There was a problem hiding this comment.
As long as the test cases are rigorous enough, this should be ok. I cannot see how we can run into having a duplicated here, can we?
There was a problem hiding this comment.
Agree.
I wasn't worried about duplicates as much as special characters and such.
| } | ||
|
|
||
| // TODO: revisit return type once providers are implemented, it might be missing binary when not transformed | ||
| return value; |
There was a problem hiding this comment.
As mentioned in the comment here, I stayed generic with types because at this stage I'm not yet sure what each provider/AWS SDK (from _get) will return.
I have opened #1172 to track this work.
| this.addToCache(key, values, configs.maxAge); | ||
| } | ||
|
|
||
| // TODO: revisit return type once providers are implemented, it might be missing something |
|
|
||
| } | ||
|
|
||
| // TODO: revisit `value` type once we are clearer on the types returned by the various SDKs |
| ) { | ||
| return new TextDecoder('utf-8').decode(fromBase64(value)); | ||
| } else { | ||
| // TODO: revisit this type once we are clearer on types returned by SDKs |
| } | ||
| } | ||
|
|
||
| class GetMultipleOptions implements GetMultipleOptionsInterface { |
There was a problem hiding this comment.
Should these classes be in separate files?
There was a problem hiding this comment.
Given this file's size, I would say so. But it is not critical.
| const value = this.store.get(key); | ||
| if (value) { | ||
| if (value.isExpired()) { | ||
| this.store.delete(key); |
There was a problem hiding this comment.
As far as I can tell, the Python implementation doesn't clear expired items from the cache.
Can you think of any case in which doing that might become an issue?
There was a problem hiding this comment.
No. We just trade time for space here. The operation is O(1) so I don't think there is any issue to delete it now.
The problem is more on doing more than one thing in a single method. It is not obvious to me that hasKeyExpiredInCache() will prune the this.store. The new maintainer may use this function and didn't know that he's pruned the cache. Thus, I'm incline to remove this.
If we want to prune expired items, I would expect a public/protected method to do this explicitly. But that will cause O(n) and I am not sure if it's useful. Map has O(1) access so we are only saving the memory consumption here, which I expect it to be very small gain.
Thus, I'm incline to remove this and keep the expired item.
There was a problem hiding this comment.
That said. It's open to debate. I don't think that it's bad enough to block this PR. So I would give an approval. You can decide in later commit if you want to remove this.
There was a problem hiding this comment.
Good points, I didn't think about the operation costs and I agree that the memory savings are marginal.
I have removed it.
BaseProvider class
ijemmy
left a comment
There was a problem hiding this comment.
One comment on prunning expire key
| } | ||
|
|
||
| abstract class BaseProvider implements BaseProviderInterface { | ||
| public store: Map<string, ExpirableValue> = new Map; |
There was a problem hiding this comment.
I'll go with private first and broaden later if needed.
| } | ||
| } | ||
|
|
||
| class GetMultipleOptions implements GetMultipleOptionsInterface { |
There was a problem hiding this comment.
Given this file's size, I would say so. But it is not critical.
| */ | ||
| public async get(name: string, options?: GetOptionsInterface): Promise<undefined | string | Record<string, unknown>> { | ||
| const configs = new GetOptions(options); | ||
| const key = [ name, configs.transform ].toString(); |
There was a problem hiding this comment.
As long as the test cases are rigorous enough, this should be ok. I cannot see how we can run into having a duplicated here, can we?
| const value = this.store.get(key); | ||
| if (value) { | ||
| if (value.isExpired()) { | ||
| this.store.delete(key); |
There was a problem hiding this comment.
No. We just trade time for space here. The operation is O(1) so I don't think there is any issue to delete it now.
The problem is more on doing more than one thing in a single method. It is not obvious to me that hasKeyExpiredInCache() will prune the this.store. The new maintainer may use this function and didn't know that he's pruned the cache. Thus, I'm incline to remove this.
If we want to prune expired items, I would expect a public/protected method to do this explicitly. But that will cause O(n) and I am not sure if it's useful. Map has O(1) access so we are only saving the memory consumption here, which I expect it to be very small gain.
Thus, I'm incline to remove this and keep the expired item.
| const value = this.store.get(key); | ||
| if (value) { | ||
| if (value.isExpired()) { | ||
| this.store.delete(key); |
There was a problem hiding this comment.
That said. It's open to debate. I don't think that it's bad enough to block this PR. So I would give an approval. You can decide in later commit if you want to remove this.
128ed70 to
14f8b81
Compare
| interface GetMultipleOptionsInterface { | ||
| maxAge?: number | ||
| forceFetch?: boolean | ||
| sdkOptions?: unknown | ||
| transform?: string | ||
| throwOnTransformError?: boolean | ||
| } |
There was a problem hiding this comment.
Just to reduce boilerplate:
interface GetMultipleOptionsInterface extends GetOptionsInterface {
throwOnTransformError?: boolean
}
There was a problem hiding this comment.
Good point, please feel free to address this in your PR for AppConfigprovider
Description of your changes
This PR introduces a new package (
parameters) in the npm workspace as well as theBaseProviderfor the new utility and its unit tests.The changes related to the new workspace package include:
pacakges/parametersfolder withpackage.jsonThe changes related to the
BaseProviderinclude the content of thesrcandtestsdirectories:BaseProviderclassBaseProviderPlease don't take in account the content of the
README.mdfile nor the docstrings (or lack thereof) for the various features, both items will be addressed in their own PRs.How to verify this change
See unit tests added as part of this PR.
Related issues, RFCs
Issue number: #1173
PR status
Is this ready for review?: YES
Is it a breaking change?: NO
Checklist
Breaking change checklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.