Search code examples
grailsservicetransactionssingleton

Check if a Grails' service method is already running with certain parameter


I'm using grails 4.0.6 and I need to check if a given service's method is in execution with a certain domain object's instance. In this case, the method takes a long time to run and it is called with a parameter (a domain class' instance). If it is called again with the same instance that it is currently in execution with, the call must be aborted. I tried setting a flag in the domain class (and flushed the update) however it is not reflected in the new call. Any hints are appreciated.


Solution

  • If you need to abort the second call, use a Lock. If you just don't want them running concurrently, use a synchronized block.

    Lock:

    class MyService {
        static def locks = [:]
    
        def someMethod(inputParam) {
            def key = "${inputParam.class}${inputParam.id}"
            def lock = locks.get(key)
            if (!lock) {
                lock = new ReentrantLock()
                locks.put(key, lock)
            }
            if (lock.tryLock()) {
                // do your work here
                lock.unlock()
            }
        }
    }
    

    Synchronized:

    Your service method would pretty much be

    synchronized (key) {
        // your work
    }
    

    Any of this may need tweaks...I just typed it in here without any testing!