• Nenhum resultado encontrado

Para a execução da composição e análise da eĄcácia das estruturas implementadas, vamos propor um conjunto de casos de teste para a composição criada na seção anterior. Os casos de testes precisam contemplar: o atraso na resposta de serviços, a troca de um serviço errôneo por outro serviço equivalente, e a troca de uma subcomposição em que ocorreu uma

5.3. Casos de Teste 93

falha por uma outra subcomposição que realize a mesma tarefa. Utilizaremos, para todos os casos, TEMPORESPOSTA (3,3).

Para simulação do atraso na resposta de um serviço, criamos um arquivo, chamado TempoEspera.txt. O texto do arquivo contém os seguintes dados:

getCidadeByName 2 getCidadeByCoord 0 s1getTemperatura 4 s2getIuv 1 ... s6getIuv 4

O intuito da criação deste arquivo é deĄnir um determinado tempo de atraso na resposta das operações chamadas pela composição. Para cada operação, temos um determinado valor de atraso. Além disso, queremos que, em tempo de execução, esses valores possam ser alterados, para simular casos onde o Retry é benéĄco à composição. Sendo assim, no código de todas as operações dos serviços, colocamos um código que abre o arquivo, coleta a informação do tempo de atraso, e chama a função Thread.sleep, que simula um tempo de espera dentro do código, cujo trecho é mostrado abaixo:

FileReader arq = new FileReader(".../TempoEspera.txt")); BufferedReader arqTempo = new BufferedReader(arq);

String tempo = arqTempo.readLine(); ...

Thread.sleep(x*1000);

Dessa forma, podemos agora mostrar os casos de testes para testarmos a eĄciência da máquina de redução:

• Caso 1: Ű Neste primeiro caso, vamos ver a utilidade e eĄciência do Retry. Propomos a execução normal da composição, exceto na operação buscarCidadeNome. Num primeiro momento, daremos um atraso para que o mesmo não execute nas primeiras tentativas. Logo após, faremos com que o mesmo execute normalmente, fazendo assim com que a ope- ração alternativa buscarCidadeCoord seja descartada. Todas as outras execuções devem ocorrer de forma correta, ou seja, na pilha de subcomposições, as chamadas às operações s1Temperatura e s2IUV devem ser executadas com sucesso, acarretando na exclusão das outras subcomposições equivalentes. Da mesma forma, a operação mostrarFigura deve ocorrer com sucesso, tendo como consequência a exclusão da operação mostrarTexto. • Caso 2: Ű Pretendemos ver a utilidade e eĄciência do Rebinding. Vamos simular uma

onde haverá a substituição do serviço referente a esta operação pelo serviço CidadeCoord, que possui a operação buscarCidadeCoord.

• Caso 3: Ű Neste terceiro caso, vamos ver a utilidade, eĄciência e níveis de inconsistência do Restructure. Este tem a semântica semelhante ao Rebinding, mas é aplicado a com- posições, e não a serviços individuais. Simularemos duas situações: uma onde há um erro no início da execução da subcomposição alternativa e outro onde há um erro no Ąnal da subcomposição, quando determinados processamentos já tiverem sido realizados. Como não há a possibilidade de desfazer processamentos, veremos como o resultado Ąnal da execução da composição é afetado.

• Caso 4: Ű Neste último caso teste, vamos propor a utilização de todas as estruturas de uma só vez. Na primeira pilha de chamada, simularemos o estouro de tentativas da operação buscarCidadeNome. Na pilha de subcomposições, simularemos erros em duas subcomposições alternativas, uma no início da subcomposição e outra no Ąnal da sub- composição; por Ąm, na última pilha de chamadas, daremos um atraso na execução da operação mostrarFigura, que executará normalmente na segunda tentativa.

5.4 Resultados obtidos

Após termos dado uma composição de serviços e proposto um conjunto de casos de testes para sua execução, vamos veriĄcar os resultados obtidos e analisar o quanto as estruturas criadas podem ser úteis no tratamento de falhas ocorridas nas composições. Inserimos também códigos para o cálculo do tempo gasto na execução de cada uma das estruturas.

5.4.1

Caso 1

