harlowja / fasteners

A python package that provides useful locks.
Apache License 2.0
243 stars 45 forks source link

InterProcessLock does not actually lock? #100

Closed slhck closed 1 year ago

slhck commented 1 year ago

Maybe there is something that I don't understand about locks, but this code allows me to run two instances of the same program concurrently:

lock = fasteners.InterProcessLock('.lock')

with lock:
    # do some work

Whereas if I really want exclusive access, I have to implement something like:

lock = fasteners.InterProcessLock(".lock")
locked = lock.acquire(blocking=False)

if locked:
    try:
        # do some work
    except Exception as exc:
        raise exc
    finally:
        lock.release()
else:
    raise RuntimeError("Could not acquire lock, is another process runnning?")

In other words, what is the purpose of the context manager function if it does not actually enforce the lock?

psarka commented 1 year ago

Hi, could you, please, provide more info, in particular your OS and fasteners version? I cannot reproduce your issue, and if I run two instances of the program you provided I get the expected exclusive behavior. In particular, I modified your example like this and ran in two terminals:

import time
import fasteners

lock=fasteners.InterProcessLock('.lock')

with lock:
    print('hi')
    time.sleep(10)
slhck commented 1 year ago

Oh, I get it now, the difference is that it's blocking by default! In your example it works — it does lock. I will close this. Thanks for your quick response!

Still: is there any way to get the context manager behavior working with a lock that does not block but raises an exception immediately?

psarka commented 1 year ago

No, context managers are not flexible and always block.

I thought about this at some point (context managers raising timeout exceptions), but don't remember now what was the conclusion :roll_eyes:

slhck commented 1 year ago

No problem, I can live with the example I gave above.