Jam.py documentation

lock

lock(self, lock_name, timeout=-1)

domain: server

language: python

class Task class

Description

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.

Example

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])