litedb-org / LiteDB

LiteDB - A .NET NoSQL Document Store in a single data file
http://www.litedb.org
MIT License
8.65k stars 1.25k forks source link

Replace Mutex name hashing with URI escaping (Fix #2543) #2557

Open Joy-less opened 1 month ago

Joy-less commented 1 month ago

Shared mode uses a named Mutex to avoid multiple processes reading/writing at the same time. LiteDB names the Mutex to contain the absolute file path of the database. But Mutex names have to be valid file paths, so this would cause an invalid file path like:

Global\c:\users\user\documents\github\litedb\litedb.tests\bin\debug\net8\demo.db.Mutex

So instead, currently it hashes the file path using SHA1 to turn it into the following:

Global\0a1ab52c4b3f3d01730f61b59e7891bc029ab372.Mutex

However, this is a hacky solution in my opinion. Someone experienced exceptions (#2543) caused when creating SHA1. This PR avoids the need to hash the path by using URL escaping:

Global\c%3A%5Cusers%5Cuser%5Cdocuments%5Cgithub%5Clitedb%5Clitedb.tests%5Cbin%5Cdebug%5Cnet8%5Cdemo.db.Mutex

Also, I changed it to use .ToLowerInvariant() instead of .ToLower() because Windows file paths are case insensitive even for non-ASCII characters (e.g. É and é).

This PR should fix #2543 since it removes hashing.

Joy-less commented 1 month ago

I should just mention that since this changes the name of the Mutex, shared mode won't lock correctly if you have two processes where one is using the current or older version of LiteDB and one is using a future LiteDB version.

JKamsker commented 1 week ago

Super hard to accept prs that are hard to test :/

Joy-less commented 1 week ago

Super hard to accept prs that are hard to test :/

I don't think so... It's pretty simple. If you like, I can write a test to ensure two connections can still be active at once.

JKamsker commented 1 week ago

Tbh i am unsure about this change. can we have a setting at userlevel that allows to set a flag for this? (Default this behaviour)