domain: server
language: python
class Task class
Use lock
to implement a platform independent file lock in Python, which
provides a simple way of inter-process communication.
This method is a wrapper around Python filelock library: https://github.com/benediktschmitt/py-filelock
Once lock has been acquired, subsequent attempts to acquire it block execution, until it is released.
lock_name
parameter is the name of the lock. It must be unic in the
application. The filelock library creates a file in the locks folder with
this name and .lock extention that it uses to implement the lock.
timeout
parameter - if the lock cannot be acquired within timeout seconds, a
Timeout exception is raised.
The code
def calculate(item):
lock = item.task.lock('calculation'):
lock.acquire()
try:
#some code
finally:
lock.release()
is equivalent to
def calculate(item):
with item.task.lock('calculation'):
#some code
The example with timeout:
from jam.third_party.filelock import Timeout
def calculate(item):
try
with item.task.lock('calculation', timeout=10):
#some code
except Timeout:
print("Another instance of this application currently holds the lock.")
In the following example when saving invoice the app calculates sold tracks. Before doing this it acquires a lock:
def on_apply(item, delta, params):
with item.task.lock('invoice_saved'):
tracks_sql = []
delta.update_deleted()
for d in delta:
for t in d.invoice_table:
if t.rec_inserted():
sql = "UPDATE DEMO_TRACKS SET TRACKS_SOLD = COALESCE(TRACKS_SOLD, 0) + \
%s WHERE ID = %s" % \
(t.quantity.value, t.track.value)
elif t.rec_deleted():
sql = "UPDATE DEMO_TRACKS SET TRACKS_SOLD = COALESCE(TRACKS_SOLD, 0) - \
(SELECT QUANTITY FROM DEMO_INVOICE_TABLE WHERE ID=%s) WHERE ID = %s" % \
(t.id.value, t.track.value)
elif t.rec_modified():
sql = "UPDATE DEMO_TRACKS SET TRACKS_SOLD = COALESCE(TRACKS_SOLD, 0) - \
(SELECT QUANTITY FROM DEMO_INVOICE_TABLE WHERE ID=%s) + %s WHERE ID = %s" % \
(t.id.value, t.quantity.value, t.track.value)
tracks_sql.append(sql)
sql = delta.apply_sql()
return item.task.execute(tracks_sql + [sql])