-
Notifications
You must be signed in to change notification settings - Fork 115
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
Operation repo refactor #1179
Operation repo refactor #1179
Conversation
5424208
to
a9bc2dc
Compare
src/core/executors/ExecutorStore.ts
Outdated
Object.values(this.store).forEach((executor) => { | ||
if ( | ||
executor instanceof SubscriptionExecutor && |
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.
Does the ExecutorFactory
already ensure we don't have duplicate executors? Or if it doesn't take care of it, shouldn't we just omit adding it in the first place?
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.
Under this PR, the factory will return the reference to the single static subscription executor three times and be mapped to via the three ModelName
keys that correspond to it: pushSubscriptions, emailSubscriptions, and smsSubscriptions
There's probably a cleaner way to do this without hard-coding a check here
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.
Adding on to what rgomezp said:
The ExecutorStore creates an executor for each value in ModelName
And there are 3 names for subscriptions:
- Identity
- Properties
- PushSubscriptions
- EmailSubscriptions
- SmsSubscriptions
This PR should ensure that there are no duplicate executors from the ExecutorFactory
. But we could omit adding it in the first place by having 1 ModelName
for the subscription executor instead. I don't think this would heavy lift but I'm not sure.
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.
The ModelName
enum is widely used, not just for the executor factory.
You would have to change the way the ExecutorStore
indexes the executors to only have 3 keys. But this adds a point of maintenance in the future should we add new supported models.
Is there an issue arising from the differences in behavior between the WebSDK & iOS? Or is this PR aimed at bringing the SDKs to parity to address an outstanding issue?
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.
Having one flush that is controlled by the operation repo would make it easier to implement a JWT feature where we would like to pause the operation repo when we receive an invalid token. And with changing to 1 flush, I didn't think there would be a need to have 3 separate subscription executors for push, sms, email.
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.
But this adds a point of maintenance in the future should we add new supported models.
Could you elaborate on what maintenance would be needed?
You would have to change the way the ExecutorStore indexes the executors to only have 3 keys.
I thought this change would consist of changing the enum and the previous references to use 1 subscription enum. What other things would need to be done?
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.
Could you elaborate on what maintenance would be needed?
The executor store store interface looks like
type ExecutorStoreInterface = {
[key in ModelName]?: OSExecutor;
};
If you change it to say
type ExecutorStoreInterface = {
identity: OSExecutor;
properties: OSExecutor;
subscriptions: OSExecutor;
};
or similar you would have to update in two places should you add new model types. Not a huge deal though.
I thought this change would consist of changing the enum and the previous references to use 1 subscription enum. What other things would need to be done?
The enum isn't just used for creating executors. It's used throughout the user-model SDK.
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.
I believe it would instead be changing this code:
export enum ModelName {
Identity = 'identity',
Properties = 'properties',
// TO DO: make singular
PushSubscriptions = 'pushSubscriptions',
EmailSubscriptions = 'emailSubscriptions',
SmsSubscriptions = 'smsSubscriptions',
}
to this:
export enum ModelName {
Identity = 'identity',
Properties = 'properties',
Subscriptions = 'subscriptions',
}
I think this will simply things and means if we add another subscription type we won't have to change this again. We will have to update code that depends on ModelName
however, and migrate any existing cached operations to the new name though.
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.
I think this will simply things and means if we add another subscription type we won't have to change this again. We will have to update code that depends on ModelName however, and migrate any existing cached operations to the new name though.
That's a big lift. We also rely on the model name to differentiate between subscription models, like in the CoreModuleDirector
, OSModel
, etc...
src/core/executors/ExecutorStore.ts
Outdated
Object.values(this.store).forEach((executor) => { | ||
if ( | ||
executor instanceof SubscriptionExecutor && |
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.
Under this PR, the factory will return the reference to the single static subscription executor three times and be mapped to via the three ModelName
keys that correspond to it: pushSubscriptions, emailSubscriptions, and smsSubscriptions
There's probably a cleaner way to do this without hard-coding a check here
f2ca9d4
to
65ed239
Compare
7d53a4a
to
0f60a67
Compare
6e61697
to
7a2bcf7
Compare
5c0d2b6
to
1f73e80
Compare
de0cb83
to
9992570
Compare
9992570
to
937d585
Compare
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.
Just a couple comments. After this I think LGTM
Added a delta queue to the operation repo to flush all executor deltas at the same time. The operation repo's delta queue enqueues all deltas and then will sort and pass the delta to its correct executor. Previously, each executor was in charge of enqueuing and flushing their own delta queue. This change also aligns the Web SDK more with the iOS SDK's operation repo implementation.
Change pushSubscription, smsSubscription, and emailSubscription to point to the same SubscriptionExecutor. This way the SubscriptionExecutor only fires once instead of 3 times.
Running tests consecutively that enqueue operations to the SubscriptionExecutor will fail due to the operationQueue length not matching the expected value. pushSubscription, smsSubscription, emailSubscription now point to the same SubscriptionExecutor and the operationQueue was not being cleared for the next test. The other tests don't fail but I also cleared the operation queue there too.
Will be used to retry operations for users with a valid Jwt token. Accessed through Operation.model.externalId
External id from previously logged in user was kept on anonymous user's push subscription model when logged out
Change delta queue time back to 1 second. Was creating misalignment bugs due to the time being the same
Refactors ModelName enum for SmsSubscription, EmailSubscription, PushSubscription to 1 name called Subscriptions. This omits adding multiple subscription executors for sms, email, push and only creates 1 executor because all subscriptions are grouped together.
Fixes failing executor tests that result in removing the check. Tests were changed to: await the async TestEnvironment initialize function, remove additional initialization of core module because it was already created in TestEnvironment initialization, fix timers for tests that check the delta queue to check after 1 flush.
These logs clutter the console due to being called every second/5 seconds
Create new type to make it clear what subscription channel is being filtered for in getSubscriptionOfTypeWithToken
For externalId on OSModel
937d585
to
d4bbe89
Compare
Description
1 Line Summary
An operation repo refactor that will help with the implementation of identity verification
Details
pushSubscription
,smsSubscription
, andemailSubscription
model names for 1 new name:subscriptions
. This change requires a database upgrade.Operation.model.externalId
Unit Tests:
Systems Affected
Validation
Tests
Info
Checklist
Programming Checklist
Interfaces:
Functions:
Typescript:
Other:
elem of array
syntax. PreferforEach
or usemap
context
if possible. Instead, we can pass it to function/constructor so that we don't callOneSignal.context
Screenshots
Info
Checklist
Related Tickets
This change is