This project is read-only.

ILockFileManager on cloud hosting

Topics: Core
Feb 27, 2012 at 6:43 PM

I've learned today from Sarki that there is such as ILockFileManager and other corresponding lock file management interfaces with corresponding implementations. Do these work (or even: are there existing alternatives that work) in a cloud hosting environment where writing to local files is limited?


Feb 27, 2012 at 8:06 PM

To clarify: really I'm looking for a reliable solution for locking a code snippet that will work in any environment, across all nodes if there are more than one. The current issue is with Combinator trying to overwrite combined resource files if there are simultaneous requests for the same set of resources. In this specific scenario file existence check with IStorageProvider or composite unique keys with Migrations would also do it, but those are not yet implemented.

Feb 27, 2012 at 8:38 PM

This service will just lock for a single instance. It's used by the indexing service right now which has each server independent. You could use TaskLease instead, which is used to give work tokens to different servers. 

Feb 27, 2012 at 10:24 PM

Thanks! TaskLease just seems right.

However looking at its implementation I wonder if I would run into the same problems as with my current (essentially very similar) implementation: here if to requests (even if on the same server) would try to acquire the same task simultaneously it could happen that both think the task is not yet acquired (this can happen in the time frame between checking the existence of a TaskLeaseRecord and creating it if not found). Now this is not as impossible as it sounds :-), I actually can reproduce it reliably on my dev box.

Also I'm unsure how I would implement "locking", i.e. here polling Acquire() to wait for the other worker to finish. Is there an example of properly using this service? I couldn't find one.

Feb 27, 2012 at 10:27 PM

You can do some "retry" loop. The resources should not change so often.

Feb 27, 2012 at 11:35 PM

Thanks, I was thinking along the lines of Thread.Sleep() for a few times till the acquire is released; I've read controversial statements about its impact on throughput, though. However this shouldn't be a bottleneck anyway. Another approach would be to simply return uncombined resources; this is not nice but wouldn't happen too often anyways.

Feb 28, 2012 at 10:45 PM
Edited Feb 28, 2012 at 10:46 PM

Thinking a bit further: I don't really understand how TaskLease should work regarding transactions. AFAIK (I'm new to transactions, so I'm unsure) the transaction for the request gets commited on the end of the request. Now if there are two (nearly) simultaneous requests for the same task (that runs for the life time of a request) it can happen (and I think I can produce this on my dev box) that one task starts to run before another one times out or frees up its task acquire. That means that although one request acquired the task before the other one the slower request doesn't know of the record created by the quicker one since it's not yet in the DB.

So is TaskLease designed to work if a task runs only as long as one request?

Feb 29, 2012 at 1:52 PM

It seems for me that using creating a locker file with IStorageProvider would work better in this case.