Em 8 de agosto de 2012 20:41, Luiz Americo Pereira Camara <luizamericop-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> escreveu:
> Em 8 de agosto de 2012 12:11, Paulo Botelho <ppbflu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> escreveu:
>>
>> Olá Pessoal,
>>
>> Sou novo no grupo e estou fazendo uns testes com o FastCgi, (fpWeb,
>> fpFCGI) e consegui fazer os testes iniciais.
>>
>> O que não consegui (e é fundamental para mim) é fazer com que aceite
>> chamadas simultâneas/concorrentes.
>>
>> Em um simples teste, tenho duas actions. a action1 faz um sleep(n) e em
>> seguida faz a resposta normal.
>> A action2 simplesmente responde um texto qualquer.
>>
>> Se chamar action1 e action2 simultaneamente, action2 só responde depois
>> que action1 terminar o sleep e responder.
>>
>> Alguém tem alguma sugestão de como utilizar o FastCgi em um ambiente de
>> concorrência ?
>
>
> Qual o servidor você está usando?
>
> Pelo menos o apache não suporta Multiplexing:
> http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
>
> Acho que o fpweb também não
>
> Com relação a concorrência, o fastcgi permite executar mais de uma instância
> por vez (configurável).
>
> Luiz
Luiz, deixa eu te contar uma coisa legal que aprendi sobre FCGI no Apache (experiência no Mint, Apache crú, usando config default), vai ser legal pro Paulo acompanhar... Estou enviando em anexo o teste super bobo que fiz usando custfcgi. (me falaram no BT que ela é multi thread)
Quando um usuário faz uma requisição comum, que seja razoavelmente rápida, o Apache abre uma única instância do executável fcgi. Se o mesmo usuário e/ou outros usuários fizeram novas requisições, o Apache continua aproveitando a mesma instância do fcgi. E ele vai levando a vida, aproveitando a mesma instância, até todo mundo descansar de requisições e o timeout do fcgi ser disparado, aí enfim a instância desaparece. Eu gostei muito disso, e é nessa parte que o FastCGI ganha em performance para o PHP.
O cenário muda na seguinte situação: o primeiro usuário faz uma requisição, que irá entrar em loop ou ficar presa num sleep por alguns segundos. Supondo que o PID da instância seja 8306; Um novo usuário faz uma requisição quase que no mesmo instante do primeiro usuário, para esse segundo o PID é 8307. O primeiro, ainda preso no loop, fica observando o botão de refresh do browser rodando, avisando que está em processamento... O segundo usuário faz uma nova requisição, e vamos que o PID dele continua sendo o 8307. Já o segundo, vai trocando de instância, dividindo o tempo em cada uma delas para escapar do timeout. Eu notei que para o primeiro request fugir de ser encerrado pelo timeout, o Apache continua abrindo novas instâncias para ele, mas elas não passam de dez. Os caras do Apache foram muito espertos em criar algo assim. Resumindo em miúdos, para o Apache em Linux Mint (juro que irei testar no openSUSE e no meu server online na HostMonster), o Apache mantém uma única instância para requests razoavelmente rápidos, e uma série de 10 instâncias para requests pesados. Isso deve ser correto, uma vez que quem usa FastCGI são os caras mais exigentes do mundo no quesito performance: o povo do C++.
Teste bobo, se puder, faça no teu server e nos conta como foi tua experiência (eu não tenho pressa, fique a vontade):
------------------------------------------
program project1;
{$mode objfpc}{$H+}
uses
custweb,
custfcgi,
HTTPDefs,
SysUtils;
type
TApp = class(TCustomFCGIApplication)
protected
function InitializeWebHandler: TWebHandler; override;
end;
TWHandler = class(TFCGIHandler)
public
procedure HandleRequest(ARequest: TRequest; AResponse: TResponse); override;
end;
function TApp.InitializeWebHandler: TWebHandler;
begin
Result := TWHandler.Create(Self);
end;
procedure TWHandler.HandleRequest(ARequest: TRequest; AResponse: TResponse);
begin
case ARequest.PathInfo of
'/timer': Sleep(60000);
'/test': AResponse.Content := FormatDateTime('hh:nn:ss', Now);
end;
end;
begin
with TApp.Create(nil) do
try
Run;
finally
Free;
end;
end.
------------------------------------------
Para testar, chame /test. Usando ps e grep pegue o PID do primeiro request; Chame /timer, e fique observando a variação de PIDs dele, porém notando o PID do primeiro.
Testei se meu roteador estava OK quando a isso, cheguei a suar frio pois acreditei que quando o roteador estivesse ocupado com uma rota e ação em loop, ela só ia processar o pattern das próxima ações após a primeira sair do da primeira loop, tipo um funil. Caí o queixo, funcionou tudo perfeitamente, isso é certo pq usei um request independente para cada rota; cada rota tem uma ação em ponteiro, e cada ação tem um método request próprio. Gostaria de dar uma olhada nos fontes em PVT? Te enviei convites no Bitbucket mas como não respondeu pensei que não tinha interesse em acompanhar o nascimento do projeto. :/
Sorte nos testes. o/
--
Silvio Clécio
My public projects - github.com/silvioprog
--
Você recebeu esta mensagem porque está inscrito no Grupo "Lazarus-BR"
nos Grupos do Google.
Para postar neste grupo, envie um e-mail para
lazarus-br-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Para cancelar a sua inscrição neste grupo, envie um e-mail para
lazarus-br+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Para ver mais opções, visite este grupo em
http://groups.google.com.br/group/lazarus-br?hl=pt-BR