Consulta DataSnap com Paralelismo XE7
Olá amigos
Ultimamente tenho realizado diversos testes de desempenho utilizando a tecnologia DATASNAP e servidores localizados no Brasil, Canadá e França.
Como resultado pude observar que o fator determinante de desempenho das aplicações está muito relacionado com a qualidade da conexão do usuário, a que chamamos de "última milha". Ou seja, quando o trecho de conexão "última milha" é bom a localização do servidor não impacta muito a experiência do usuário utilizando a aplicação.
Para resolver esse problema pensei em utilizar técnicas de paralelismo nas consultas Datasnap.
Paralelismo??? A ideia seria executar as consultas em paralelo conforme o trecho a seguir:
Eu sei que existem outras técnicas no Datasnap para "encapsular" varias consultas mas gostaria de experimentar o paralelismo.
Infelizmente não funcionou. Fiz até mesmo diversas modificações no código utilizando conexões individuais para cada consulta utilizando no servidor serviços individuais, com portas separadas, para cada conexão do cliente.
Faltou apenas desativar os filtros de segurança da conexão datasnap mas acredito que o problema não está relacionado com eles.
Então seguem as perguntas:
Existe algo na arquitetura do DataSnap que inviabilize esse tipo de paralelismo?
O que é necessário fazer para que o trecho de programa acima funcione?
abraço para todos
Ultimamente tenho realizado diversos testes de desempenho utilizando a tecnologia DATASNAP e servidores localizados no Brasil, Canadá e França.
Como resultado pude observar que o fator determinante de desempenho das aplicações está muito relacionado com a qualidade da conexão do usuário, a que chamamos de "última milha". Ou seja, quando o trecho de conexão "última milha" é bom a localização do servidor não impacta muito a experiência do usuário utilizando a aplicação.
Para resolver esse problema pensei em utilizar técnicas de paralelismo nas consultas Datasnap.
Paralelismo??? A ideia seria executar as consultas em paralelo conforme o trecho a seguir:
procedure TDM.Q1AfterScroll(DataSet: TDataSet);
var
task: array of ITask;
begin
SetLength(task,3);
task[0]:= TTask.Create (procedure ()
Begin
Q2.Close;
Q2.Params.ParamByName('P1').Value:=Q1F1.Value;
Q2.Params.ParamByName('P2').Value:=Q1F2.Value;
Q2.Open;
End);
task[0].Start;
task[1]:= TTask.Create (procedure ()
Begin
// Q3.RemoteServer:=DSPConnection3 Tentei utilizar outra conexão mas não funcionou;
Q3.Close;
Q3.Params.ParamByName('P1').Value:=Q1F1.Value;
Q3.Params.ParamByName('P2').Value:=Q2F2.Value;
Q3.Open;
End);
task[1].Start;
task[2]:= TTask.Create (procedure ()
Begin
// Q4.RemoteServer:=DSPConnection4 Tentei utilizar outra conexão mas não funcionou.
Q4.Close;
Q4.Params.ParamByName('P1').Value:=Q1F1.Value;
Q4.Params.ParamByName('P2').Value:=Q2F2.Value;
Q4.Open;
End);
task[2].Start;
TTask.WaitForAll(task);
end;
Eu sei que existem outras técnicas no Datasnap para "encapsular" varias consultas mas gostaria de experimentar o paralelismo.
Infelizmente não funcionou. Fiz até mesmo diversas modificações no código utilizando conexões individuais para cada consulta utilizando no servidor serviços individuais, com portas separadas, para cada conexão do cliente.
Faltou apenas desativar os filtros de segurança da conexão datasnap mas acredito que o problema não está relacionado com eles.
Então seguem as perguntas:
Existe algo na arquitetura do DataSnap que inviabilize esse tipo de paralelismo?
O que é necessário fazer para que o trecho de programa acima funcione?
abraço para todos
Marcelo Carvalho
Curtidas 0
Melhor post
Artur Barth
08/03/2016
Resolvi um problema de Threads utilizando TJvThread. Foi a unica forma que encontrei de fazer 27 threads rodarem ao mesmo tempo sem que nem uma delas trave.
Executando com uma rotina chamada ExecuteWithDialog(Self) todas rodam ao mesmo tempo. Vale ressaltar que não rodam isoladas, neste caso, deve-se criar uma Connection para cada Thread.
Att.
Artur Barth
Executando com uma rotina chamada ExecuteWithDialog(Self) todas rodam ao mesmo tempo. Vale ressaltar que não rodam isoladas, neste caso, deve-se criar uma Connection para cada Thread.
Att.
Artur Barth
GOSTEI 2
Mais Respostas
Marcelo Carvalho
24/10/2014
Apenas uma pequena correção no código enviado. Favor substituir no código as referências Q2F2 por Q1F2.
GOSTEI 0
Raylan Zibel
24/10/2014
Já tentou fazer as consultas dentro de Threads?
GOSTEI 0
Marcelo Carvalho
24/10/2014
Olá Grato pelo seu interesse
Sim.
A classe TTASK ( System.Threading.TTask) implementa Threading.
Sim.
A classe TTASK ( System.Threading.TTask) implementa Threading.
GOSTEI 0
Claudio Ferreira
24/10/2014
Que tipo de erro deu ? Ou se não deu erro o que aconteceu ?
GOSTEI 0
Marcelo Carvalho
24/10/2014
Grato pelo seu interesse.
O programa apresentou funcionamento anormal. Funcionou apresentando algumas informações e travou.
Modifiquei o programa e tentei utilizar três TFDconnection um para cada FDQuery. Também não funcionou.
Posteriormente, no servidor, recompilei três versões do módulo server com portas diferentes uma para cada TFDconnection. Também não funcionou.
Estava utilizando filtros de criptografia que eu não desativei. Acredito que isso não foi a causa do problema pois nas últimas tentativas utilizei três programas no server em portas diferentes.
Ainda acredito que esta técnica pode funcionar e reduzir o tempo de transferência das informações.
O programa apresentou funcionamento anormal. Funcionou apresentando algumas informações e travou.
Modifiquei o programa e tentei utilizar três TFDconnection um para cada FDQuery. Também não funcionou.
Posteriormente, no servidor, recompilei três versões do módulo server com portas diferentes uma para cada TFDconnection. Também não funcionou.
Estava utilizando filtros de criptografia que eu não desativei. Acredito que isso não foi a causa do problema pois nas últimas tentativas utilizei três programas no server em portas diferentes.
Ainda acredito que esta técnica pode funcionar e reduzir o tempo de transferência das informações.
GOSTEI 0
Claudio Ferreira
24/10/2014
Concordo contigo que essa técnica reduz o tempo de transferência, é realmente muito interessante utilizá-la. Fiz um teste recentemente usando threads mas com ZEOS, também não consegui fazer funcionar até o final. Ele rodava até um certo tempo e depois dava um AV.
Penso que a implementação de Threads para o Windows ainda não está madura o suficiente para uso. Quando digo madura é que seja de fácil implementação sem que se possa incorrer numa série de problemas difíceis de identificar e de corrigir. Por exemplo ao olhar o seu código não vejo erro algum de implementação, deveria funcionar, mas simplesmente algumas coisas que colocamos em threads não funcionam muito bem.
Penso que a implementação de Threads para o Windows ainda não está madura o suficiente para uso. Quando digo madura é que seja de fácil implementação sem que se possa incorrer numa série de problemas difíceis de identificar e de corrigir. Por exemplo ao olhar o seu código não vejo erro algum de implementação, deveria funcionar, mas simplesmente algumas coisas que colocamos em threads não funcionam muito bem.
GOSTEI 0
Marcelo Carvalho
24/10/2014
Olá Claudio
Entendo que vale a pena insistir.
Vou encaminhar e-mails para alguns conhecidos e quando obtiver uma resposta compartilharei.
Entendo que vale a pena insistir.
Vou encaminhar e-mails para alguns conhecidos e quando obtiver uma resposta compartilharei.
GOSTEI 0
Sanderson Torres
24/10/2014
Boa noite, alguém obteve sucesso com o processo em discussão?
GOSTEI 0
Sanderson Torres
24/10/2014
Boa noite, alguém obteve sucesso com o processo em discussão?
GOSTEI 0
Carlos Modesto
24/10/2014
O que seria esse "Q1F1" e "Q2F2"?
GOSTEI 0
Marcelo Carvalho
24/10/2014
O que seria esse "Q1F1" e "Q2F2"?
Resposta: São parâmetros passados para consulta executada dentro da TTASK.
No exemplo Servem apenas para simular os parâmetros de uma consulta qualquer em uma tabela.
Resposta: São parâmetros passados para consulta executada dentro da TTASK.
No exemplo Servem apenas para simular os parâmetros de uma consulta qualquer em uma tabela.
GOSTEI 0
Marcelo Carvalho
24/10/2014
Prezado Arthur Barth
Pode compartilhar um exemplo do código utilizando a solução que você encontrou?
Pode compartilhar um exemplo do código utilizando a solução que você encontrou?
GOSTEI 0