No primeiro caso, propomos uma falha na primeira tentativa de execução da operação buscarCidadeNome, que pertence ao serviço Servico1. Atribuiremos um atraso na resposta desse serviço e vamos supor que, nessa chamada, devido a uma sobrecarga momentânea, o ser- viço respondesse em 8 segundos. Sendo este tempo muito maior do que o tempo de espera, a primeira tentativa não terá sucesso e a operação não será considerada. Já na segunda tentativa, não colocamos nenhum atraso na comunicação com o serviço, simulando que o mesmo não está mais sobrecarregado. Alguns dos trechos do arquivo de saída são os seguintes:

Início da composição em 19:01:22 ...

Temporizador disparado em 19:01:22. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 19:01:25. 2a tentativa...

Serviço "buscarCidadeNome"(33172286) executado com sucesso em 19:01:26. ...

5.4. Resultados obtidos 95

Fim da composição em 19:01:33

Na primeira tentativa, foi detectado um atraso no tempo de resposta do serviço, sendo esta tentativa abortada. Já na segunda tentativa, vemos que o serviço respondeu à solicitação em cerca de 1 segundo apenas. Em outras palavras, com o uso do Retry, tivemos um gasto de 4 segundos na resposta da operação buscarCidadeNome (3 segundos na primeira tentativa que foi abortada, e cerca de 1 segundo nesta nova tentativa). Se executássemos a composição sem o uso do Retry, teríamos um gasto de cerca de 8 segundos na execução da operação buscaCidadeNome. Sendo assim, tivemos um ganho de 4 segundos, mesmo com duas chamadas, na execução da operação buscarCidadeNome. Isso inĆui também no tempo total de execução da composição, que foi de 11 segundos (sem o uso do Retry, esse tempo iria ser de cerca de 15 segundos).

Ainda utilizando este primeiro caso, vamos supor atrasos que impeçam a execução tanto na primeira quanto na segunda execução, sendo estes atrasos de 4 segundos cada. Obtemos o seguinte resultado no arquivo texto:

Início da composição em 20:10:37 ...

Temporizador disparado em 20:10:38. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 20:10:41. 2a tentativa... Tempo esgotado na 2a tentativa.

Temporizador disparado em 20:10:44. 3a tentativa...

Serviço "buscarCidadeNome"(33172286) executado com sucesso em 20:10:44. ...

Fim da composição em 20:10:50

Consideremos o tempo a partir da primeira tentativa até o momento da execução da operação buscarCidadeNome. De acordo com o arquivo de saída, esse tempo foi de 6 segundos. Entretanto, especiĄcamos que o atraso na primeira tentativa de execução do serviço seria de 4 segundos. Sem o uso do Retry, teríamos conseguido executar o serviço em um espaço de tempo menor que o espaço usando o Retry. Dessa forma, concluímos que, em determinados casos, o uso do Retry pode trazer benefícios à eĄciência da composição, enquanto que, em outros casos, o uso pode tornar a composição um pouco mais lenta.

5.4.2

Caso 2

Vamos considerar agora o estudo de caso 2, onde queremos ver a utilidade do uso do Rebinding. Vamos propor falhas na comunicação com a operação mostrarFigura, que pertence à pilha de chamadas que está localizada no Ąnal da composição principal. Faremos com que haja o estouro nas tentativas de execução desta operação. Como ela encontra-se dentro de uma pilha de chamadas, haverá a substituição desta operação por um outra (caso a pilha não seja vazia).

Ao realizar a execução da composição com a inserção desta falham, mostramos abaixo alguns trechos especiĄcados pelo arquivo de saída:

Início da composição em 20:33:15 ...

Temporizador disparado em 20:33:26. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 20:33:29. 2a tentativa... Tempo esgotado na 2a tentativa.

Temporizador disparado em 20:33:32. 3a tentativa... Tempo esgotado na 3a tentativa.

Não foi possível executar o serviço "mostrarFigura". Procurando soluções Removendo o vertice Chamada de Serviço - 1397168

Temporizador disparado em 20:33:33. 1a tentativa...

Serviço "mostrarTexto" (33172286) executado com sucesso em 20:33:35. Fim da composição em 20:33:35

