quarta-feira, maio 21, 2008

Load balancing com Tomcat e Apache

Introdução

Não é bem tema de telas de cadastro, mas posto igual porque tendo isso, então as nossas telas de cadastro poderão continuar funcionando por mais tempo...

Estou falando de load balancing, e especificamente, sobre load balancing usando o Apache HTTP e o (famoso) Tomcat.

Original no TheServerSide

Na prática, o artigo lido está no TheServerSide e ele, além de explicar o que é load balacing, dá exemplos de configuração muito úteis no dia-a-dia.

Aprendizado

Gostei do artigo porque fiquei sabendo que:

1. O mod_proxy é mais atual (e provavelmente melhor) que o mod_jk (que eu usava há anos atrás quando eu realmente fazia sistemas legais...)

2. Os algoritmos Round Robin de load factor têm variantes, habilitando o balenceamento por número de acessos ou tamanho das requisições.

3. Para preservar as Stick Sessions durante um desligamento programado, existe um "processo de shutdown" de servidores Real Workers, onde o objetivo é deslocar a carga de trabalho até que o servidor que será retirado do grupo não tenha mais (ou, se tiver, que esse número seja bem pequeno de) usuários ativos.

Conclusões

Faz anos que não pego nenhum trabalho que fosse preciso load balancing ou clustering de serviços.

E isso é uma pena, mostrando que os nossos Stakeholders não tem uma visão de como é importante disponibilidade e que como nosso conhecimento pode ir por entre os dedos quando não o aplicamos.

sábado, maio 17, 2008

Novo Layout

Vemelho & Preto
Depois de fazer alguns testes no meu blog adimensional, resolvi colocar um novo layout no blog das telas de cadastro.

Sim, estou usando o layout do Carls Mason, e tenho que admitir, embora não seja 100%, ele cai como um luva para o novo logo da minha empresa, a 3Layer Tecnologia.

Notícias Tristes
Na verdade, tenho notícias um pouco lacrimosas paras contar, mas, como eu me conheço bem, essas já são costumeiras em minha vida.

Sim, estou falando da negativa de incubação do projeto Merlin, na Incubadora Raiar do pólo tecnológico da PUC, em Porto Alegre.

Fazia tempos que esperávmos incubar a 3Layer Tecnologia lá, e estavámos com "altos planos" para isso.

Entretanto, acredito que a nossa profunda crença em Software Livre, e a nossa certa libertinagem no amparo financeiro tenham sido o elemento fatídico para o insucesso nessa empreitada.

Pelo sim, pelo não, não fomos escolhidos.

Tristes? Ah, ah!

Em nada.

Para quem conheçe minha história, sabe que não desisto facilmente. Meus planos pessoais vão muito além da temperança, boa vontade e capacidade de assimilação de certas pessoas.

Penso longe, sim - e é isso que me move.

Luto faz quase 8 anos nas idéias do Metagen, e agora do Merlin. Luto contra o tempo, contra as más nuançes da vida, do destino, da saúde, dos negócios, dos amores, do trabalho e os reveses (existe essa palavra?) diários.

Certa vez consultei um guru, e ele disse verdades. Atemporais, tenho que admitir. De momento, já acreditei. E hoje, hoje as confirmo.

Serão quatro anos, e não três, como agora ocorrem.

Assim, sigo à frente, e sem desistir, implico nele, o Merlin.

E a eles, que sintam o amargo.

sexta-feira, maio 16, 2008

Putz, copiaram o Merlin

Frameworks runtime para Telas de Cadastro

Quando iniciei o Metagen lá em 2001, achei que era uma coisa bem diferente. E era. Até a semana passada, para o mundo Java eu não conhecia nada do gênero.

Nas diversas pesquisas que realizei, encontrei mais de 20 projetos acadêmicos provando que a gerção de IU em tempo de execução já era possível lá nos anos 80.

Porém, frameworks de uso profissional, que não entrassem em “viajens” como álgebra relacional, formalismos maquiavélicos, linguagens conceituais ou gramáticas de outro mundo, bem, isso não tinha nada até o Merlin aparecer...

Metawidget

