Olá amigos… tenho uma dúvidazinha básica… como alguns de vcs sabem, e tenho discutido bastante aqui no GUJ, estou passando por uma fase “component-based” para aplicações Web (no Java eu uso o Seam).
Da mesma forma estou estudando Rails que é action-based e realmente acho o Rails muito produtivo.
Ainda não cheguei a uma conclusão conclusiva sobre tentar tornar o http stateful (se é uma boa ou não). No caso do Java o Seam realmente torna o desenvolvimento mais rápido. Algumas aplicações very-ajaxian que tenho desenvolvido realmente achei a abordagem component-based muito favorável.
Bem, a dúvida é que volta e meia no Rails rola action do tipo:
def emitir_pedido
@pedido = Pedido.find(params[:id])
@pedido.emitir
...
end
Geralmente se estou numa tela rica como a emissão de um pedido (pense numa aplicação web e não num website) muitas actions são chamadas e muitas precisam obter o pedido. Essa linha “find” acima é bem repetitiva no meu controller. Isso não gera um overhead grande no banco?
Fazendo um paralelo tosco, quando desenvolvia em Struts (eca) e Webwork muitas vezes enfiava as coisas na sessão pra não gerar este overhead (mas a sessão também gera overhead para manter esse estado). É uma boa estratégia fazer o mesmo com o Rails? O que vcs tem feito?
Já tinha discutido aqui uma vez que component-based é melhor para aplicações web e não web sites. Existe alguma iniciativa component-based web em Ruby?
Rodrigo, acho que você está confundindo statefull x stateless com action-base x component-based.
A um tempão conversando com um dos criadores do Seam ele assumiu que realmente não esperava que usassem o framework p/ um
site com número muito elevado de usuários já que escalar HttpSession é difícil pacas.
Você não considera que o tratamento component-based é uma tentativa de tornar o Http Statefull? O Seam na minha opinião é isso.
Sim… eu não usaria o Seam para fazer uma aplicação pra centenas de usuários. O http://seamframework.org vivia caindo.
Pare para pensar. Pelo menos no meu mundo (empresas normais não empresas “web”) o que desenvolvemos são aplicações que rodam sobre Http e não Web Sites que servem milhares de pessoas.
Não seria correto dizer que action-based sem guardar nada na sessão gera um overhead maior de banco?
Como o Kumpera disse, escalar HttpSession é um bela de uma droga, e pensando no seu cenário com poucos usuários, o overhead do banco não seria um problema tão grande, seria?
Você não considera que o tratamento component-based é uma tentativa de tornar o Http Statefull? O Seam na minha opinião é isso.
[/quote]
Não tenho opinião sobre isso. Até hoje não vi uma descrição boa de qual a diferença entre os dois modelos. E por que component-based necessáriamente
é statefull.
O problema não é exatamente o número de usuários, mas sim não saber quantos são. Acho que escrever uma webapp p/ alguns milhares de usuários usando o dia todo no trabalho com Seam é viável. Aplicação statefull precisam de um sizing mais preciso, coisa que não é possível para um site público.
Sim, para sistemas e não sites, o fato de ser statefull beira a irrelevância. Só não enfiar um pdf de 5 megas na HttpSession que vai funcionar.
Se não existir nenhum tier entre o AS e o banco, sim, sem dúvida. Frameworks component-based facilitam tanto assim o uso da session?
[quote=Rubem Azenha][quote=rodrigoy]
Não seria correto dizer que action-based sem guardar nada na sessão gera um overhead maior de banco?
[/quote]
O uso de um mecanismo de cache não resolveria essa questão? Por que aí em vez de ter os dados na sessão, os dados ficariam disponíveis no cache.[/quote]
O problema é que os dados seriam de usuário e não dados gerais. No caso de você implementar cache por usuário seria quase a mesma coisa que usar a session, visto que o cache fica na memória do servidor do mesmo jeito.
Eu tinha até escrito isso no post anterior, mas voltei atrás e editei, pois tinha confundido as bolas. De qualquer forma, eu partilho um pouco da sua opinião sobre cache, mas no sentido de não manter essas coias na sessão, deixar acesar o find do pedido, mas tendo um cache por trás.
Não acredito que a relação component based X action based seja a mesma que statefull X stateless. Um action-based framework pode ter requisições statefull e um component-based framework pode ter requisições stateless. Simples assim.
O que eu vejo é que o Faces não só não desestimula o uso de Session, como ainda o incentiva, já que uma requisição precisa necessariamente do carregamento da página de origem e depois a de destino. Por causa disso, é sempre mais fácil ter os objetos de modelo em sessão para evitar carregar essa página de origem com objetos “zerados”, que, às vezes, prejudica o comportamento da requisição.
Com outros frameworks, dificilmente existe um incentivo para se usar sessão, já que para isso se exige alguma manipulação de código. Como exemplo: Wicket, um component-based framework, e Struts 2, action-based.
Tenho uma opinião pessoal de não gostar de sessão. Ela é usada, na maioria das vezes, para fazer cache, só que muito “low level” e sempre misturado ao código de controller. A conseqüência é que um “arrependimento” na política de cache implica um esforço hercúleo para corrigir.
E existe implicações no uso indiscriminado de sessão. Uma delas é o grande período de ócio do objeto (uma vez que o objeto na sessão ficará 0.1 segundo sendo utilizado, e 5 segundos esperando uma próxima requisição) que acarretará um alto consumo de memória, e possivelmente uma escrita em disco pelo SO por causa do swap. Isso só acontece em casos extremos, mas é uma boa medida para contrabalancear com o argumento de que é melhor usar sessão para evitar leitura e escrita em disco.
Com relação à dúvida do Rails, do Pedido#find, o método do controller é associado a uma url. Se essa url for cacheada, é possível guardar a página HTML em memória, e daí as próximas requisições não implicará em nenhuma execução de código Rails.
O benefício que vejo no component-based é realmente o statefull. Se você usa JSF por exemplo sem usar o Seam gerenciando estado eu não vejo muitos benefícios. Você só estaria mudando Commands por Metodos.
Tem razão… não tinha pensado nisso. Dá pra escalar bem statefull mas precisa saber quantos são… Bem, o mesmo ocorre pra stateless mas com uma margem maior pra erro.
Sim… vou lembrar disso! Tem pessoas que acham um absurdo guardar objetos na sessão. Eu não vejo esse problema principalmente em Aplicações Web e não sites.
Sim… Na verdade o Seam abstrai isso. Você não precisa se preocupar com a sessão. O framework mantém estado dentro de uma conversation. Eu gosto do Conversation Model do Seam. Ele também impede que besteiras fiquem penduradas na sessão.
[quote=Emerson Macedo][quote=Rubem Azenha][quote=rodrigoy]
Não seria correto dizer que action-based sem guardar nada na sessão gera um overhead maior de banco?
[/quote]
O uso de um mecanismo de cache não resolveria essa questão? Por que aí em vez de ter os dados na sessão, os dados ficariam disponíveis no cache.[/quote]
O problema é que os dados seriam de usuário e não dados gerais. No caso de você implementar cache por usuário seria quase a mesma coisa que usar a session, visto que o cache fica na memória do servidor do mesmo jeito.
Eu tinha até escrito isso no post anterior, mas voltei atrás e editei, pois tinha confundido as bolas. De qualquer forma, eu partilho um pouco da sua opinião sobre cache, mas no sentido de não manter essas coias na sessão, deixar acesar o find do pedido, mas tendo um cache por trás.[/quote]
Eu estava imaginando que nesse caso, como não guardar nada na sessão gera um overhead maior de banco, seriam dados que ficam no banco mesmo. Ex: em vez de manter na sessão o objeto Produto, guardar só o Id dele.
Eu nunca fiz nenhum tipo de teste, mas acho que um cache “escala mais” que uma HttpSession.
[quote=Rubem Azenha]
Eu estava imaginando que nesse caso, como não guardar nada na sessão gera um overhead maior de banco, seriam dados que ficam no banco mesmo. Ex: em vez de manter na sessão o objeto Produto, guardar só o Id dele.
Eu nunca fiz nenhum tipo de teste, mas acho que um cache “escala mais” que uma HttpSession.[/quote]
E o que é httpSession senao estado do cliente armazenado no cache do servidor?
[quote=cmoscoso][quote=Rubem Azenha]
Eu estava imaginando que nesse caso, como não guardar nada na sessão gera um overhead maior de banco, seriam dados que ficam no banco mesmo. Ex: em vez de manter na sessão o objeto Produto, guardar só o Id dele.
Eu nunca fiz nenhum tipo de teste, mas acho que um cache “escala mais” que uma HttpSession.[/quote]
E o que é httpSession senao estado do cliente armazenado no cache do servidor?[/quote]
Isso mesmo. Foi exatamente o que eu escrevi no POST anterior. Dá no mesmo.
Estado mantido em um cache de verdade (como o cache de segundo nível do Hibernate) está seguro de levar diversos updates e também de mostrar sempre a última versão, um cache em HttpSession não tem isso (a não ser que você mesmo implemente), as informações que estão lá podem perder a validade rápido e você vai ter que dar um jeito de estar sempre “consertando” isso.
Estado mantido em um cache de verdade (como o cache de segundo nível do Hibernate) está seguro de levar diversos updates e também de mostrar sempre a última versão, um cache em HttpSession não tem isso (a não ser que você mesmo implemente), as informações que estão lá podem perder a validade rápido e você vai ter que dar um jeito de estar sempre “consertando” isso.[/quote]
No exemplo do yoshi, os dados são de um pedido do usuário. Em teoria, só ele vai estar alterando isso, então nesse caso eu acho que realmente não faz diferença colocar no HttpSession ou cachear de outra forma.
O Rails permite que se grave a session[] no banco. Se eu tiver uma layer/cache entre app->db posso usar a session despreocupadamente?
[comentário paralelo (que não tem haver com a pergunta anterior, não estou dizendo que Seam é melhor)]
Só postando aqui, no Seam não é diretamente a session que usamos, mas sim o conteiner de inject/outject… um Seam Component é cacheable, então, não lidamos com a session diretamente.
[/comentário paralelo]
Estado mantido em um cache de verdade (como o cache de segundo nível do Hibernate) está seguro de levar diversos updates e também de mostrar sempre a última versão, um cache em HttpSession não tem isso (a não ser que você mesmo implemente), as informações que estão lá podem perder a validade rápido e você vai ter que dar um jeito de estar sempre “consertando” isso.[/quote]
Voce esta sugerindo salvar no banco a sessao do usuario ?
Eu estou sugerindo não ter nada em um lugar que é difícil de escalar e a sessão do usuário em uma aplicação web comum (na memória de um único servdor) não é uma boa idéia. Guardar em um banco de dados pode ser o ideal, especialmente se esse banco de dados puder ser apenas o banco de dados das sessões (claro que isso depende do seu tamanho), usar memcached também é uma boa idéia, enfim, só não se deve colocar os dados na “sessão http”, porque essa não escala de jeito nenhum.
Eu estou sugerindo não ter nada em um lugar que é difícil de escalar e a sessão do usuário em uma aplicação web comum (na memória de um único servdor) não é uma boa idéia. Guardar em um banco de dados pode ser o ideal, especialmente se esse banco de dados puder ser apenas o banco de dados das sessões (claro que isso depende do seu tamanho), usar memcached também é uma boa idéia, enfim, só não se deve colocar os dados na “sessão http”, porque essa não escala de jeito nenhum.[/quote]
Mas a ideia inicial nao era evitar acesso ao banco?
memcached seria uma estratégia maais “faca vc mesmo” de algo que deveria ser transparente e que envolve questoes de seguranca.
Se escalabilidade for mesmo importante eu consideraria usar REST. Neste caso a sessao se tornaria parte da aplicacao com um resource identificado por uma url; aí é irrelevante se fica cachedo ou nao.
Não a minha. Pra mim a idéia inicial é não manter estado num lugar que vai lhe dar trabalho.
Desde quando o uso de caches como o memcached não é transparente?
Isso vai ser tão transparente quanto você fizer ser. Em rails por exemplo você pode fazer cache de objetos que vão ser carregados pelo ActiveRecord usando memcached sem alterar nada das suas interfaces públicas, mesma coisa com o Hibernate em Java usando caches distribuúidos como JGroups.
Não sei o que REST traria de diferente, você vai ter que colocar esses dados em algum lugar não vai? Os dados não podem ir na URL, o que vai estar na URL é simplesmente informação pra você ir buscar os dados em algum lugar (um banco de dados, por exemplo).