-
Notifications
You must be signed in to change notification settings - Fork 5.3k
BZ 69781 - improve FileStore thread safety #882
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
Conversation
04f4ff7
to
cff0888
Compare
There is slight disagreement between Is there a specific reason for that? If not, please make all operations uniform in their operation. |
Thanks for the feedback @ChristopherSchultz. That primarily happened as I was trying to ensure that |
I'm not sure I see a change. In Also, please don't force-push and overwrite the commits. It's fine to have a PR with 10 commits. It makes is much easier to review the follow-up changes you've made. |
throw new IOException(sm.getString("fileStore.deleteSessionFailed", file)); | ||
try{ | ||
acquireIdWriteLock(id); | ||
if (file.exists() && !file.delete()) { |
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'll actually modify (remove) the session file here so we should acquire the lock to protect from modifying the file during any potential load that may be reading it.
ObjectInputStream ois = getObjectInputStream(fis)) { | ||
try { | ||
acquireIdReadLock(id); | ||
if (!file.exists()) { |
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.
If we've confirmed the file exists for us to read, then we don't want it modified or deleted from this point through to the read completion. So we grab the lock before file.exists and hold to read completion. If we checked file.exists
before the lock in save
, then it's not truly protected from a delete/modification from another thread right after before the save
then acquires the lock and completes its read.
((StandardSession) session).writeObjectData(oos); | ||
try { | ||
acquireIdWriteLock(session.getIdInternal()); | ||
try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath()); |
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 save
is not consuming or removing existing data so it does not care or need to check if the file exists or not already. We just need to acquire the lock before writing any actual data to ensure we don't modify the data during a load
operations data read.
I've added a test case for this to main (12.0.x). I haven't looked at the proposed solution yet. |
Since there's an issue, the main question is if the extra code belongs to the store. The main problem is that there are two entry points to the store: the PersistentManagerBase but also the PersistentValve (not good). |
I took a look at the patch and it looks OK. I think there is some were similar locking code in web resources but we can look at refactoring once this patch is committed. I also looked at whether this needed a store level fix and I don't think it does. The requirement is that the Store implementation needs to support concurrent calls to Any objections to accepting this PR at this point? |
+1 then, I haven't had time to review it yet. |
The test case has found an issue with this implementation. The issue is that usage increments/ |
Closing this PR as it doesn't fully address the concurrency issues. I have a fix based on this PR that does address them that I will apply and then back-port shortly. |
No description provided.