Mas agora os tempos são outros. E como me atraso constantemente em implementar o Merlin, a máquina anda e mais e mais pessoas começam a perceber que esse negócio de gerar código-fonte não tem nada a ver.

Bem por acaso, anteontem, nem não sei o que eu estava fazendo no branquelo, mas me deparei com um link de uma ferramenta chamada Metawidget.

Li alguns artigos e uma entrevista com o criador e só tenho uma frase a dizer: putz, copiaram o Merlin!

Funcionamento da bagaça

O framework do cara tem a essência do Merlin, mas trabalhando de outra forma.

Ele suporta além de beans Java, o famigerado XML. Assim, ele chama isso de “back-end”. Para ler esses back-ends, ele possui o conceito de Inspectors. Os inspectors usam (basicamente) reflexão e coisas to tipo para ler classes POJO, JavaBeans, Anotações ou XML.

E também dá para estender e criar inspectors para outros back-ends, tais como tabelas relacionais (pelo menos é o que o cara diz).

Para a geração, que também ocorre em tempo de execução, ele usa o conceito de Metawidgets. Você pode interpretar essas metawidgets como sendo um pattern Wrapper que encapsula e delega a widget do pacote gráfico em uso.

Assim, tal como o Merlin, ele também suporta diversas bibliotecas gráficas, como Swing, JSF, SWT e – isso eu achei legal – o Android.

Muito parecido

Depois de ler a documentação, baixei o fonte começei a olhar o negócio por dentro.

O Merlin possui a anotação @Caption, que serve para definir o label na tela, tendo suporte à internacionalização (i18n). A bagaça tem a @UiLabel.

O Merlin possui a anotação @Group, que serve para definir (sub)agrupamentos. O framework do cara possui a @UiSection.

O Merlin possui a anotação @Order, que serve para reordenar componentes na tela. O cara usa a @UiComesAfter.

O Merlin possui a anotação @Property, que serve para definir propriedades do controle de IU. O do cara tem a @UiAttributes.

O Merlin possui a anotação @Ignore, quando desejamos que um atributo de um objeto não seja mostrado na tela. A bagaça do cara tem o @UiHidden.

Os Inspectors do cara, são, praticamente, os Resolvers do Merlin.

Os Metawidgets do cara, são, again, os Renderers do Merlin.

Cada metawidget do cara estende a classe-base do pacote gráfico em uso. Por exemplo, ele tem uma metawidget que estende um JComponent para o Swing, outra que estende um UIComponentBase para o JSF, e outra que estende LinearLayout para o Android.

Observem que isso não representa limitações, pois permite que essas metawidgets (ainda não consegui decorar esse nome) sejam estendidas ou mesmo criadas do zero para pacotes gráficos diferentes. Ele tem um exemplo para o RichFaces.

Na prática, essas metawidgets recebem alguns parâmetros (que vêm das anotações, do objeto “inspectado” ou do código-fonte da aplicação principal) e passam-nos para a widget real no sistema. Como disse, é um wrapper com um pouco de deletage (ufh)...

Também olhei trechos de código e, pasmem (ou nem tanto), tem coisas praticamente iguais. Estruturas IF e blocos SWITCH parecem fazer as mesmas coisas em determinados momentos.

Outras funcionalidades semelhantes são o suporte à substituição de controles em tempo de execução, parametrização de layout, binding customizável (com suporte à JSR295) e mapeamento automático de tipos de dados para tipos de controle.

Para não dizer que estou mentindo, vejam:

//Metawidget renderizando um campo booleano e outro char

if ( "boolean".equals( type ) )

return new JCheckBox();

if ( "char".equals( type ) )

return new JTextField();


//Merlin renderizando as mesmas coisas

if (field.getClass() == FieldString.class) {

c = new JTextField();

} else if (field.getClass() == FieldBoolean.class) {

c = new JCheckBox();

}

Enfim, muito, mas muito parecido mesmo ;)

Parecido sim, mas não igual

Mas embora tenham os mesmos objetivos, os frameworks têm algumas diferenças sim. Evitando falar na configuração realimentada do Merlin, vou colocar algumas coisas que os distinguem:

