Timer tasks?

Pintou uma daquelas tarefinhas de corno pra fazer aqui… daquelas que a gente se arrepende por ter escolhido ser programador :smiley:

Seguinte: eu tenho que pedir pra um webserver (extranet) de x em x segundos, pegar um XML de retorno, parsear o dito e jogar um objetão contendo todos os dados numa fila JMS.

Parsear o XML ja esta bem resolvido (I <coracaozinho> Digester), e postar na fila de mensagens idem. O problema aqui eh mesmo fazer a conexao HTTP e pegar o XML de tanto em tanto tempo. Entao, la vai:

Qual a maneira mais segura, robusta, testavel, elegante, etc, etc, etc, de se montar um Timer, numa aplicacao J2EE 1.3, sem depender do appserver?

cv:

Por que não experimenta usar as classes java.util.Timer e java.util.TimeTask? Dê uma olhada aqui e aqui.

Grato,

[quote=“cv”]
Qual a maneira mais segura, robusta, testavel, elegante, etc, etc, etc, de se montar um Timer, numa aplicacao J2EE 1.3, sem depender do appserver?[/quote]

hahahaha
Vc não quer 1 doce? A mais facil é comprar uma solução de scheduling como o quartz. Caso contrario vc ta ferrado…

Bom, de forma simples e que atenda suas necessidades:

-Stateless Session Bean que vai ser a fachada pro teu sistema de timer.
-Entity Bean para representar cada TimerTask.
-Serviço que cria 1 background thread e fica fazendo pooling por Tasks expiradas.

Teu SB permite registrar 1 EJB que implemente a interface TimerTask para ser notificado a cada X minutos.

Alem disso ele tem uma função de pooling que verifica por todos TimerTask expirados, invoca eles e reagenda, se necessario.

O resto dos métodos são arroz com feijão e não vou me explicar.

Teu EB simplesmente guarda uma referencia pro EJB a ser invocado, os parametros de agendamento e a próxima hora de execução.

Usando Entity Beans vc resolve o problema da persistencia dos timers, mas a performance da operação de pooling e retirada da sua fila pode não ficar ótima.

Vc pode resolver isso usando BMP e implementando algum tipo de heap para os tasks. Mas isso pode dar bastante trabalho ate.

Isso supoe que voce tenha todos nodes do teu appserver com sincronização razoavel de relogio. Oque deveria ser muito comum.

Devem existir alguns problemas que eu não tou prevendo aqui, mas como não são meus…

Rafael, valeu pelos links, estou dando uma olhada agora.

Louds, isso nao ficou meio over-engineered nao? Eu tenho que rodar soh uma tarefa (que faz o download do XML, parseia e posta na fila JMS), e os unicos problemas que eu posso ter sao quedas de conexao com o servidor do XML ou atraso na entrega do XML. Em ambos os casos, eu simplesmente falho a task, deixo logado o warning, e a proxima task que rodar fica encarregada de baixar o que faltou. Nao sei se pra isso eu preciso de Entity Beans e tudo mais, ja que com certeza eu nao vou rodar isso de forma distribuida (pra que ter um cluster de 5 maquinas baixando o mesmo arquivo e postando os mesmos dados na JMS? :))

[quote=“cv”]Rafael, valeu pelos links, estou dando uma olhada agora.

Louds, isso nao ficou meio over-engineered nao?
[/quote]
Eu acho que não, vc nã quer 1 serviço de timer robusto? Ou seja, sobreviva a falhas no AS ou serviço de timer.

A idéia de usar Entity Bean era para facilitar a persistencia de forma a ser compativel com j2ee. Senão vc vai ter que escrever 1 Connector que te prove a fonte externa de dados.

Se voce estiver contando que somente erros dentro da tua operação vão ocorrer, ai tudo bem, porem podem acontecer erros externos. Se alguem puxar o cabo do teu AS, tudo bem esse timer ir pro vinagre? Se tiver ok, não precisa de Entity Bean.

Como vc falou que precisa de algo robusto, seguro, etc, etc, etc. Pensei nisso logo de cara.

Uma solução beem mais simples seria instalar 1 serviço no teu AS que gerenciaria em memoria a fila de timers em um background thread.
Se vc precisar de um implementação disso eu fiz a quase 2 anos e ta bem testada, vc provavelmente não vai precisar modificar muita coisa. Só vai ter que integrar ela com teu AS hehehe…

[quote=“cv”]
(pra que ter um cluster de 5 maquinas baixando o mesmo arquivo e postando os mesmos dados na JMS? :))[/quote]

Acho que voce não entendeu o ponto aqui. A ideia não é ter 5 máquinas baixando o mesmo arquivo, mas qualquer podendo baixar.

Entendi o que vc quis dizer, louds… mas o “web service” que eu tou acessando (só não é um webservice pq nao usa soap nem nada, é só um GET que recebe alguns parâmetros na URL e recebe um XML) é bem legalzinho… eu posso passar dois params na URL dele que me dão a maior comodidade do mundo (e eu não sabia disso quando postei a 1a msg):

?registro=1000&qtdeRegistros=100

Ou seja, eu soh preciso ver em qual registro eu parei no banco de dados (bye bye fila JMS, voce foi substituida por uma tabela no Oracle…) e continuar dali :slight_smile: