5

I've written a python function that calls a tool (Import CAD to GDB) in a loop. When I run it I have seen that it hangs sometimes, and I have to force the script to quit. I am wondering if there is a way to kill the tool execution after a certain amount of time, and move on to the next item in the loop? Here is what I have so far - I've included a timer but it still hangs:

import os, arcpy, arcgisscripting, time, sys
gp = arcgisscripting.create()

def ConvertCADtoGDB(srch_dir,gdb_dir,timeout):
    for dirpath, dirnames, files in os.walk(srch_dir):
        for file in files:
            f_name, f_ext = os.path.splitext(file)
            in_dgn = dirpath+'\\'+file
            out_gdb = gdb_dir+'\\'+f_name+'.gdb'
            if f_ext == '.dgn':
                if not os.path.isdir(out_gdb):
                    start = time.time()
                    end = start + timeout
                    while time.time() < end:
                        print 'creating',out_gdb
                        gp.ImportCAD_conversion(in_dgn,out_gdb,'','Explode_Complex')
  • The time.time() < end will calculate the time when it starts that while loop, but not continue checking it while ImportCAD_conversion is running. – Erica Jul 10 '14 at 15:22
  • I know i have discovered this when running it. So I was thinking if there was a way to stop the tool execution.. the question is how do i stop it once it starts and hangs? – kflaw Jul 10 '14 at 16:28
  • I don't think it's exactly hanging -- the import process is still running, but taking a very long time and not providing any visible feedback that it hasn't crashed. – Erica Jul 10 '14 at 16:59
  • I've checked the file that it hangs on, very small uncomplicated file, so shouldn't take long at all. When I run it through the CADtoGeodatabase tool goes very quick. I am using ImportCADtoGeodatabase which is a deprecated tool but it gives the option to explode complex features which I need to do. – kflaw Jul 10 '14 at 17:11
3

You could use the multiprocessing module. The code below creates a separate process to run the ImportCAD_conversion tool in, waits for it to complete and terminates it if the timeout is exceeded.

Note the use of the if __name__ == '__main__': syntax, which is required on Windows.

import os, arcpy, arcgisscripting, time, sys
gp = arcgisscripting.create()

def ConvertCADtoGDB(in_dgn,out_gdb):
    gp.ImportCAD_conversion(in_dgn,out_gdb,'','Explode_Complex')
    if not arcpy.Exists(out_gdb):raise RuntimeError('%s does not exist'%out_gdb)

def main(srch_dir,gdb_dir,timeout):
    for dirpath, dirnames, files in os.walk(srch_dir):
        for f in files:
            f_name, f_ext = os.path.splitext(f)
            in_dgn = os.path.join(dirpath,f)
            out_gdb = os.path.join(gdb_dir,f_name+'.gdb')
            if f_ext == '.dgn':
                if not os.path.isdir(out_gdb):
                    print 'creating',out_gdb
                    #####################################################
                    # Create a separate process to run the tool in
                    p = multiprocessing.Process(target=ConvertCADtoGDB,
                                                args=(in_dgn,out_gdb))
                    p.start()
                    p.join(timeout)   # Wait for process to complete
                    if p.is_alive():  # Terminate process if it is 
                        p.terminate() # still running after the timeout
                        print('Conversion of %s terminated'%in_dgn)
                    else:
                        print('Conversion of %s successful'%in_dgn)
                    #####################################################

if __name__ == '__main__':
    srch_dir=r'C:\Temp\dgns'
    gdb_dir=r'C:\Temp\gdbs'
    timeout=5 #Seconds
    main(srch_dir,gdb_dir,timeout)
  • Now I have been running this in my script, but I am noticing that everything is terminating. I have set a time limit of 30 seconds and I have tested on some of the drawings outside of the script, they were sucessfully converted within that time. Wonder what is wrong? – kflaw Jul 21 '14 at 18:09
  • update: it does seem to work now, though interestingly only after I upped the timeout to 60 seconds. I wonder why it would take longer when run from the script, vs running the tool in arcmap? I also wonder if I have to wait the full 60 seconds, if the tool can complete in a shorter amount of time? – kflaw Jul 21 '14 at 18:23
  • @kflaw If the tool completes in less than the timeout, you don't have to wait the full 60 sec (or whatever the timeout is). Running the tool in a separate process will take longer than in ArcMap or in the same python process as the new python process has to load arcpy again every time. – user2856 Jul 21 '14 at 21:05
  • I see that makes sense. So if it takes less than the timeout it will move to next item before the timeout finishes? another thing is that I can't get the files to write out, though it is printing that they are. I thought maybe because I need a return statement in the ConvertCADtoGDB function but that wasn't it. – kflaw Jul 21 '14 at 21:09
  • @kflaw correct. Also the tool help says the output gdb is temporary so it maybe getting deleted when the subprocess completes – user2856 Jul 21 '14 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.