1. POJO x Back-End: O Merlin foi projetado para suportar somente classes que sejam, no mínimo, POJOs. E nada mais. Nesse ponto, o framework do cara vai além, pois permite XML e outras coisas. Nós, no Merlin, vamos continuar afincos à nossa abordagem, pois dia após dia, a Domain Driven Design vem provando que é a melhor forma de fazer sistemas. Assim, nada de XML ou mundo relacional. Peço “sorry” aos que discordam...

2. Campos de lookup: Toda vez que o Metawidget encontra um campo de objeto que é uma referência para outro objeto, ele renderiza o objeto referenciado dentro da janela principal. No Merlin, o padrão é renderizar como um campo de lookup, ou seja, uma caixa de seleção. Acredito que o cara permita outro comportamento, mas não vi isso nos exemplos ou documentação. No Merlin, isso é feito via anotação ou novos renderizadores.

3. Renderização customizada: Nos exemplos do cara, para trocar um controle por outro (por exemplo, não quero o campo “nome” como uma caixa de texto, mas sim como uma caixa de seleção), o cara usa código-fonte na aplicação principal. No Merlin, isso também é possível. Poré, o mais fácil, rápido (e conveniente, pois entra para o sistema de histórico) é usar a anotação @RenderAs.

4. Inspectors x Renderers (again): No framework do cara, os inspectors são definidos na aplicação principal. Assim, se um bean tiver a anotação (do JPA) @Column.length mas não tiver o Inspector associado definido, então essa anotação é ignorada. No Merlin, o propósito é continuar usando ela para fazer coisas como, saber o tamanho que o campo deve ter na tela.

5. Binders: O Metawidget delega, assim como o Merlin, o processo de binding para frameworks de terceiros, como a JSR295. Mas para fazer isso, ele usa código na aplicação principal, ou via XML. No Merlin, usa-se essencialmente anotações, como @Binder, ou @RenderAs.binder.

6. Section x Group: São agrupadores de campos na tela. Não consegui ver detalhes maiores, mas acredito que as sections no Metawidget não possam ser renderizadas de maneiras diferentes. Por exemplo, no Merlin dá para fazer @Group.renderAs e também dá para fazer subagrupamentos com @Group.in.

7. Tratadores de eventos: Também não percebi suporte para o tratamento de eventos no Metawidget. Toda vez que o cara deseja colocar um tratador de evento em um controle, ele chama, tal como no Merlin, o método utilitário getComponent(String name). No Merlin, acredito que o conceito de Agentes seja muito mais fácil. Por exemplo @Agent(event=”focusLost”, action=”buscarPessoaPorCpf”)

8. Injeção, scripting, OCL e EL: Não vou falar tanto, pois o cara está, assim como quase eu estou, sozinho nessa história de criar frameworks. Porém, o suporte à injeção de recursos, previsto para o primeiro release do Merlin, é uma coisa obrigatória nos frameworks de hoje em dia. Ademais, para quem conhece Object Constraint Language e o poder que ela nos trás, não a dispensa tão facilmente. O suporte a scripting também é um recurso poderoso e não pode ser deixado de lado. Essas são coisas que estamos prevendo no Merlin e que o Metawidget parece deixar para um segundo momento, eu acho. Mas ele traz a Expression Language, e isso é bom. Tanto, que é previsto no Merlin.

Não conheçe? Tá bom...

Posso estar sendo tendencioso em minha análise (seráquáquáquá?). Mas não ocultei verdades em nenhum momento.

A única coisa que fico triste mesmo é que lendo o FAQ do projeto do cara, ele diz que não conheçe nenhuma solução do gênero. E isso é uma pena.

Compreendo que usando a língua inglesa o poder de penetração é maior. E até engines como a do branquelo acabam aumentando essa diferença. Mas o cara dizer que não conheçe nenhum gerador (ou seria, renderizador) semelhante é uma abscência total de informações. E não estou falando do Merlin, mas de coisas bem mais antigas, como o DRIVE, ITE, FUSE, AME, MASTERMIND, HUMANOID, UIDE, MECANO e, claro, o bom e velho Metagen...

Conclusões

Quatro.

Se temos concorrentes, é porque temos nicho de mercado.

