Invoco a todos los maestro Sayayines, Jedys, Shaolin, etc. del modulo FI, tengo un problema que hoy esta de cumpleaños ya tiene 3 años y va creciendo fuerte y sano .
Bueno después de esa intro algo diferente a lo que vinimos, el asunto es que al ejecutar esta transacción en ciertas sociedades y para un periodo determinado, el proceso concluye por timeout, y no permite terminar su ejecución, se que me podrán decir como solución que aumente el tiempo al timeout pero en esta empresa eso no es factible por reglas internas de la empresa los procesos no deben demorar mas allá de un tiempo razonable. He investigado en Internet y es muy poco lo que he encontrado.
Esta transacción lo que permite es ejecutar un proceso que calcula las posiciones de liquidez de documentos FI (específicamente cuentas bancarias), dentro del programa existe una función que ejecuta una búsqueda recursiva que puede tener hasta un máximo de 9999 iteraciones (una verdadera locura) pero según me indican acá no puedo tampoco reducir ese numero, en resumen no tengo muchas posibilidades así que he optado como ultimo recurso ver si alguien acá le abra tocado alguna vez pasar por esto.
Hemos aplicado un monton de notas la ultima creo fue la 798996 que corresponde a una función de reducción de los registros que procesa el programa, se genera una función llamada FLQ_PAIR_REST_TWAERED_1CL y esto es lo que explica que hace:
* Actualizado por SAP en la nota 798996 de 12.Julio 2007
* (Nueva subrutina PARTNERS con recursión para evitar 'demasiado' redu.)
*
*
* Principio: Un racimo de líneas despejadas se divide en parejas
* (Mismo monto de transacción, signo opuesto) y resto.
* Dependiendo de lo que se mantenga (en la tabla U_T_KEEP), algunos pares
* O el resto se quita del clúster de borrado. Así se consigue
* Más pequeño y con bastante frecuencia esto significa una mejor evaluación
*
* Esta función de salida ha demostrado ser útil en una serie de casos, y
* Inútil en otros, donde la calidad de los datos originales no era
* Apropiado. Usted puede usarlo a su propio riesgo, y no hay garantía
* Va a entregar la simplificación deseada y la mejora.
El tema es que algo reduce pero no es suficiente!! y este es solo un ejemplo son varias notas que se han ido aplicando a lo largo de los años.
Ese es mi ultimo recurso que voy a proponer en caso de no encontrar otra solución, el problema de eso es que son muchas las sociedades involucradas y distintos los parámetros de ejecución, de todas maneras igual lo tengo como opción. Salu2
intenta reducir la ejecución, separando por algún parámetro
sociedad, centro, año o acotando fechas,
si hace hasta 9999 iteraciones por un documento FI (según entendí) no me parece razonable ejecutarlo todo, es obvio que hará time_out, la otra opción es de fondo como dice @Salco pero igual estarás gastando recursos del servidor exageradamente por un buen tiempo al no separar la ejecución.
Independiente de la Tx, Cuando tengo ese problemas de time out, por temas de recursos del servidor, y si el proceso toma mucho pero mucho tiempo, considero diseñar un programa “Padre” Z( que maneje el concepto de ejecución o programación paralela y el programa “Hijo” vendría a ser tu tx FLQAC ). Ejecutas en Fondo este programa “Padre” y genera hilos ( JOB’s del programa “Hijo” ) ( El nro de hilos lo gestionas tú ). Si consideras aún más distribuir por grupo de servidores los hilos para gestionar la carga.
Hola @David147 suena interesante tu idea pero no logro entender de que me sirve diseñar un Z que se deba ejecutar en fondo para a su vez este ejecute también en fondo instancias del programa hijo, en este punto me perdí, que gano al hacerlo así, considerando que el programa hijo igual se ejecuta en fondo con éxito, el problema radica en que al ejecutarlo en modo normal se cae y si lo dejo ejecutando en fondo el resultado es un ALV que no puedo recuperar del Job.
Salu2
La idea es para procesos que demoran más de 1 dia, disminuir el tiempo, con esta técnica en un par de horas, por el echo que están corriendo procesos paralelos ( hilos ), termina el proceso en mucho menos tiempo.
En tu caso, si el resultado es un reporte y si ejecutas en fondo, una opción es evaluar si el ALV se encuentra en el spool cuando ejecuta en fondo y si te sirve ó en su defecto generar un archivo plano en el servidor con la info del ALV por cada programa hijo.
Hola @David147 por aca nuevamente he investigado lo de la programación en paralelo y ya he realizado pruebas y en verdad es de gran ayuda.
Por lo que he podido comprender este programa padre cumple la función de ejecutar como procesos independientes las distintas partes de un mismo problema. También he visto que para ejecutar funciones la sintaxis es algo similar a esto:
call function nombre_funcion
starting new task 'FUNC2'
destination 'NONE'
performing nombre_procedimiento on end of task
exporting
parametro = parámetro_retorno.
Ahora bien he realizado algunos ejemplos con cosas simples consultar dos materiales simultaneos en procesos separados y todo bien, sin embargo aun no logro asimilar como le hago con mi TRX estándar, tendría que realizar una división de toda la lógica que realiza esta TRX e ir ejecutando proceso a proceso hasta completar toda esta lógica (algo bastante complicado dado que cada proceso dentro de la TRX devuelve resultados que sirven para ejecutar las siguientes partes del código) o mas bien la idea seria ejecutar como una tarea independiente la TRX estándar.
No se si me supe explicar pero es algo complejo hablar en estos términos.
Otra duda que tengo es respecto al ciclo de vida de este tipo de ejecución, es decir si ejecuto varias tareas en paralelo no es posible que entre cada tarea exista información de dependencia que sirva para ejecutar una siguiente tarea, ¿se comprende? ni yo entiendo bien lo que estoy preguntando?
Mas específicamente es posible dentro de la programación en paralelo que pueda definir una secuencia de ejecución secuencial para ciertas tareas? se que suena inconsistente pero bueno no tengo de otra
y no te serviría la ejecución en paralelo para cada sociedad? Ejecutar en fondo el proceso en tantos hilos como sociedades tengas o incluso sociedades-otros parámetros de selección…
Efectivamente, es una opción tu propuesta, la opción que brindo es que los hilos sean JOB’s ( ejecución en fondo ) del Programa Hijo, ejecutados por una variante especifica que se defina en el programa Padre ( Este programa también se ejecuta en Fondo ).
Como utilizo variantes de la tx para cada hilo, esta garantiza el ciclo completo de la tx. ( como menciono @Salco por sociedad, Centro, rango de fecha, por uno de los criterios del parámetro de selección tienes que realizar tu quiebre para los hilos ).
Esto se da solo si tu proceso consta de más de 2 transacciones y tienes que ver la secuencia de ejecución ( FIFO ), si tu proceso( Programa Padre) solo es una tx(Programa Hijo) esto no se da.
Efectivamente, si sabez cuando termino un JOB( Programa Hijo), puedes lanzar otro JOB hijo secuencial en el mismo proceso en Fondo del JOB ( Programa Padre ).
De hecho lo que pretendo hacer es separar la cantidad de registros iniciales que me devuelve la TRX en bloques de 100 registros y por cada 100 voy a ejecutar una instancia de la tarea independiente.
@David147 mira he escrito un programa que en teoría debe simular lo que intento hacer:
REPORT ZRL_TEST_15.
DATA: BEGIN OF it_result OCCURS 0,
output TYPE I,
END OF it_result,
contador TYPE i,
_lines TYPE i,
BEGIN OF _it_count OCCURS 0,
count(2) TYPE n,
END OF _it_count.
REFRESH it_result.
CLEAR contador.
DO 5 TIMES.
_it_count-count = _it_count-count + 1.
APPEND _it_count.
ENDDO.
DESCRIBE TABLE _it_count LINES _lines.
LOOP AT _it_count.
CALL FUNCTION 'ZRFC' STARTING NEW TASK _it_count-count
PERFORMING return_zrfc ON END OF TASK
EXPORTING
i_input = _it_count-count.
ENDLOOP.
WAIT UNTIL contador = _lines.
LOOP AT it_result.
WRITE:/ it_result-output.
ENDLOOP.
FORM return_zrfc USING taskname.
RECEIVE RESULTS FROM FUNCTION 'ZRFC'
KEEPING TASK
IMPORTING
e_output = it_result-output.
APPEND it_result.
CLEAR it_result.
contador = contador + 1.
ENDFORM.
FUNCTION ZRFC.
*"----------------------------------------------------------------------
*"*"Interfase local
*" IMPORTING
*" VALUE(I_INPUT) TYPE I
*" EXPORTING
*" VALUE(E_OUTPUT) TYPE I
*"----------------------------------------------------------------------
CASE i_input.
WHEN 1.
CALL FUNCTION 'ENQUE_SLEEP'
EXPORTING
seconds = 5.
e_output = 5 * I_INPUT.
WHEN 2.
CALL FUNCTION 'ENQUE_SLEEP'
EXPORTING
seconds = 10.
e_output = 10 * I_INPUT.
WHEN 3.
CALL FUNCTION 'ENQUE_SLEEP'
EXPORTING
seconds = 15.
e_output = 15 * I_INPUT.
WHEN 4.
CALL FUNCTION 'ENQUE_SLEEP'
EXPORTING
seconds = 20.
e_output = 20 * I_INPUT.
WHEN 5.
CALL FUNCTION 'ENQUE_SLEEP'
EXPORTING
seconds = 25.
e_output = 25 * I_INPUT.
ENDCASE.
ENDFUNCTION.
La primera parte es el programa de control, después hice una f() RFC que de acuerdo al índice que recibe ejecuta la f() con diferente tiempo que es lo que me puede ocurrir en mi situación real, el tiempo de ejecución puede variar dependiendo de la variante que ejecute.
El problema es que el procedimiento que recibe las respuestas de las funciones se ejecuta inmediatamente y por ende
el resultado final para cada ejecución de la f() es cero, si en vez de eso mi función realiza solo este código e_output = i_output como los resultados se evalúan todos juntos funciona bien.
Existe alguna manera de que sea posible lanzar varias instancias de ejecución de mi f() pero que la recuperación de los resultados se haga en un solo procedimiento tal como lo tengo desarrollado en el ejemplo pero considerando que el tiempo de respuesta es variable en cada ejecución?
Muchas gracias
Ya encontré el problema la función ENQUE_SLEEP no me funciona correctamente reemplace mi función con lo siguiente:
data: cont type DECFLOAT34.
cont = i_input * 2000.
DO cont TIMES.
e_output = cont.
ENDDO.
Con esto ya me devuelve los resultados de cada ejecución correctamente.