jenkinsci / lockable-resources-plugin

Lock resources against concurrent use
https://plugins.jenkins.io/lockable-resources
MIT License
88 stars 184 forks source link

Non-blocking or timeouted lock step #30

Open nick-rumyantsev opened 8 years ago

nick-rumyantsev commented 8 years ago

It would be nice to have a tryLock; body; releaseLock execution flow in addition to an existing lock { body }. This will allow to implement any custom resource selection logic, i.e.

  1. Try lock the best (fastest, cheapest, your personal favorite, etc) available environment.
  2. Oh, it is occupied at the moment, let's fallback to another one
body = { business logic here }
// say, I have two resources: "cheap" and "expensive", both share the label "test env"
lockObj = tryLock label:'cheap env'
if (! lockObj) // okay-okay, let's just wait for any of envs available
    lock label:'test env', body: body //no timeout here

Until label locking is not implemented, this can help work it around:

// I have 10 similar resources: env1, env2, env3...env10
i=0
waitUntil {
    i++
    if (i>10) {
        i=0 //enumarate again
        sleep 10 //make it a little less fanatical
    }
    tryLock "env$i" // should return something coerced to true on success
}

The lock obtaining func should return some lock object and user is obliged to save its value for further releasing. Good-old try-finally to ensure that resource is released:

try{
    lockObj = tryLock 'env'
} finally {
    lockObj.release() //this will help user not to forget to save a variable and will not allow to release others' resources.
}

Alternatively we could extend existing lock step with timeout filed which limits the phase of lock obtaining. The step itself shoud return boolean whether it manage to acquire a lock or not:

body = { business logic here }
// say, I have two resources: "cheap" and "expensive", both share the label "test env"
boolean lockObtained = lock label:'cheap env', body: body, timeout: 1 /*min*/
if (! lockObj) // okay-okay, let's just wait for any of envs available
    lock label:'test env', body: body //no timeout here
amuniz commented 8 years ago

I see the option of adding a timeout parameter more interesting (and simple to use) than the other approach.

amuniz commented 8 years ago

BTW, please use https://issues.jenkins-ci.org to file issues on this plugin (component lockable-resources-plugin). Thanks.

mPokornyETM commented 1 year ago

To get next free resource will be possible soon by shared groovy library. In that case you will be able to implement it. But I will try to implement it directly in the java plugin source. Because using of sleep step in the pipeline will waste our logs. That means we need new property like waitForLockTimeout.