Skip to content
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

Multi Triggers -> Develop #395

Draft
wants to merge 41 commits into
base: develop
Choose a base branch
from
Draft

Conversation

akashvercetti
Copy link
Collaborator

No description provided.

akashvercetti and others added 30 commits October 30, 2024 10:52
- TODO: Call IsEventFirstTime from the new db/localDataStore class
- Renamed one letter object names to fit the context
- TODO: Call appropriate persist method from the new db/localDataStore class
- Added new class CTEventDatabase to store user events in database.
- Added create table, insert, update and check event methods.
…ofile-events

[MC-2088] Evaluate first time profile events
…ents

 [MC-2086] Evaluate first time events
- synchronised userEventLogs set access
…e to the database. updated tests. added normalised names to queries.
Copy link
Contributor

@nzagorchev nzagorchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In - (void)processEvent:(NSDictionary *)event withType:(CleverTapEventType)eventType the event is written to the local storage and further down in the same method the evaluation manager is called to evaluate the in-apps for the event.
The local data store calls persistEvent which calls self.dbHelper upsertEvent in a background queue with dispatch_async. The database then runs the query in the database queue.
The evaluation is done on the serial queue on which the events are processed and queued.
The current flow is persistEvent, upsertEvent, evaluateOnEvent, eventExists, update success, upsert success. However, this does not seem guaranteed since code runs on different queues. This opens for potential race conditions. Please check this.

Please check the comments left. I have not finished reviewing all files but I believe the feedback provided is enough for discussion. I will leave additional comments if I have more suggestions.

dispatch_queue_t _databaseQueue;
}

+ (instancetype)sharedInstanceWithConfig:(CleverTapInstanceConfig *)config {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CTEventDatabase shared instance with config is bit misleading that it can return a different instance based on the config and use a shared instance with same configs. Do we want separate databases per account id?
The CTEventDatabase is only used in the local store, does it need to be a singleton?

- (instancetype)initWithConfig:(CleverTapInstanceConfig *)config {
if (self = [super init]) {
_config = config;
_databaseQueue = dispatch_queue_create([[NSString stringWithFormat:@"com.clevertap.eventDatabaseQueue:%@", _config.accountId] UTF8String], DISPATCH_QUEUE_CONCURRENT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a concurrent queue for database access is generally discouraged unless reads and writes are separated or synchronized.
Also, all calls to this queue are dispatch_sync which negates its concurrency to be DISPATCH_QUEUE_CONCURRENT.

CleverTapSDK/EventDatabase/CTEventDatabase.m Outdated Show resolved Hide resolved
CleverTapSDK/EventDatabase/CTEventDatabase.m Outdated Show resolved Hide resolved
CleverTapSDK/EventDatabase/CTEventDatabase.m Outdated Show resolved Hide resolved
CleverTapSDKTests/CTLocalDataStoreTests.m Outdated Show resolved Hide resolved
CleverTapSDKTests/CTLocalDataStoreTests.m Outdated Show resolved Hide resolved
CleverTapSDKTests/CTLocalDataStoreTests.m Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it is better to use the CTClock protocol (CTSystemClock implementation) to get the current timestamp (see the CTImpressionManager). This will allow easier mocking and testing.

deviceID:kDeviceID];

NSInteger firstTs = [self.eventDatabase getFirstTimestamp:self.normalizedEventName deviceID:kDeviceID];
XCTAssertEqual(firstTs, currentTs);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can easily fail if the insertEvent takes more than a second or there is code executed between setting currentTs and calling insert.

This is valid for other tests as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants