Second delay
sleep(10);
Sleep(seconds), keep trying every second until the checkout is successful.
Example code:
int err_stat;
err_stat = 1;
while (err_stat) {
send_wait(0, group_leader, "checkout", dob_ref);
if (!msg_error()) {
err_stat = 0;
} else {
sleep(1); // 1 second
}
Where can I find Spel functions documentation?
Thank you cdtj,
I've modified my code using your suggestion.
Hi Grant,
anything can happen mainly on peak periods multiple scripts can try to access same object and cause a deadlock.
Michael, thanks for sharing, I really missed that method!
another suggestion, if youre using some scripts that hanging (or deadlocking) frequently but at this moment you can't rewrite or disable it, calling method with timeout could be a better way:
int send_failed, send_timeout;send_timeout = 60; // in secondssend_failed = send_wait(send_timeout, obj, method, ...);if (send_failed) {// handling timeout} else if (msg_error()) {// handling error} else {// doing somethng}
Regards.
Just another approach for this specific question regarding checkout retries:
send_wait(0, group_leader, "sure_checkout", object, delay, retries);
this ootb method will try to checkout the object "retries" times, and will more or less double the delay time between each retry, starting with "delay".
Very convinient and sytem conform, if you need to make sure, that the checkout take place.
It still might fail and you have to handle this case of course, but under usual circumstances, this will do the job.
If it still fails, I would handle this as an exceptional behaviour, with appropriate error messaging . It is very unusual that a lock from a different group leader will exist that amount of time, and I would assume that something else is going wrong in this case.
Regards
..............Michael
Hi cdtj,
Thank you for the feedback. I figured the code was safe because it checked to see if the object was locked or checked out, and only retires for those error messages. Do you really think an object can be checked out indefinitely?
In my testing it exits the loop after the first or second iteration.
it's dangerous to use this code in prod env because it can cause infinite loop, also script that called in a single thread will be locked for all the time.
better way:
checked_out = 1;z_ticker = 0;z_tick_limit = 5;// loop will be terminated on tick limitwhile ((checked_out) && (z_ticker < z_tick_limit)) { // Send manual notfiy send_wait(0, top_object(), "call_attr", "api", "notify_contacts", who, persistent_id, subject, body, 1, 0, (string) format("cnt:%s", (uuid) customer)); if (msg_error()) { logf(ERROR, "Error with manual notify activity: %s", msg[0]); if (sindex(msg[0], "Object is CO") > 0 || sindex(msg[0], "locked") > 0 || sindex(msg[0], "checked out") > 0) { logf(MILESTONE, "%s falls asleep, ticker: %d", method, z_ticker); checked_out = 1; } else { checked_out = 0; logf(MILESTONE, "%s ended on ticker: %d", method, z_ticker); return; } sleep(1); // 1 second } else { checked_out = 0; } // increment ticker z_ticker++;}
Here's an example using a while loop to see if an object is checked out and waiting to 1 second. This code is called in a POST_CI trigger.
checked_out = 1;while(checked_out){//Send manual notfiysend_wait(0, top_object(), "call_attr", "api", "notify_contacts", who, persistent_id, subject, body, 1, 0, (string) format("cnt:%s", (uuid)customer));if (msg_error()) { logf(ERROR,"Error with manual notify activity: %s",msg[0]); if(sindex(msg[0],"Object is CO") > 0 || sindex(msg[0],"locked") > 0 || sindex(msg[0],"checked out") > 0){ checked_out = 1; } else{ checked_out = 0; logf(MILESTONE, "%s ended", method); return; } sleep(1); // 1 second}else{ checked_out = 0;}}