Temos o tempo onde foi iniciada a execução da composição (desconsideramos os tempos das outras execuções, as quais foram realizadas todas com sucesso). Logo após, chegamos às tentativas de executar a operação buscarFigura. Após três tentativas, não obtivemos sucesso e, dessa forma, precisamos descartar esse serviço, em virtude da demora na sua execução. A máquina procura alternativas para continuar a execução. Como este serviço faz parte de uma pilha de chamadas, a máquina veriĄca se a pilha esta vazia. Se ainda existem serviços a serem utilizados, ela retira o serviço do topo da pilha e começa a execução deste (no caso, o serviço RespostaUsuarioTexto, cuja operação relacionada é mostrarTexto). A execução desta opera- ção ocorre logo na primeira tentativa. Como a pilha o último vértice da composição, chegamos ao Ąnal da mesma. O tempo gasto na execução desta pilha, com o uso do Rebinding, foi de 9 segundos. Supondo que a operação buscarFigura demorasse um bom tempo para executar, o Rebinding serviu para dar alternativas à execução da composição, uma vez que, sem seu uso, teríamos que esperar um tempo indeterminado para a Ąnalização da execução por causa de um atraso pontual na composição.

5.4.3

Caso 3

Vamos agora analisar o estudo de caso 3. Mostraremos agora a utilidade e eĄciência do uso do Restructure. Temos o uso deste mecanismo nos serviços que retornam informações temporais sobre as cidades. Criamos uma pilha de subcomposições que contém quatro subcom- posições (uma composição principal e três subcomposições alternativas), sendo que cada uma delas possui o paralelismo de dois serviços, visto que nenhum deles tem a capacidade de enviar toda a informação de uma só vez. Utilizaremos dois cenários nesse caso: no primeiro, a falha

5.4. Resultados obtidos 97

ocorre logo no início da execução da subcomposição, onde nenhum processamento foi realizado, tendo a exclusão de vários vértices; já no segundo simularemos a falha no Ąnal da subcomposição, onde determinados processamentos foram realizados.

No primeiro cenário, vamos simular um erro na execução da operação s1Temperatura. Vejamos trechos importantes do arquivo de saída:

Início da composição em 17:07:26 ...

Temporizador disparado em 17:07:37. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 17:07:41. 2a tentativa... Tempo esgotado na 2a tentativa.

Temporizador disparado em 17:07:46. 3a tentativa... Tempo esgotado na 3a tentativa.

Não foi possível executar o serviço "s1Temperatura". Procurando soluções Removendo o vertice Chamada de Serviço - 9992755

Removendo o vertice Saida de Serviço - 8304354 Removendo o vertice Sync - Saida - 18403721 Removendo o vertice Chamada de Serviço - 6586390 Removendo o vertice Saida de Serviço - 1397168 ...

Temporizador disparado em 17:07:51. 1a tentativa...

Serviço "s3Temperatura" (14397555) executado com sucesso em 17:07:52. ...

Temporizador disparado em 17:07:52. 1a tentativa...

Serviço "s4IUV" (10618321) executado com sucesso em 17:07:53. ...

Fim da composição em 17:07:54

Após encontrar a referência da cidade desejada através da operação buscarCidadeNome, encontramos a pilha de subcomposições. A primeira subcomposição disponível contém um para- lelismo entre as operações s1Temperatura e s2IUV. Tentamos executar a s1Temperatura antes que s2IUV seja executado. Depois de três tentativas, vemos que não obtivemos sucesso na co- nexão com este serviço. Isso acarreta na exclusão de toda a subcomposição, sendo excluídos 5 vértices. Como nenhum processamento foi realizado, o ambiente de variáveis continua o mesmo de antes da execução da subcomposição. Posteriormente, retiramos outra composição para a execução. Obtivemos sucesso em ambos os serviços que buscam a informação para o usuário. Vemos que a execução da composição ocorreu em 28 segundos.

antes da detecção da ocorrência da falha, vamos supor que a operação s2IUV tenha sido exe- cutada e tenha alterado o ambiente de variáveis, inserindo a variável iuv no ambiente. Após a execução, temos as seguintes informações:

Início da composição em 17:35:18 ...

Temporizador disparado em 17:35:27. 1a tentativa...

Serviço "s2IUV" (20955323) executado com sucesso em 17:35:28. ...

Temporizador disparado em 17:35:29. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 17:35:33. 2a tentativa... Tempo esgotado na 2a tentativa.

Temporizador disparado em 17:35:38. 3a tentativa... Tempo esgotado na 3a tentativa.

