DistributedLock icon indicating copy to clipboard operation
DistributedLock copied to clipboard

Consider Named Mutex implementation for Cross Platform OS level locking

Open dazinator opened this issue 3 years ago • 7 comments

I saw the windows only implementation, and I wondered if you had come accross "named mutexes" in .net core / .net 5 - which I think will offer the same OS Level (inter process) locking, but will work cross platforms.

Some notes from here: https://docs.microsoft.com/en-us/dotnet/api/system.threading.mutex?view=net-5.0

Mutexes are of two types: local mutexes, which are unnamed, and named system mutexes. A local mutex exists only within your process. It can be used by any thread in your process that has a reference to the Mutex object that represents the mutex. Each unnamed Mutex object represents a separate local mutex.

Named system mutexes are visible throughout the operating system, and can be used to synchronize the activities of processes. You can create a Mutex object that represents a named system mutex by using a constructor that accepts a name.

dazinator avatar Mar 18 '21 13:03 dazinator

In terms of a lock escalation strategy, I think it would make sense to escalate in this mannor:

  1. Local process
  2. OS Level
  3. Some external coordinator (i.e sql server etc)

So this really comes in at 2) allowing a cross platform friendly way to achieve that.

dazinator avatar Mar 18 '21 13:03 dazinator

In terms of a lock escalation strategy, I think it would make sense to escalate in this mannor:

This is what #38 is all about. The way I'm imagining that design should allow for 3 levels of locking, but I anticipate that in most cases you'll want just:

  1. Local process
  2. Something more distributed (OS Level, SQL, etc)

In order to need three tiers, you need multiple processes on the same machine and across machines competing for the same lock. It's definitely possible to have that use-case, but it has never come up in the scenarios I've worked with. I'd be interested to hear about what the 3-level scenarios are that you've encountered.

"named mutexes" in .net core / .net 5 - which I think will offer the same OS Level (inter process) locking, but will work cross platform

Interesting I hadn't realized that named mutexes now work cross platform. Definitely something to investigate. One of the annoying things about Mutex as opposed to EventWaitHandle is that a held mutex is associated with a specific thread, which will make it a bit tricky to get the async semantics to work properly.

Until then, the FileDistributedLock class should provide a cross-platform approach to OS-level locking.

madelson avatar Mar 19 '21 11:03 madelson

I'd be interested to hear about what the 3-level scenarios are that you've encountered.

Not many! I was just thinking purely conceptually that this order makes sense. The only one that springs to mind would be where you have a multi-tenant platform, and a have a seperate process per tenant. For example tenant 1 and tenant 2 processes on machine A, and tenant 3 and tenant 4 processes on machine B. Suppose the processes are homogeneous and share some global "platform wide" config. You can log in as a platform admin into any of them, and update the global config. You'll need to lock the global config in order to update it. It's this kind of scenario where this would be useful - but... I admit it's a stretch and I doubt the lock would be very contended in this kind of scenario so an extra hop to to a global coordinator isn't really a big deal ;-)

dazinator avatar Mar 19 '21 11:03 dazinator

Until then, the FileDistributedLock class should provide a cross-platform approach to OS-level locking.

Good point! I haven't looked at the implementation - but has this been tested / used with file shares? Because I am wondering if there was a global file share that all machines were looking at, then this could also be set up as a global lock strategy?

dazinator avatar Mar 19 '21 12:03 dazinator

has this been tested / used with file shares

I haven't tried this. The lock is based on .NET's exclusive stream locking which uses OS-level file locking under the hood. My understanding from reading docs is that this may or may not work depending on the particular file share technology being employed. If you have any findings with a particular system let me know and I'll update the docs to include that!

madelson avatar Mar 20 '21 12:03 madelson

has this been tested / used with file shares

I haven't tried this. The lock is based on .NET's exclusive stream locking which uses OS-level file locking under the hood. My understanding from reading docs is that this may or may not work depending on the particular file share technology being employed. If you have any findings with a particular system let me know and I'll update the docs to include that!

I had azure file shares in mind - which use the SMB protocol. According to the docs here it looks like it should just work? https://docs.microsoft.com/en-us/rest/api/storageservices/managing-file-locks#smb-file-locking I will eventually try it and update here if any issues.

dazinator avatar Mar 20 '21 18:03 dazinator

Note to self: came across WaitThread in the runtime which offers a pattern we could follow for this.

madelson avatar Jul 09 '22 12:07 madelson