Se a forma de implementar é quase a mesma, é porque estamos fazendo certo (ou estamos errando junto!).

Se os releases do Merlin demorarem a sair, não precisam sair mais.

E se não aprendermos inglês logo, de nada adianta ter releases.

sexta-feira, maio 02, 2008

Enfim ela: A JSR 317 - Java Persistence API 2.0 disponível para revisão

Veio hoje o email para o grupo, indicando que o Early Draft Review da nova especificação de persistência do Java está disponível para o público olhar e, claro, opinar.
É bem verdade que ela veio com o atraso de um mês (a previsão desse review era para o Abril passado), mas veio em boa hora igual.

Números e Improvements
Tenho inclinação inconsciente (olha eu usando palavras seguidas com as mesmas iniciais) para olhar as coisas e traçar comparativos. Essa JSR tem 299 páginas, que equivale ao número da JSR dos WebBeans, que está nas mão do hábil Gavin King.

Coincidências à parte, essa nova versão da Java Persistence API busca expandir os recursos da JPA 1.0, agregando features que há muito já deveriam estar disponíveis: melhorias na linguagem de query; expansões no mapeamento objeto-relacional (com ênfase para listas ordenadas, coleções de objetos embutidos e alguns outros recursos relacionados); padronização na engine de geração da DDL; contratos expandíveis para passivação e replicação de contextos de persistência; melhorias e uma maior padronização no gerenciamento nos estados dos entity beans e, principalmente, o suporte a validação dos beans.

Quanto à API Criteria (que diga-se de passagem, eu não gosto), esse primeiro draft nao trouxe nada de novo. Acredito que o grupo ainda não chegou a um denominador comum e, por isso, acho que esse capítulo somente deve vir no draft 2 desse documento.

Contraste
Não conheço niguém que usa JPA puro. Em outras palavras, não conheço ninguém que efetivamente homologou sua aplicação JPA com múltiplos frameworks sobre múltiplos banco de dados em múltiplos servidores.

Acredito eu - até que me provem o contrário - que isso é utopia mesmo. Ninguém em sã consciência (diga-se de passagem, os stakeholders) está a fim de arcar com isso, mesmo porque o ROI (Return Of Investment) de um trabalho desses sempre tende a zero.

Assim, o que acontece é que as pessoas (como eu) acabam usando implementações robustas (como o Hibernate - desculpem, mas Toplink não é um exemplo aqui) e deixam a equidade do JPA de lado.

Nesse sentido, essa revisão na JPA é mais impactante para os players que criam as implementações, e não nós que as utilizamos.

Ainda sem cache
Já era esperado, mas repito que eu ficaria feliz se o recuso de cache fosse disponibilizado na JPA.

Quem usa Hibernate, tem isso desde suas primeiras versões; antes com o ehcache, e hoje com o maravilhoso suporte dos caches clusterizados hierárquicos do JBoss :). Porém, essa feature ainda não deve vir tão cedo.

Ao meu ver, o recurso de cache na JPA somente deve vir lá pela versao 4 ou mais. Isso ocorre porque para termos um recurso de cache consistente, dependemos de protocolos de mais baixo nível, os quais estao na infra-estrutura de base do servidor EJB, tais como replicação e failover, lembrando que isso pode incluir recursos clusterizados ou não em ambientes transacionais e em modelos de rede muito atipicos. Quem usa JBoss se aproxima disso; quem usa outros servidores de aplicação, eu não tenho tanta certeza.

Obviamente, o recurso de cache poderia comerçar simplório (hic), como foi o ehcache lá nos idos do Hibernate 1.0 (há mais de 5 anos). Porém, acredito que isso esta mais para uma outra JSR, visto que envolveria mais do que apenas os entity beans. Enfim, ainda não temos.

Mais detalhes! Mais detalhes!
Vou ter que ler a especificação para saber exatamente o que mudou frente à JSR 220 (há, eu gostava tanto desse número). Somente depois, vou poder dar mais detalhes.

Sugiro para quem trabalhe na área, que baixe os 5MB do PDF e leia também. Afinal, a leitura é uma constante na nossa área.

Quanto ao release de hoje, bem, é o mundo evoluindo :)