Muchas veces nos resultará útil lanzar algún tipo de proceso en background con tal de no bloquear el navegador. Por ejemplo, procesos que impliquen actualización o creación de muchos objetos
Para ello, podemos utilizar los siguientes fragmentos de código para hacerlo
1-Por un lado, crearemos un adaptador o incluiremos este código para gestionar la llamada a procesos externos
class CommandLauncher(threading.Thread):
def __init__(self, command,params=[]):
threading.Thread.__init__(self)
self.command = command
self.result = None
if len(params):
self.command = ‘%s %s’%(self.command,’ ‘.join(params))
def run(self):
command_in, command_out = os.popen4(self.command, bufsize=0)
self.result = command_out.read()
command_in.close()
command_out.close()
def abort(self):
import os, sys
if sys.platform == ‘win32’:
os.abort()
my_pid = str(os.getpid())
command_in, command_out = os.popen4(«/bin/ps -Af | /bin/grep %s | /bin/grep -v grep» % my_pid)
result = str(command_out.read())
for line in result.split(‘n’):
while line.find(‘ ‘) > -1:
line = line.replace(‘ ‘,’ ‘)
parts = line.split(‘ ‘)
if len(parts)>1 and parts[2] == my_pid:
# A child process to be killed
os.kill(long(parts[1]), 9)
os.waitpid(long(parts[1]), 0)
command_in.close()
command_out.close()
2- Dentro de nuestro código, haríamos una llamada de este tipo:
def miProcesoEnBatch(self,portal):
try:
command = ‘/usr/local/kmkey/zope/bin/zopectl run miscript.py’
thread = CommandLauncher(command)
thread.start()
except:
llamar a algun proceso que reporte el error(log propio o envío de mail)
raise «Export error», thread.result
return
Con esto , conseguimos hacer una llamada a un proceso externo desde nuestro navegador (en el proceso externo deberemos montar algún sistema para enviar aviso de que ha finalizado o ha dado error)
Un ejemplo de proceso externo sería este:
if __name__ == «__main__»:
try:
import_products()
#low priority
os.nice(5)
app = makerequest(app)
site = app.unrestrictedTraverse(‘mi_sitio_kmkey’)
user = site.acl_users.getUser(‘manager’).__of__(site.acl_users)
newSecurityManager({}, user)
app = makerequest(app)
site = app.unrestrictedTraverse(‘mi_sitio_kmkey’)
#todo mi proceso aquí# (con commits parciales)
get_transaction().commit()
except:
(exc, msg, tb) = sys.exc_info()
out = StringIO()
traceback.print_exception(exc,msg,tb,None,out)
out.seek(0)
body = str(out.read())
#montar algún sistema para reportar errores, ya
#sea con log propio, envió de mail o logger de zope
escribelog(body)
enviarMail(site,subject=»Traceback Error a importació de matrícules»,body=body)
logger.error(«Importar matricules Traceback:n%s», body)