-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(wip): added cached entity #2489
Conversation
apps/api/src/app/shared/services/cache/invalidate-cache.service.ts
Outdated
Show resolved
Hide resolved
|
@scopsy Created caching only by subscriber id. |
@CachedEntity({ | ||
builder: KeyGenerator.subscriber, | ||
}) | ||
private async fetchSubscriber({ | ||
subscriberId, | ||
_environmentId, | ||
}: { | ||
subscriberId: string; | ||
_environmentId: string; | ||
}): Promise<SubscriberEntity | null> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we enforce the param, passed to the function to make sure that it's enforce by TS? That hsubscriberId and environment id is indeed passed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried it about a week ago and a bit struggled to do so.
const buildQueryKey = ({ | ||
type, | ||
keyPrefix, | ||
environmentIdPrefix = 'e', | ||
environmentId, | ||
identifierPrefix = 'i', | ||
identifier, | ||
query, | ||
}: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to have those unit tested
# Conflicts: # .cspell.json # apps/api/src/app/events/usecases/process-subscriber/process-subscriber.usecase.ts # apps/api/src/app/events/usecases/send-message/send-message-chat.usecase.ts # apps/api/src/app/events/usecases/send-message/send-message-email.usecase.ts # apps/api/src/app/events/usecases/send-message/send-message-in-app.usecase.ts # apps/api/src/app/events/usecases/send-message/send-message-push.usecase.ts # apps/api/src/app/events/usecases/send-message/send-message.command.ts # apps/api/src/app/events/usecases/send-message/send-message.usecase.ts # apps/api/src/app/shared/services/cache/cache.service.ts # apps/api/src/app/widgets/usecases/get-notifications-feed/get-notifications-feed.usecase.ts # apps/api/src/app/widgets/usecases/mark-all-message-as-seen/mark-all-message-as-seen.usecase.ts # apps/api/src/app/widgets/usecases/mark-message-as/mark-message-as.usecase.ts
👇 Click on the image for a new way to code review
Legend |
@djabarovgeorge Note this on the PR progress https://github.com/novuhq/novu/pull/2754/files#r1105489639 |
# Conflicts: # apps/api/src/app/events/usecases/send-message/send-message-in-app.usecase.ts # apps/api/src/app/events/usecases/send-message/send-message.usecase.ts # apps/api/src/app/events/usecases/trigger-event/message-matcher.service.spec.ts # apps/api/src/app/subscribers/usecases/get-subscriber-template-preference/get-subscriber-template-preference.command.ts # apps/api/src/app/subscribers/usecases/get-subscriber-template-preference/get-subscriber-template-preference.usecase.ts # apps/api/src/app/subscribers/usecases/update-subscriber-preference/update-subscriber-preference.usecase.ts
export class KeyGenerator { | ||
public static query = () => { | ||
return { feed, messageCount }; | ||
}; | ||
|
||
public static entity = () => { | ||
return { subscriber, integration, notificationTemplate, user, environmentByApiKey }; | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is a POC I am thinking about what could be the easiest way to interact with the methods, with IDE suggestion of the class methods
feat: refactor cache functions
…rigger feat: cache notification template by trigger identifier
} | ||
} catch (err) { | ||
// eslint-disable-next-line no-console | ||
console.error(`An error has occurred when extracting "key: ${methodName}`, 'CacheInterceptor', err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
console.error(`An error has occurred when extracting "key: ${methodName}`, 'CacheInterceptor', err); | |
Logger.error(`An error has occurred when extracting "key: ${methodName}`, 'CacheInterceptor', err); |
const variant = this.TTL_VARIANT_PERCENTAGE * num * Math.random(); | ||
|
||
return Math.floor(num - (this.TTL_VARIANT_PERCENTAGE * num) / 2 + variant); | ||
} | ||
|
||
private splitKey(key: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great to add test here
# Conflicts: # apps/api/src/app/events/usecases/send-message/send-message-in-app.usecase.ts # apps/api/src/app/topics/use-cases/index.ts
What change does this PR introduce?
It is the POC of dividing the Cached Interceptor into CachedRequest and CachedEntity, this one is the CachedEntity part, I a bit carried away and added a couple of extra queries which were not so necessary at the moment please look at the trigger flow part.
In this solution, we cache under subscriber._id && subscriber.subscriberId separately, and when we need to invalidate we invalidate by key and not by pattern.
Why was this change needed?
In order to reduce the number of scans on the Redis server.
Other information (Screenshots)