El problema de fondo es que por defecto el lanzamiento de informes desde el cliente espera a que la ejecución del informe termine y presentarlo en pantalla. Durante este tiempo el cliente queda "frito", y si llegamos al fatídico Timeout nos quedamos en ascuas. Lo cierto es que el servidor continua trabajando y elabora el informe.... pero no tenemos forma de recuperarlo....¡diantre!
Hay varias estrategias para resolver este problema. Una de ellas consiste en lanzar un nuevo servidor de OpenERP contra la base de datos original en un equipo potente y ocioso y lanzar el informe contra ese servidor. A mí me ha funcionado razonablemente bien ya que en estas condiciones es más difícil llegar a ver que el período de gracia "caduca".
Otra opción consiste en ampliar el tiempo de espera del cliente lo suficiente (linea 69 del fichero bin/modules/action/main.py), reemplazando los 200 intentos/segundos por un número más alto.
Pero hay otra solución que es la que voy a exponer aquí. Consiste en hacer uso del XML-RPC y lanzar el informe y su recuperación desde un programa externo para almacenarlo en un fichero de nuestro sistema de archivos.
Pongo aquí código de ejemplo y paso a comentarlo a continuación:
import xmlrpclib
import base64
sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/report')
id_informe = sock.report('terp', 3, 'password', 'module.report.name', [ids])
resultado = {'state':False}
while not resultado['state']:
resultado = sock.report_get('terp', 3, 'password', id_informe)
cadena_pdf = resultado['result']
cadena_pdf = base64.decodestring(cadena_pdf)
fichero_pdf = open('/tmp/fichero.pdf','w')
fichero_pdf.write(cadena_pdf)
fichero_pdf.close()
Las lineas fundamentales son donde se lanza la ejecución del informe (sock.report) donde terp es la base de datos, 3 es el id del usuario admin (podría ser otro usuario), password su contraseña, module.report.name es el nombre interno del informe e ids son los identificadores de los registros para los que lanzar el informe. Así por ejemplo, si fuesemos a lanzar como informe la factura con id 1, esta línea sería:
id_informe = sock.report('terp', 3, 'admin', 'account.invoice', [1])
A continuación se inicia un bucle que comprueba si la variable state devuelta por el método report_get es verdadera. Mientras el informe se está calculando, el valor de dicha variable es False. Podríamos incorporar una línea haciendo que el programa espere 1 o más segundos antes de volver a lanzar la petición.
Al final el informe se escribe en el fichero /tmp/fichero.pdf desde donde podremos recuperarlo.
0 comentarios:
Publicar un comentario en la entrada