-
Notifications
You must be signed in to change notification settings - Fork 38
lock state files for session persistent tables #4870
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
base: main
Are you sure you want to change the base?
lock state files for session persistent tables #4870
Conversation
|
Hi! Thank you for contributing! |
eedeac6 to
276f827
Compare
39947be to
614e9b5
Compare
| NProto::TError TryInit(bool restoreClientSession) | ||
| { | ||
| auto handlesPath = StatePath / "handles"; | ||
| auto indexPath = StatePath / "nodes"; |
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 are leaking implementation details from TLocalIndex into TSession. TSession shouldn't know that there is a "nodes" file which is used by the TIndex
| auto handlesPath = StatePath / "handles"; | ||
| auto indexPath = StatePath / "nodes"; | ||
|
|
||
| if (!TryLockFile(handlesPath, HandlesFileLock) || |
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.
Locking handles here is premature because the file may be deleted later:
if (isNewSession) {
...
handlesPath.DeleteIfExists();
| return makeResponse(*it->second); | ||
| } | ||
|
|
||
| auto clientSessionStatePath = StatePath / ("client_" + clientId); |
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 simplest and safest fix is to create a dedicated lock file in clientSessionStatePath (e.g. session.lock or state.lock) and never delete it. Then lock that file to guard the whole session state.
| { | ||
| TTestBootstrap bootstrap; | ||
| bootstrap.CreateFileStore("fs", "cloud", "folder", 100500, 500100); | ||
| TTempDirectoryPtr bootstrapCwd; |
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.
Is there actually a new test that tests that it's forbidden to run two instances of same TSession ?
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.
ShouldFailToLockSessionStateTwice
|
|
||
| Y_UNIT_TEST(ShouldRecoverSessionHandles) | ||
| { | ||
| TTestBootstrap bootstrap("fs", "client"); |
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.
To avoid extra refactoring in UTs, add CloseStore to TTestBootstrap and call it explicitly when needed.
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.
StopFileStore
| TString expectedSessionId; | ||
|
|
||
| for (auto& file: files) { | ||
| auto handle = |
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.
Need to test this in devlab as well. Run filestore-vhost-local create fs, start endpoint attach vm. Then run another filestore-vhost-local process and see what happens
614e9b5 to
0fb8d64
Compare
|
Note This is an automated comment that will be appended during run. 🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit 0fb8d64.
🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit 0fb8d64.
🟢 linux-x86_64-relwithdebinfo: all tests PASSED for commit 0fb8d64.
|
|
Note This is an automated comment that will be appended during run. 🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit c7cc5f8.
🔴 linux-x86_64-relwithdebinfo: some tests FAILED for commit c7cc5f8.
🟢 linux-x86_64-relwithdebinfo: all tests PASSED for commit c7cc5f8.
|
| void Init(bool restoreClientSession) | ||
| virtual ~TSession() | ||
| { | ||
| UnlockFile(SessionFileLock); |
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.
Do we need destructor here ? The TFileLock will close the file when it's destroyed and this will unlock it automatically
| UnlockFile(SessionFileLock); | ||
| } | ||
|
|
||
| NProto::TError TryInit(bool restoreClientSession) |
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 can keep calling the function Init() and just add return value
| } | ||
|
|
||
| auto clientSessionStatePath = StatePath / ("client_" + clientId); | ||
| clientSessionStatePath.MkDir(); |
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 let's just move the whole session state lock logic here. Create TFileLock to guard the session state, lock it and move it to TSession. When the TSession object destroyed the file lock will be automatically released. Also let's do unit tests in session_ut.cpp
#3745
Add option for TPersistentTable to lock the state file. Avoid state corruption if case of several vhosts accidentally start with the same parameters on the same machine.