-
Notifications
You must be signed in to change notification settings - Fork 24
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
Limit writes to session file #243
Limit writes to session file #243
Conversation
Package publishing
Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation. |
'session_id': now.millisecondsSinceEpoch, | ||
'last_ping': now.millisecondsSinceEpoch, | ||
})); | ||
sessionFile.writeAsStringSync('${now.millisecondsSinceEpoch}'); |
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.
Actually, when we discussed this yesterday, I was assuming this was the client ID, and we'd never need to re-write this. Since this is the session ID, this means we would still need to write to this when starting a new session, and another process could read from it in the middle of a write, do I have that correct?
If so, I have a few thoughts:
- using last modified timestamp still seems like an improvement, and we'd at least get less race conditions
- STILL using JSON is probably better, because then we would get a parse error vs. just getting the WRONG session_id
- let's just hard-code the json as a string, rather than invoking the overhead of
jsonEncode
- maybe it's enough to catch the parse error, and then re-try 1 second later?
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 agree with all of these points. Removing the last ping key should be easy enough. Also with the refactor to prevent a huge amount of write operations, I think we may be able to fall back to attempting to paraeContents
again?
If we see that this is still coming up in the error logs for the race condition, we can return to setting the sessionId back to the current timestamp. Thoughts?
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 we may be able to fall back to attempting to paraeContents again?
It would still be possible for the second parse to fail, right?
If we see that this is still coming up in the error logs for the race condition, we can return to setting the sessionId back to the current timestamp.
Not sure what you mean here. Are you proposing using something else other than the current timestamp for the sessionId?
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.
It would still be possible for the second parse to fail, right?
Yes, the parseContents
method always has the possibility of failing.
Not sure what you mean here. Are you proposing using something else other than the current timestamp for the sessionId?
And what I meant here is monitoring the crash logs to see if we run into this race condition again... i would suspect that we would have a lot less instances of this error since we are now writing a lot less by checking File.lastModifiedSync
method
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.
Okay so I think i found a better solution now in my latest commit
If we fail when we attempt Session.parseContents
, we will now set the session id to be the current timestamp (within the catch
blocks), and then we will also pass this timestamp to the file so that whatever we have set in the error handling blocks agrees with what is persisted. How does that sound?
|
||
Session({ | ||
required this.homeDirectory, | ||
required this.fs, | ||
required ErrorHandler errorHandler, | ||
}) : sessionFile = fs.file(p.join( | ||
homeDirectory.path, kDartToolDirectoryName, kSessionFileName)), | ||
_sessionId = DateTime.now().millisecondsSinceEpoch, |
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 seems like it's "solving" the problem of LateInitializationError by assigning the variable the wrong value. Or am I misunderstanding how this works?
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.
You're correct, this value is getting set when calling the constructor and it will eventually get replaced when we run Session.initialize
. This just makes it so that we don't have to make the variable late
.
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.
It's technically not an invalid session id since later on in the code, we could be setting the this value in the file because we need a new session id if the old one had 30 mins of inactivity
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.
we could be setting the this value in the file because we need a new session id if the old one had 30 mins of inactivity
But if it has NOT been 30 minutes of inactivity, the correct session ID would be a different value, right?
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.
Yes that's correct, we would have to decide if that is worth it to remove the late
variable
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.
lemme take a look at this later today?
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.
sgtm, no rush
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.
from discussion, maybe we should just make _sessionId nullable, and allow sending a null session id. this would also help when sending errors.
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.
Yep this makes sense with me, i also just confirmed that sending null
for the session id is a valid json payload for GA4
// Initialize the session handler with the session_id and last_ping | ||
// variables by parsing the json file | ||
// Initialize the session handler with the session_id | ||
// by parsing the json file |
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.
As a side note, I think we should refactor the error handling class so that it doesn't depend on session data AND remove the need for the log handler
This is because:
- Having session information for error reports is not necessary, this is just for maintainers of this package so we know what errors are coming up in the wild
- We can also remove the need for the log handler because there is no value in locally persisting the error event on the user's computer (this log file is used for the survey handler feature, we are not using error events for targeting users)
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.
LGTM
Fixes:
File.lastModifiedSync
for_lastPing
#240Related to:
This update makes it so that we only write to the session file only when the session id needs to be updated. Previously, we were writing with every event in order to keep track of when the last ping was so that we can keep the session alive or start a new one.
We now instead use the last modified timestamp for the session file as a stand in for when the last ping happened.
The file's format has also changed
Contribution guidelines:
dart format
.Note that many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.