Não foi possível executar o serviço "s1Temperatura". Procurando soluções Removendo o vertice Chamada de Serviço - 6586390

Removendo o vertice Saida de Serviço - 1397168 Removendo o vertice Sync - Saida - 18403721 ...

Temporizador disparado em 17:35:42. 1a tentativa...

Serviço "s3Temperatura" (10272673) executado com sucesso em 17:35:43. ...

Temporizador disparado em 17:35:43. 1a tentativa...

Serviço "s4IUV" (2124186) executado com sucesso em 17:35:44. ...

Fim da composição em 17:35:45

Temos a mesma situação do cenário anterior, porém, com a execução da operação s2IUV ocorrendo antes da falha. Observamos que temos um número menor de remoções de vértices que o cenário anterior. Como houve a execução de uma operação da subcomposição antes da ocor- rência da falha, houve a criação de um variável no ambiente. Como falamos anteriormente em outras seções, a máquina de redução estendida não dá suporte à compensação de procedimentos realizados antes de falhas, ou seja, não há como remover a variável do ambiente. Entretanto, com a exclusão dos vértices e da subcomposição falha, outra subcomposição entra em execução (paralelismo entre as operações s3Temperatura e s4IUV). Quando a execução desta subcom- posição termina, a variável temperatura é inserida no ambiente. Em relação à variável iuv, esta já existe. Entretanto, ela é setada com o valor dado pela operação s4IUV. Nessa situação, vemos que não houve incosistências no resultado Ąnal de execução da composição, pois apenas a variável já havia sido criada, e foi apenas alterada.

5.4. Resultados obtidos 99

5.4.4

Caso 4

Por Ąm, no estudo de caso 4, propomos pelo menos uma falha em cada uma das três es- truturas presentes na composição principal. Na primeira subcomposição, vamos supor um atraso momentâneo na operação buscarCidadeNome, que é executada em outra tentativa. Já na pilha de subcomposições, vamos colocar atrasos nas operações s2IUV e s3Temperatura, para que as mesmas não consigam executar dentro do número de tentativas máximas. Da mesma forma, vamos colocar um atraso na operação mostrarFigura, para que a mesma não execute e seja substituída pela operação mostrarTexto. Após a execução com esses parâmetros, obtemos os seguintes resultados no arquivo texto (omitimos algumas partes pela extensão do arquivo):

Início da composição em 19:21:34 ...

Temporizador disparado em 19:21:34. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 19:21:37. 2a tentativa...

Serviço "buscarCidadeNome" (30967688) executado com sucesso em 19:21:37. ...

Temporizador disparado em 19:21:39. 1a tentativa...

Serviço "s1Temperatura" (10651400) executado com sucesso em 19:21:39. ...

ERROS NA PRIMEIRA E SEGUNDA SUBCOMPOSIÇÃO ... Temporizador disparado em 19:21:58. 1a tentativa...

Serviço "s5Temperatura" (14500383) executado com sucesso em 19:21:59. Temporizador disparado em 19:22:00. 1a tentativa...

Serviço "s6IUV" (18328955) executado com sucesso em 19:22:00. ...

Temporizador disparado em 19:22:01. 1a tentativa... Tempo esgotado na 1a tentativa.

Temporizador disparado em 19:22:04. 2a tentativa... Tempo esgotado na 2a tentativa.

Temporizador disparado em 19:22:07. 3a tentativa... Tempo esgotado na 3a tentativa.

Não foi possível executar o serviço "mostrarFigura". Procurando soluções Temporizador disparado em 19:22:10. 1a tentativa...

Serviço "mostrarTexto" (21247461) executado com sucesso em 19:22:10. ...

Fim da composição em 19:22:10

O tempo total de execução da composição foi de 26 segundos. Na primeira pilha de chamadas, com uma tentativa falha executada pela operação buscarCidadeNome, e com sucesso

na segunda tentativa, foram gastos um pouco mais de 3 segundos (a segunda chamada teve a resposta quase que instantânea). Já na pilha de subcomposições dos serviços de informações das cidades, com erros tanto na primeira subcomposição (ocorrendo no Ąm da execução da sub- composição) quanto na segunda subcomposição (ocorrendo no início da subcomposição) foram gastos 21 segundos. Já na pilha de chamadas que mostram o resultado ao usuário, com falhas na operação mostrarFigura, tivemos um gasto de 9 segundos.