Conversation
…e manager implementations BREAKING CHANGE: removed accessTokenOptions from FronteggContext configuration
test(context): fixed tests of FronteggContext
refactor(cache): decoupled cache managers from AccessTokens
# [6.0.0-alpha.1](5.1.1-alpha.1...6.0.0-alpha.1) (2023-07-31) ### Code Refactoring * **sdk:** removed irrelevant accessTokenOptions; refactored cache manager implementations ([3bbe939](3bbe939)) ### Bug Fixes * **cache:** Bringing back the ICacheManager generic to the class level ([7d04440](7d04440)) ### Features * **cache:** decoupled cache managers from AccessTokens ([85db523](85db523)) ### BREAKING CHANGES * **sdk:** removed accessTokenOptions from FronteggContext configuration
…l FronteggSDK cache
… frontegg cache component
df5dcfc to
83be07d
Compare
6e12d8e to
7a0548e
Compare
7a0548e to
5c3bbf3
Compare
|
|
||
| constructor(private readonly cache: ICacheManager<CacheValue>) {} | ||
|
|
||
| async loadSnapshotAsCurrent(dto: VendorEntitlementsDto): Promise<IsUpdatedToRev> { |
There was a problem hiding this comment.
"loadSnapshotAsCurrent" - what is that "Current"? the name is not fully clear to me
maybe "loadSnapshotAsCurrentRevision" would be more explanatory
There was a problem hiding this comment.
I had these concerns as well, I found it very difficult to come up with self-explanatory and fancy names for methods. Seems like I failed in both aspects 😮💨
|
|
||
| const cacheInitializer = new FronteggEntitlementsCacheInitializer(entitlementsCache); | ||
|
|
||
| const sources = new DtoToCacheSourcesMapper().map(dto); |
There was a problem hiding this comment.
Why not creating the mapper with static map function?
| import IORedis from 'ioredis'; | ||
| import { CacheValue } from '../cache.manager.interface'; | ||
|
|
||
| // TODO: define all tests of Redis-based ICacheManager implementations in single file, only change the implementation |
There was a problem hiding this comment.
still need that todo?
There was a problem hiding this comment.
yes, it's about having a single .spec file for all ICacheManager instances, as they're about to do the same from the interface perspective
| } | ||
| } | ||
|
|
||
| forScope<S extends CacheValue>(prefix?: string): ICacheManager<S> { |
There was a problem hiding this comment.
Shouldn't this function be static?
There was a problem hiding this comment.
Well, no. The intention was to create the new (scoped) instance of the same class, using the very same Redis connection (or NodeCache instance in case of local), but with different prefix and (important) - different typing.
When you use FronteggCache.getInstance() static method, in return you're receiving the instance and you don't really know (or - don't really NEED TO KNOW) what class it is. It's just fulfilling the ICacheManager interface. If this method is static, you'd need to iterate over known implementation and check which instance it is - and that's an antipattern, because in your code you need to know about the ICacheManager, not about particular implementations.
Usage of non-static method allows to apply the polymorphism here, so cache implementations know how to actually produce their scoped copies and don' leak implementation details that other parts of code should not be concerned about.
| import { ICacheValueSerializer } from '../../serializers/types'; | ||
| import { CacheValue, ICacheManagerCollection } from '../cache.manager.interface'; | ||
|
|
||
| export class RedisCacheCollection implements ICacheManagerCollection<CacheValue> { |
There was a problem hiding this comment.
Can you explain the difference between this and the IORedis one?
There was a problem hiding this comment.
it uses different Redis library!
| this.options.expireInMs, | ||
| ); | ||
|
|
||
| this.scheduleLeadershipTry(); |
There was a problem hiding this comment.
why not calling this as part of becomeFollower function?
There was a problem hiding this comment.
The becomeFollower method should be called when the follower/leader status flips. When instance was a follower and still remains a follower, this method should not be called.
Why? I don't want to emit follower event after each leadership race that is lost.
| private static EXTEND_LEADERSHIP_SCRIPT = | ||
| "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('PEXPIRE', KEYS[1], ARGV[2]) else return 0 end"; | ||
|
|
||
| async tryToMaintainTheLock(key: string, value: string, expirationTimeMs: number): Promise<boolean> { |
There was a problem hiding this comment.
Can you add here a comment explaining how this works?
5b22c42 to
3ec695b
Compare
| Logger.debug(`trying again in ${delayTime} seconds`); | ||
| await delay(delayTime * 1000); | ||
| return retry(func, { numberOfTries: numberOfTries - 1, secondsDelayRange }); | ||
| const delayTime = Math.floor(Math.random() * (delayRangeMs.max - delayRangeMs.min + 1)) + delayRangeMs.min; |
There was a problem hiding this comment.
❗Cycode: SAST violation: 'Use of a Broken or Risky Cryptographic Algorithm'.
crypto.pseudoRandomBytes()/Math.random() is a cryptographically weak random number generator.
Severity: Medium
Would you like to exclude this SAST violation from your status checks?
Tell us what to do with one of the following hashtags:
| Tag | Short Description |
|---|---|
| #cycode_sast_ignore_here | Applies to this request only |
| #cycode_sast_false_positive | Applies to this SAST violation for all repos in your organization |
No description provided.