How can I execute an
os.execute("example.exe") with a timeout of 'n' seconds in Lua?
By timeout I mean if 'example.exe' takes more than 'n' seconds to finish execution, it has to be terminated forcibly and lua script must continue executing the statements after os.execute('example.exe').
Related
I'm doing a parametric sweep of some Abaqus simulations, and so I'm using the waitForCompletion() function to prevent the script from moving on prematurely. However, occassionally the combination of parameters causes the simulation to hang on one or two of the parameters in the sweep for something like half an hour to an hour, whereas most parameter combos only take ~10 minutes. I don't need all the data points, so I'd rather sacrifice one or two results to power through more simulations in that time. Thus I tried to use waitForCompletion(timeout) as documented here. But it doesn't work - it ends up functioning just like an indefinite waitForCompletion, regardless of how low I set the wait time. I am using Abaqus 2017, and I was wondering if anyone else had gotten this function to work and if so how?
While I could use a workaround like adding a custom timeout function and using the kill() function on the job, I would prefer to use the built-in functionality of the Abaqus API, so any help is much appreciated!
It seems like starting from a certain version the timeOut optional argument was removed from this method: compare the "Scripting Reference Manual" entry in the documentation of v6.7 and v6.14.
You have a few options:
From Abaqus API: Checking if the my_abaqus_script.023 file still exists during simulation:
import os, time
timeOut = 600
total_time = 60
time.sleep(60)
# whait untill the the job is completed
while os.path.isfile('my_job_name.023') == True:
if total_time > timeOut:
my_job.kill()
total_time += 60
time.sleep(60)
From outside: Launching the job using the subprocess
Note: don't use interactive keyword in your command because it blocks the execution of the script while the simulation process is active.
import subprocess, os, time
my_cmd = 'abaqus job=my_abaqus_script analysis cpus=1'
proc = subprocess.Popen(
my_cmd,
cwd=my_working_dir,
stdout='my_study.log',
stderr='my_study.err',
shell=True
)
and checking the return code of the child process suing poll() (see also returncode):
timeOut = 600
total_time = 60
time.sleep(60)
# whait untill the the job is completed
while proc.poll() is None:
if total_time > timeOut:
proc.terminate()
total_time += 60
time.sleep(60)
or waiting until the timeOut is reached using wait()
timeOut = 600
try:
proc.wait(timeOut)
except subprocess.TimeoutExpired:
print('TimeOut reached!')
Note: I know that terminate() and wait() methods should work in theory but I haven't tried this solution myself. So maybe there will be some additional complications (like looking for all children processes created by Abaqus using psutil.Process(proc.pid) )
According to the syntax of ie.waitforcomplete command, it takes input in terms of milliseconds but while I was running this code, it does for 10 seconds as it should.
ie.open google.com nowait true
window ✱internet✱
ie.seturl g1ant.com
ie.waitforcomplete 1000
ie.seturl duckduckgo.com
As manual suggests, ie.waiforcomplete "suspends script execution until a webpage is loaded". The first argument is timeout which "specifies time in milliseconds for G1ANT.Robot to wait for the command to be executed". It simply means that when you have:
ie.waitforcomplete 1000
It will wait for maximum time of 1000 milliseconds (1 second) for a webpage to load, if it fails, an exception will occurr.
And the following code means that it will wait for maximum time of 10 seconds.
ie.waitforcomplete 10000
Lets say I have a tcl script which should normally execute in less than a minute - How could I make sure that the script NEVER takes more than 'x' minutes/seconds to execute, and if it does then the script should just be stopped.
For example, if the script has taken more than 100 seconds, then I should be able to automatically switch control to a clean up function which would gracefully end the script so that I have all the data from the script run so far but I also ensure that it doesn't take too long or get stuck infinitely.
I'm not sure if this can be done in tcl - any help or pointers would be welcome.
You could use interp limit when you use a child interpreter.
Note that this will throw an uncachable error, if you want to do some cleanup you to remove the limit in a parent interp.
set interp [interp create]
# initialize the interp
interp eval $interp {
source somestuff.tcl
}
# Add the limit. From now you have 60 seconds or an error will be thrown
interp limit $interp time -seconds [clock seconds] -milliseconds 60000
set errorcode [catch {interp eval {DoExpensiveStuff}} res opts]
# remove the limit so you can cleanup the mess if needed.
interp limit $interp time -seconds {}
if {$errorcode} {
# Do some cleanup here
}
# delete the interp, or reuse it?
interp delete $interp
# And what shall be done with the error? Throw it.
return -options $opt $res
Resource limits are the best bet with Tcl, but they are not bullet-proof. Tcl can not (and will not) abort C procedures, and there are some ways to let the Tcl core do some hard working.
There must be a loop that you're worried might take more than 100 seconds, yes? Save clock seconds (current time) before you enter the loop, and check the time again at the end of each iteration to see if more than 100 seconds have elapsed.
If for some reason that's not possible, you can try devising something using after—that is, kick off a timer to a callback that sets (or unsets) some global variable that your executing code is aware of—so that on detection, it can attempt to exit.
In PHP if I set the the memory 100M via ini_set and then I set set_time_limit(0); Does that mean that my PHP memory allocation is 100M forever(Until I restart my Apache)?
No its reset back to the original at the end of script execution.
From the manual:
string ini_set ( string $varname , string $newvalue )
Sets the value of the given configuration option. The configuration
option will keep this new value during the script's execution, and
will be restored at the script's ending.
and set_time_limit(0); is treated the same.
Example:
// 1. Script starts
echo ini_get('memory_limit');//128M
// 2. We set a new limit the script will now have 100M
ini_set('memory_limit','100M');
echo ini_get('memory_limit'); //100M
die;
// 3. Script ends now its set back to 128M
With set_time_limit(0); it just tells the script to not time out, tho say you were to use set_time_limit(0); within a loop then on each iteration its internal counter is set to 0 over and over.
So if you were to use set_time_limit(1); within a loop as long as each iteration of the loop did not last longer then 1 second then it would still not time out as set_time_limit(n); would reset the internal timeout counter to 0 on each iteration.
Example of it not timing out after 1 second:
for($i=0;$i<=10;$i++){
set_time_limit(1);
usleep(999998); //2micro seconds from a second
echo $i;
}
I received such message in erlang condose at first#localhost node
=ERROR REPORT==== 1-Jan-2011::23:19:28 ===
** Node 'second#localhost' not responding **
** Removing (timedout) connection **
My question is - what is timeout in this case? How much time before causes this event?
Howto prevent this "horror"? I can restore\recover to normal work only by restart node...
But what is the right way?
Thank you, and Happy New Year!
Grepping for the not responding string in the Erlang source code, you can see how the message is generated in the dist_util module in the kernel application (con_loop function).
{error, not_responding} ->
error_msg("** Node ~p not responding **~n"
"** Removing (timedout) connection **~n",
[Node]),
Within the module, the following documentation is present, explaining the logic behind ticks and not responding nodes:
%%
%% Send a TICK to the other side.
%%
%% This will happen every 15 seconds (by default)
%% The idea here is that every 15 secs, we write a little
%% something on the connection if we haven't written anything for
%% the last 15 secs.
%% This will ensure that nodes that are not responding due to
%% hardware errors (Or being suspended by means of ^Z) will
%% be considered to be down. If we do not want to have this
%% we must start the net_kernel (in erlang) without its
%% ticker process, In that case this code will never run
%% And then every 60 seconds we also check the connection and
%% close it if we havn't received anything on it for the
%% last 60 secs. If ticked == tick we havn't received anything
%% on the connection the last 60 secs.
%% The detection time interval is thus, by default, 45s < DT < 75s
%% A HIDDEN node is always (if not a pending write) ticked if
%% we haven't read anything as a hidden node only ticks when it receives
%% a TICK !!
Hope this helps a bit.