Mostrando postagens com marcador arquitetura. Mostrar todas as postagens
Mostrando postagens com marcador arquitetura. Mostrar todas as postagens

Apresentação na QCon SP /ou: Ai vai o PPT

Posted: 12 de set. de 2010 | . David Lojudice Sobrinho | tags: , , , 1 comentários

Primeiro, obrigado pelo pessoal que apareceu lá e principalmente para os que questionaram e/ou compartilharam um pouco dos problemas e soluções com a gente! Foi realmente muito bacana! A idéia era essa: compartilhar experiências. Objetivo mais do que alcançado!

Antes que esfrie, ai vai a apresentação:

Apresentação na QCon SP

Posted: 16 de ago. de 2010 | . David Lojudice Sobrinho | tags: , , , 0 comentários

Primeiro queria agradecer ao pessoal que compareceu no DevInSampa (fotos)! Foi muito bacana, com o pessoal fazendo perguntas bem interessantes.

Agora esperamos você na QCon SP!

Case CMS Abril - System of Systems e Arquitetura (quase) Caótica.
Ao aceitar que organizações são sistemas amplos, orgânicos e complexos, devemos adaptar nossa arquitetura a esta realizade. Como viabilizar um enterprise system que se adapte com a velocidade necessária as mudanças de requisitos, conflitos de necessidades dentro deste paradigma?
Para tanto, será explorada a teoria de Sistemas Complexos Adaptáveis e Emergência x BDUF, System of Systems e REST Archtectural Style e como estes conceitos estão ajudando a Abril a construir o parque de aplicações que suporta a publicação de mais de 100 sites e provê mais de 300 milhões de requests/mês.

Apresentação no Dev in Sampa

Posted: 22 de jul. de 2010 | . David Lojudice Sobrinho | tags: , , , 0 comentários

A apresentação no Dev in Sampa foi aprovada. Obrigado pelos votos! Espero você lá!

Apresentação no Dev in Sampa

Posted: 13 de jul. de 2010 | . David Lojudice Sobrinho | tags: , , , 0 comentários

Estamos concorrendo com uma apresentação no Dev in Sampa, que acontece no dia 14/08. Vota lá! :)

REST in Sampa: Case CMS Abril
Ao aceitar que organizações são sistemas amplos, orgânicos e complexos, devemos adaptar nossa arquitetura a esta realizade.
Como viabilizar um enterprise system que se adapte com a velocidade necessária as mudanças de requisitos, conflitos de necessidades dentro deste paradigma?
Para tanto, será explorada a teoria de Sistemas Complexos Adaptáveis e Emergência x BDUF, System of Systems e REST Archtectural Style e como estes conceitos estão ajudando a Abril a construir o parque de aplicações que suporta a publicação de mais de 100 sites e provê mais de 300 milhões de requests/mês.

Link Relations /ou: What the rel?

Posted: 8 de jul. de 2010 | . David Lojudice Sobrinho | tags: , , , 0 comentários

Estamos utilizando representações hipermídia (HATEOAS) a algum tempo já. Uma discussão que fica interessante é quando alguém pergunta: O que eu coloco no rel do link?

Aqui vai o que pensamos sobre o assunto e como estamos utilizando aqui na Abril.


No geral, o rel indica qual a relação do link com o atual recurso. O rel="prev" do Atom, por exemplo, indica que o link vai para a página anterior em relação a página atual. Logo a semântica que o rel de um link carrega depende do recurso atual (página atual), do media type (Atom) e do contexto. Veremos...

1. O recurso atual

Todo rel deve dar um significado ao link em relação ao recurso atual:

  • Mudar o estado do próprio recurso: (um PUT para o rel="self", por exemplo)
  • Recursos relacionados: rel="comentarios", rel="materias_associadas"
  • Navegar para a próxima parte de um fluxo: rel="next"

2. Media type

Alguns media types fixaram em suas especificações os valores que o rel pode receber. Para citar alguns, o Atom tem os seus assim como o HTML.

Problema? Imagine um recurso representado em Atom, com o link rel="related". Este link deve indicar "recursos relacionados" nessa representação. Mas e caso estivéssemos usando um outro media type que também tivesse uma predefinição para rel="related", mas com outro significado? Lembre-se que um recurso pode ser representado em vários media types e os links com rel que indicam qual a navegação do fluxo.

Ainda no caso Atom, caso você queira usar algum outro rel que não esteja na lista, é necessário usar uma URI. Algo como rel="http://blabla.com/proxima_semana". A idéia é que a URI leve a documentação da relação.

3. Contexto

O contexto no qual a representação vai ser usada é relevante. Vejo 3 contextos:
  • Machine-2-Machine na Web: o recurso e suas representações estão visíveis na web.
  • Machine-2-Machine em um ambiente fechado (enterprise integration): o recurso e suas representações estão visíveis apenas em um ambiente onde os clients são conhecidos.
  • Human-2-Machine: o recurso e suas representações são lidos por uma pessoa. No caso da web, esta página HTML que você está lendo serve de exemplo. Mas poderíamos pensar na Web API do twitter e um desenvolvedor lendo o recurso raw da API, tentando criar uma automação.

Respondendo a pergunta: O que eu coloco no rel do link?

O rel deve expressar o mais claro possível a relação do recurso atual com o link. De preferência um subjetivo e não um verbo.

O recurso vai ficar exposto na web? Se sim, tente respeitar as especificações do media type para rel conhecido ("prev", "next", por exemplo), mesmo correndo o risco de conflito entre media types. Crawlers podem navegar pelo seu conteúdo e gerar relacionamento entre eles já que o rel é conhecido. No entanto, micro formatos fariam um trabalho melhor aqui. E para rel não conhecido, não utilizar URIs. Além de complicar o código do client, a URI no rel dificulta a leitura do nosso amigo desenvolvedor externo, além de não mudar a atitude dos crawlers.

Caso o recurso não esteja exposto na web, ignore completamente as especificações do media type e de preferência a rel com nomes claros que seus clients consigam entender facilmente (linguagem ubíqua).

Conclusão

A verdade é que a discussão sobre linked data ainda está aberta nos comitês do W3C.

Enquanto não existe um padrão claro, nossa visão tenta ser pragmática, baseada em cenários conhecidos por nós e baseado também em outros casos de serviços na web.

Jim Webber na Abril Digital /ou: No caminho certo...

Posted: 11 de mai. de 2010 | . David Lojudice Sobrinho | tags: , , , , 0 comentários

Ontem assistimos a apresentação (short version) do Jim Webber sobre REST aqui na Abril. Apesar de já ter lido o PDF umas mil vezes, ainda assim foi muito legal rever alguns conceitos e aprender outros novos (como usar OpenID e OAuth, por exemplo).


Depois passamos um tempo conversando sobre o que estamos fazendo aqui (System of Systems, REST, Arquitetura Emergente, Restfulie, Scrum em Escala, etc). O resultado da conversa foi muito bacana. Vou tentar postar mais sobre esses assuntos. O mais legal é a confirmação que estamos indo no caminho certo. Cool!

System of Systems e os Sistema Complexo Adaptativos /ou: Arquitetura (Quase) Caótica...

Posted: 27 de jan. de 2010 | . David Lojudice Sobrinho | tags: , , 0 comentários

No último post eu descrevi como estamos pensando a plataforma de publicação e gerenciamento de conteúdo na Abril Digital e como o conceito de System of Systems (SoS) se aplica. Neste post quero discutir algumas características de um SoS.

Toda vez que penso nos conceitos de System of Systems (SoS), me vem a mente a imagem de uma grande revoada, aquela formação no ar por um monte de pássaros voando aparentemente sem rumo, que é caótica e concisa ao mesmo tempo. O que isso tem a ver com o SoS? Veremos...

O interessante sobre as revoadas é saber que os pássaros não têm um chefe dizendo para onde ir. Porém, o grupo se orienta no ar de forma organizada. Mas como isso é possível? O que acontece é que cada pássaro segue 3 regras básicas: evitar bater em um vizinhos ou obstáculos, alinhar vôo para coincidir com os vizinhos e voar uma distância média entre os vizinhos. Assim, um fenômeno emerge e temos a revoada. Ou seja, o que vemos é algo que parece ser criado, mas na verdade aquilo se manifesta daquela forma.

Será que conseguimos criar regras básicas para os sistemas e assim criar um SoS que se manifeste moldando as necessidade de negócio? Essa foi a pergunta que me fiz a alguns meses atrás e neste post estão algumas evidencias teóricas e práticas que dão suporte a idéia.

O fenômeno da revoada é estudado como um Sistema Complexo Adaptativo (Complex Adaptive System ou CAS), assim como outros sistemas complexos, que vão da economia a física, passando pela formação do cérebro ou a um time de scrum, "complexos no sentido de que são diversos e feitos de múltiplos elementos interconectados, e adaptativos porque têm a capacidade de mudar e aprender com experiências passadas". É aqui que o SoS se assemelha a revoada: diverso, interconectado e evolui.

Será isso mesmo? Vamos olhar o SoS através da idéia de um CAS e ver se conseguimos observar algumas propriedades semelhantes:

Emergência: Ao invés de ser prevista ou controlada, os agentes do sistema interagem de forma aparentemente aleatória. De todos esses padrões emergem interações que informa o comportamento dos agentes dentro do sistema e do comportamento do próprio sistema. Não há nenhum grande plano e o resultado apenas surge como resultado dos agentes seguirem algumas simples regras locais.

Mas o SoS não tem um grande plano? Não deve estar alinhado com a estratégia da empresa? Essa é a principal caracterisca que emerge! Ela não é controlada diretamente, assim como você não manda todos os pássaros voarem para um lado ou para outro. No entanto, acredito eu, existem mecanismos para direcionar essas características (veremos mais abaixo).

Além disso, como cada sistema é independente no SoS, eu não ficaria surpreso se um novo sistema criasse algo completamente novo, algo que simplesmente surge, emerge, juntando informações e funcionalidades de vários outros sistemas.

Co-evolução: Todos os sistemas existem dentro de seu próprio ambiente e eles também fazem parte desse ambiente. Portanto, conforme seu ambiente muda, eles precisam mudar para garantir melhor ajuste. Mas porque eles fazem parte do seu ambiente, quando eles mudam, mudam o seu ambiente também, e como ele mudou eles precisam mudar novamente, e assim por diante como um processo constante.

No SoS, isso é sutil. Imagine que um sistema foi alterado e agora ele aceita maior número de requisições. Isso vai fazer com que outros sistemas se conectem a ele e assim, alterando a configuração do SoS todo. O SoS ganha essa nova formação, que acaba por interferir em como os outros sistemas se conectam e assim por diante.

Poderíamos extrapolar para um outro exemplo, em que alguém do time de um sistema X foi trabalhar em um outro sistema ou saiu da empresa, deixando a evolução do primeiro mais lenta. Isso influencia não só no sistema X, mas também em como os outros times vêem aquele sistema, fazendo tomarem decisões se vão ou não conectar a ele. Novamente, a evolução de um sistema influenciou o conjunto que influenciou os sistemas e assim infinitamente...

Sub ideal: Um CAS não precisa ser perfeito para que prospere dentro do seu ambiente. Uma vez que um CAS atinge o estado de ser bom o suficiente, ele trocará eficiência por maior eficácia.

Pensar que um SoS não vai atingir seu estado máximo é perturbador. Mas quando se entende a complexidade de uma empresa, em todos os seus aspectos, o ótimo é inimigo do bom. Ter um SoS que evolua até chegar em seu estado quase perfeito é um grande conforto na verdade. Esperar que ele troque eficiência por eficácia é mais confortante ainda.

Variedade: Quanto maior a variedade dentro do sistema, mais forte ele é. Sistemas adaptativos complexos dependem de ambigüidade, paradoxo e contradições para criar novas possibilidades.

Não vejo problema, por exemplo, em ter dois ou mais sistemas com a mesma responsabilidade, mas que se diferenciam nos requisitos. Que ganhe o melhor! O SoS vai atrair um para o centro e o outro será expurgado. Ou não! Talvez os dois façam sentido e ganhem um número de conexões semelhantes um do outro. Assim como a evolução das espécies, só se consegue a evolução do SoS quando existe variedade.

Para estimular a variedade, não há regras explícitas (pelo menos do ponto de vista de arquitetura de sistemas) em como cada sistema deve ser construído, seja a linguagens, tecnologias ou design interno da aplicação. O importante é que o sistema se comporte bem dentro do SoS (ex.: se comunique usando HTTP e Atom/Hypermedia).

Auto-organização: Não existe uma hierarquia de comando e controle em um CAS. Não há planejamento ou gestão, mas há uma constante reorganização para encontrar o melhor ajuste com o ambiente.

O exemplo acima é válido aqui também. Quem diz se o sistema é bom ou não para o SoS é o próprio SoS. O modo dele expressar isso é a através de conexões que um sistema faz a outro sistema. Quanto mais conexões ele receber, melhor é o sistema para o SoS.

Conectividade: As maneiras pelas quais os agentes em um sistema se ligam e se relacionam entre si é fundamental para a sobrevivência do sistema, pois é a partir dessas conexões que os padrões são formados e o feedback disseminado. As relações entre os agentes são geralmente mais importante do que os próprios agentes.

Uma arquitetura baseada em serviços (SOA) tradicional não tem essa característica fundamental, que é a navegação entre os sistemas de forma transparente. No nosso caso estamos apostando no conceito de Hypermedia, no protocolo HTTP e no formato Atom para realizar essas conexões. As conexões são tão importantes para nós que estamos gastando um tempo considerável nesse problema.

Regras simples: CAS não são complicados. Os padrões emergentes podem ter uma rica variedade, mas, como em um caleidoscópio, as regras que regem a função do sistema são bastante simples.

Será que conseguiremos definir essas regras ou elas aparecerão como resultado da interação dos sistemas? A ser respondido. No entanto, acredito que parte da manipulação do comportamento emergente está aqui, ou seja, na definição prematura das regras. Assim, se as regras estiverem alinhadas com os conceitos básicos do negócio, o SoS não tem outra escapatória a não ser emergir com as características esperadas. Um desafio é definir as regras básicas de forma que elas também possam evoluir.

Sistemas Aninhados: A maioria dos sistemas está aninhados dentro de outros sistemas e muitos sistemas são sistemas de sistemas menores.

É normal que um time médio (de 6 ou 8 devs) designado para implementar um "módulo" do SoS implementem alguns sistemas/serviços, ao invés de apenas um, criando um subsistema dentro do SoS. Observar o que acontece nesses subsistemas é importante, pois talvez ali as regras do SoS não estão sendo aplicadas ou evoluções dessas regras apareçam.

À beira do caos: Teoria da Complexidade não é o mesmo que a Teoria do Caos, que é derivada da matemática. Mas o caos tem um lugar na Teoria da Complexidade em que os sistemas existem em um espectro que vai do equilíbrio para o caos. Um sistema em equilíbrio não tem a dinâmica interna que lhe permita responder ao seu ambiente e vai lentamente (ou rapidamente) morrer. Um sistema em caos deixa de funcionar como um sistema. O estado mais produtivo de se estar é à beira do caos, onde há máxima variedade e criatividade, levando a novas possibilidades.

Do ponto de vista de SoS, o caos deve ser administrado de forma a não extrapolar as expectativas e recursos da empresa. Isso não quer dizer que ele não deva existir! Evitar coisas como ESB, middlewares de governança ou qualquer forma de gerenciamento centralizado é uma maneira do SoS a evoluir e a se auto-organizar.

Fronteiras: A auto-organização implica que o sistema está rodeada por uma fronteira que o contém. Esta condição define o "auto" (self) que será desenvolvido durante o processo de auto-organização. [G. Eoyang & D.J. Conway, 1999]

A fronteira do SoS é definida quando se sabe o que é esperado dele do ponto de vista de negócio. Sem essa definição não existe como o SoS se auto-organizar, já que não existe o "auto". Além disso, é da definição da fronteira que será possível pensar as regras básicas, que deverão levar em conta até onde o sistema vai e onde é que ele termina.

Já gastamos um bom tempo definindo as fronteiras com as pessoas de negócio. Agora, o meu papel junto aos outros arquitetos da plataforma está na definição da comunicação dos sistemas e na definição das regras simples. Esperamos com essas definições criar uma terra fértil para os sistemas do SoS, deixando espaço para que eles cresçam e dêem frutos. Estamos regando diariamente!

Ah! Pensar arquitetura dessa forma traz implicações com as áreas de Infra-estrutura, Desenvolvimento e Scrum Office. Parte dessas implicações já apareceu e foram ou estão sendo resolvidas num trabalho em conjunto muito bacana e com idéias tão legais quanto. They got it!

System of Systems, REST, Hypermedia e HATEOAS /ou: Um dia na vida de um integrador de sistemas...

Posted: 18 de jan. de 2010 | . David Lojudice Sobrinho | tags: , , 1 comentários

Há alguns meses fui chamado, junto com o Julio, para revisar a arquitetura da nossa plataforma de publicação e gerenciamento de conteúdo, que é responsável desde a criação de sites até a autorização de usuários e busca de conteúdo pelos editores. Resumindo (muito) a história, encontramos alguns sistemas monolíticos que represavam os requisitos de uma empresa formada por muitas unidades de negócio com necessidades variadas, muitas vezes até conflitantes. Se a lei de Conway é inevitável, tentar trapaceá-la não foi uma boa idéia. O modelo monolítico estava na nossa mira e pronto para ser derrubado.

Precisávamos de um modelo distribuído, com sistemas menores, de baixo acoplamento e alta coesão (já tinha ouvido falar que outros estavam indo nessa direção). O Julio cunhou o termo "System of Systems" e todos entenderam a idéia de uma forma geral. Um sistema que é formado por outros sistemas, onde um requisito de negócio era dissolvido em requisitos menores para sistemas menores, mas que juntos criavam a funcionalidade que o negócio esperava.

Mas isso não é um modelo de desenvolvimento baseado em componentes tão popular nos anos 90 ou um nome diferente pra Web-services? Quase. Sim, existe um trabalho de separação de interesses (separation of concerns), assim como nos componentes e em WS. Porém, diferente dos componentes ou WS, não tínhamos o protocolo comum entre os sistemas, como nos componentes distribuídos (SOAP, CORBA, DCOM, etc). Precisávamos de um protocolo que pudesse acolher nossos requisitos:

  • Distribuído e descentralizador
  • Escalabilidade: lidamos com milhões de requisições/dia. Escalar é preciso!
  • Tolerante a falhas: não queremos deixar de mostrar uma página para o internauta só porque um dos sistemas esta fora. E sim, eles ficam fora.
  • Fracamente acoplados: quanto menos souber de suas dependências e dos que dependem dele, mais utilizado e fácil de evoluir é um sistema.
  • Facilidade de implementação: trabalhamos com diferentes linguagens e tecnologias. Protocolos abertos, com uma boa base de usuários e libs estáveis é essencial.
  • BASE (Basically Available, Soft state, Eventually consistent): privilegiamos a disponibilidade sobre a consistência dos dados (assim como um sistema para web deve ser)
  • Relacionamento entre recursos: queríamos criar uma rede de sistemas, quase caótica (do ponto de vista de governança) e sem repositório central. Pra isso, a informação sobre a relação entre recursos deveria existir no protocolo de comunicação entre os sistemas e ser entendida por qualquer sistema da plataforma.

Estávamos de olho no REST e parecia o caminho natural, mesmo com suas limitações. Sabíamos que é natural fazer CRUD com o REST, mas e o restante? Um sistema não é formado apenas por CRUD dos dados. Existem perguntas complexas que um sistema deve responder, começando por uma busca de uma palavra num texto até cálculos ou transformações de dados específicos de negócio. RPC? Talvez...

Nessa época caiu na minha mão (via @Dimas) a apresentação "REST in Practice - A Tutorial on Web-based Services", do Jim Webber, Savas Parastatidis e Ian Robinson, nomes que já tinha ouvido falar ao pesquisar sobre SOA e REST. Numa primeira visita, eu pensei que a apresentação era sobre a história das tentativas de Web-services e seus formatos para depois exaltar o quão bom o REST é. Na segunda olhada, com mais cuidado (afinal são 302 slides), me chamou a atenção o conjunto dos conceitos de REST com Hypermedia, HTTP como o protocolo de aplicação, Atom e como tudo isso deveria ser a base para uma arquitetura de um sistema distribuído. Afinal, isso tinha dado certo uma vez: a web funciona assim! Aliás, se olhar os requisitos da nossa plataforma ali em cima, vai ver que a semelhança é grande. Ou seja, parecia que eu tinha encontrado o que estava procurando.

Hypermedia é um conceito que foi citado como parte fundamental do REST no doutorado de Roy Fielding (foi neste trabalho que o termo REST apareceu), mas que foi esquecido no meio do caminho. O foco dado foi exclusivamente sobre o recurso, porém, ao esquecer o conceito de hypermedia, deixou-se de lado como conhecer e navegar nesses recursos.

Utilizar o HTTP como protocolo de aplicação e não apenas como protocolo de transporte (discussão antiga do pessoal do SOAP vs REST) já era algo que desejávamos, mas ao olhar o HTTP de perto, encontramos muito mais do que GET, POST, PUT e o DELETE. Ao entender os verbos, os códigos de retorno e os media types, tem-se um protocolo muito mais complexo e pronto para sistemas distribuídos.

E quando menos se esperava, eis que um padrão XML aparece na nossa frente: Atom. Ali no Atom é que se encontram as ferramentas para tornar o hypermedia viável entre sistemas, pois o conceito de links faz parte do padrão.

Parecia que tínhamos encontrado o que queríamos. Bom, pelo menos no campo teórico... Ao tentarmos implementar, esbarramos em alguns problemas com as libs que dão suporte a esses conceitos. Por exemplo, a especificação Atom dá suporte a uma série de features que não encontramos implementadas em nenhuma lib (Ruby ou Java) e que seriam importantes para nós. E se o HTTP é completo (e, como disse antes, complexo) ao dar suporte a sistemas distribuídos, por outro lado as libs acabam escondendo informações ou bagunçando a idéia do protocolo na tentativa de simplificá-lo.

Para nossa sorte, encontramos o Guilherme Silveira, que já estava envolvido nas discussões sobre REST, Hypermedia e HATEOAS (Hypermedia as the Engine of Application State) e estava implementando o Restfulie, uma lib que busca o REST no seu conceito original, ou seja, com os conceitos de hypermedia e transição de estado, além de ser amigável com o protocolo HTTP em toda sua complexidade.

A história ainda não terminou. Na verdade está apenas no início. Estamos começando a implementar esses conceitos nos novos sistemas, refatorando os antigos sistemas monolíticos para sistemas menores, e ainda começamos a ajudar o Guilherme na evolução do Restfulie. Temos um longo caminho pela frente na construção da nova plataforma, que vai inclusive colocar todas essas idéias a prova. Porém, mais do que nunca, acredito que estamos no caminho certo.

Escalabilidade de web sites /ou: Como é que eles conseguem?

Posted: 3 de dez. de 2009 | . David Lojudice Sobrinho | tags: , , 3 comentários

Depois de 6 meses de pesquisa, estou disponibilizando aqui o meu trabalho sobre escalabilidade de web sites que fiz para o meu curso de Pós-graduação.

Apresento no trabalho a análise das arquiteturas de web sites que estão entre os principais sites da internet. Tentei identificar o que faz, do ponto de vista de arquitetura de software, com que eles consigam atender um número muito alto de usuários.

Ai vai: pesquisa e a apresentação


RefList Cache /ou: Piece of cake!

Posted: 17 de set. de 2009 | . David Lojudice Sobrinho | tags: , , , 0 comentários

Quem já usou cache para uma aplicação web sabe: o que no começo parece simple, é mais complicada do que parece.

Um dos maiores problemas de cache é a invalidação. Quando invalidar? Onde invalidar?

Vou contar a história do projeto que participei a um ano atrás, o Gostei.com, onde o uso de memcached é extenso. Tínhamos o seguinte problema: um mesmo post pode aparecer em várias listas, sendo que estas listas poderiam ter ordenações e filtros diferentes. Mas se o post sofresse alguma alteração, como um novo voto, o número de votos tinha que ser igual em todas as listas.








A primeira abordagem foi um pouco ingênua: serializar e guardar no cache a lista inteira (List<Post>), incluindo o post junto. O problema é que a quantidade de votos de um post pertence a classe Post, tínhamos uma quantidade de votos diferente em cada lista (lista diversão-mais_votados e todos-mais_recentes, por exemplo) para o mesmo post. Era impossível saber em quais listas aquele post foi cacheado.

A solução foi usar o que chamamos de RefList Cache. Ao invés de guardar a lista com os posts, cacheamos a lista com os IDs dos posts (List<Guid>) e para cada post existe apenas um lugar no cache (uma key única). Assim, quando um post sofrer alguma alteração, basta atualizar invalidar o cache em um único lugar. Graças a um recurso do memcached (get_multi), é possível ter o RefList e todos os item com apenas duas chamadas.





Piece of cake! Quer dizer... nem tanto. Ainda tem um problema. Nada garante que todos os IDs da RefList vão estar no cache. O que fazer? Um dos recursos da lib que criamos é o conceito de hierarquia de repositório, onde é possível dizer a ordem dos locais onde a lib vai procurar pelo dado (Local Cache, Memcached, DB). Por exemplo, caso metade dos posts estiver no cache, a lib vai tentar pegar a outra metade no banco.

Aqui tem uma apresentação que ajuda a explicar a idéia: PPT.

Sweet! :)

Performance /ou: "Boa" Velocidade

Posted: 21 de fev. de 2008 | . David Lojudice Sobrinho | tags: , 0 comentários

A maioria dos sistemas que trabalhei eram de apoio ao negócio (daqueles que mudam pouco, apenas uma vez por dia). Em todos eles um dos requisitos, normalmente formalizado, era “boa velocidade de acesso à informação”, “tempo de resposta pequeno” ou algo parecido. Porém, “boa” e “pequeno” não foram quantificados.

A meu ver, qualquer que seja o sistema, ele deve ter “boa velocidade” e “tempo de resposta pequeno”. Se isto não esta quantificado, exemplo: “tempo de resposta menor que 150ms”, então presume-se que o sistema deva responder em tempos humanamente aceitáveis, principalmente quando se trata de UI.

Mas o fato de não haver quantificação estimulou alguns desenvolvedores a quebrar a flexibilidade do sistema (padrões, camadas, abstrações ou qualquer outro conceito que a arquitetura de software pudesse ter), em troca de um único benefício: performance.

Será que foi uma boa troca? Sim, isto é uma troca. Não é possível ter uma arquitetura flexível do ponto de vista de negócio e ao mesmo tempo ter a melhor performance.

Mas como escolher corretamente?

Se você já desenvolveu qualquer módulo que seja, sabe que algumas funções são mais usadas do que outras. Algumas são mais custosas (em performance) do que outras. No atual sistema que desenvolvo, tenho a seguinte tabela em mente:

Custo Performance
Freqüência de Uso da FunçãoBaixoMédioAlto
BaixoFFF
MédioFFF
AltoFP/FP

F = Flexibilidade
P = Performance

Como cada caso é um caso, o ajuste desses valores depende de algumas variáveis: tipo do sistema, disponibilidade de recursos computacionais, número de usuários, etc.

No meu caso, como mostra a tabela acima, prefiro escolher por flexibilidade. Mas conforme o ambiente muda, basta alterar o sistema, já que é mais fácil tirar flexibilidade e focar em performance do que o caminho contrário.

Agora, se você não sabe a freqüência de uso, então esqueça performance!

Will my app scale when millions of people start using it?

Ya know
what? Wait until that actually happens. If you've got a huge number of people overloading your system then huzzah! That's one swell problem to have. The truth is the overwhelming majority of web apps are never going to reach that stage.
And even if you do start to get overloaded it's usually not an allor-nothing issue. You'll have time to adjust and respond to the problem. Plus, you'll have more real-world data and benchmarks after you launch which you can use to figure out the areas that need to be addressed.

http://gettingreal.37signals.com/ch04_Scale_Later.php


A sensibilidade da escolha, hora pendendo por flexibilidade, hora por performance, é uma das chaves para conseguir um bom sistema.

ps: os últimos textos estão perdendo a acides por motivos de preguiça. Prometo o tom de crítica volta assim que a lentidão mental passar.

Modularização 2 /ou: Não estou sozinho nessa....

Posted: 11 de jan. de 2008 | . David Lojudice Sobrinho | tags: , 0 comentários

Hoje, coincidentemente, dois posts me chamaram atenção por tratarem dos assuntos relacionados ao meu post anterior.

Acabei de assistir o video "Framework Engineering: Architecting, Designing, and Developing Reusable Libraries" (em inglês) do Krzysztof Cwalina. Recomendo fortemente para os arquitetos de plantão.

Interessante que ele fala sobre Layers, Componentização, Dependências, Abstração, etc. Parece que ontem não falei tanta bobagem...

Aliás, ele está lançando a segunda edição do "Framework Design Guidelines". Leitura obrigatória para arquitetos .Net .

E nosso querido LLBLGen Man, Frans Bouma, fez mais uma vez um post excelente. Começando o blog com:

DISCLAIMER: this is a bitter post. If you get offended by this post, I'm sorry, though I had to write this. If you want to leave a comment, please do so, but as it's my blog, I'll remove comments which I think are inappropriate.
Com essa introdução não tive outra opção senão ler o post. No post ele reclama de como as pessoas de determinado group list (ALT.NET) são cegas e pouco criticas em relação ao que é colocado sobre Métodos Ágeis. O post é um misto de desabafo e analise. Mas vale pelos momentos de reflexão, principalmente sobre procurar os “porques” e sobre senso critico. Por exemplo, olha o que ele diz sobre Separation of Concerns:

If you say "You should use the principle of Separation of Concerns (SoC)", what exactly do you mean? It's not as obvious as it sounds. Please read the paper N Degrees of Separation: Multi-Dimensional Separation of Concerns by Tarr, Ossher, Harrison. It's an example how some 'technique' isn't as general usable as you might think: one has to think it through.
E ele termina o post assim:

Always keep asking Why, and search for fundamental answers. Only then you'll gain wisdom, instead of just knowledge.
Vale a pena ler ou não?

E pra finalizar o momento links, mesmo não estando relacionado com o post de ontem, um amigo me recomendou o blog Fragmental do Phillip Calçado "Shoes". Ótima leitura, tando em inglês como português.

Modularização /ou: Tudo sobre interesses e verdades...

Posted: 10 de jan. de 2008 | . David Lojudice Sobrinho | tags: , 0 comentários

Assim como eu, acredito que você, caro desenvolvedor, deve ter ouvido zilhares de vezes que software deve ser construído em módulos, componentes, bibliotecas ou qualquer outro nome para as subdivisões de código fonte. Isso levaria o software a ter maior qualidade. Mas na prática me parece contraditório. Já vi softwares com vários módulos e bibliotecas e isso não fizeram deles softwares bem construídos.

Mas e ai? Qual era o problema?

Pensando recentemente sobre o assunto, e armado agora com outros conceitos, vi que modularizar (componentizar, etc.) um software é o “como”, mas não o “porque”. Explico:

Pensando sobre isso vi que o “porque” da modularização é o que recentemente tenho visto por ai como “Separation of Concern” (Separação de Interesse) e “One Source of Truth” (Uma [única] Fonte de Verdade). Primeiro, Separation of Concern, é fazer com que o módulo, uma classe (no nível mais baixo) ou um serviço no modelo SOA (no nível mais elevado), seja responsável por um motivo único. Um sistema de recebimentos não deve ser responsável por controlar comissões, por exemplo. Assim como uma classe de business não deve saber como fazer uma chamada ao banco ou abrir um socket TCP/IP. E por ai vai...

E por que separar dessa maneira? Por um único motivo: One Source of Truth. Se a verdade, ou melhor, a maneira como faço algo, reside em apenas um lugar, de maneira atômica, eu posso mudar essa verdade e todos vão segui-la. Agora se tenho mais de uma maneira de fazer algo, qual delas é a verdadeira? Isso me lembra um professor que costumava dizer “se eu tenho um relógio eu sei que horas são, se tenho dois, já não sei mais”.

Por mais que Separation of Concern e One Source of Truth possa parecer redundante por se tratar de modularizacao, acho importante reforçar que o “como” é conseqüência do “porque”. Ou seja, os módulos que vi sendo construídos de maneira errada, com códigos duplicados, sem clara divisão de responsabilidade entre eles, estavam apenas fazendo o que lhes foi ensinado, que era modularizar, mas esqueceram de falar o porque fazer daquela maneira. E novos conceitos como “baixo acoplamento”, Inversion of Control ou Dependency Injection, etc. não ajudam a melhorar essa situação se o conceito básico não estiver lá.

Mas fazer modularização do zero usando Separation of Concern e One Source of Truth de maneira eficiente não é fácil. Não é fácil porque envolve a exclusiva capacidade humana de abstrair. E abstrair de maniera correta é uma tarefa tão difícil que não seria uma má idéia um cientista da computação ter 2 anos de filosofia na faculdade só para começar a ter boa capacidade de abstração.

Mas dá para fazer boa modularização sem quebrar a cabeça. Aprenda “patterns”. Design Patters, Enterprise Patterns, etc. Se a sua verdade absoluta não e estiver lá, pelo menos você sabe que alguém já errou por você.

Workflow Foundation /ou: Porque existem Comandos e comandos!

Posted: 13 de dez. de 2007 | . David Lojudice Sobrinho | tags: , 3 comentários

Estou ansioso para por a mão no VS2008 e seus novos recursos, com destaque ao Workflow Foundation e seu designer. Para as minhas aplicações o WF se aplica perfeitamente, criando uma camada de abstração que fica faltando hoje: a de comandos! Se você é fã do Design Patterns (GOF) como eu, já sabe do que eu estou falando. Mas para tentar explicar melhor, vou contar minha historinha…

Hoje, usamos a seguinte arquitetura nos nossos projetos:

User Layer: Páginas ASPX, Serviços, WinForms, etc., que fazem chamadas ao nosso “Core”

Business Layer: Core - Aqui encontra-se os Managers. Só e somente os Managers sabem como fazer as coisas. Por definição nossa, os Managers só podem chamar uma classe “Proxy” ou evocar o nosso ORM e suas “Entities”.

Data Layer: Usamos o ORM (70%), nosso querido LLBLGen, ou SQL (5%) ou Proxies (25%) (aka Facade), que interconecta com outros sistemas.

A boa e velha “três camadas”. Não requer prática nem tão pouco habilidade.

Mas uma coisa me incomoda. Os Managers são formados por métodos simples e atômicos (SaveCustomer, GetAccount, PayMoney, etc.). Não tenho Manages ou outro tipo de classe que implementam o uma ação, uma intenção. Uma ação é mais complexa que um método do Manager. Na verdade é o agrupamento deles. Esse agrupamento / intenção / ação é conhecido como Command Pattern.

Exemplo: Toda vez que o usuário emite uma nota fiscal, o sistema notifica o sistema de estoque e logística. Se cada módulo do sistema tem seu Manager, imagino algo assim:

Empresa.Financeiro.NotaFiscalManager.Adicionar(notaFiscal)
foreach (NotaFiscalItemEntity notaFiscalItem in notaFiscal.Items)
{
Empresa.Estoque.EstoqueManager.Reduzir(notaFiscalItem)
}
Empresa.Logistica.EntregaManager.NotificaEntrega(notaFiscal)

Esse agrupamento de código é a ação de emitir uma nota fiscal. Mas onde colocar esse código? Hoje, tenho duas opções: Caso a ação esta amarrada diretamente à UI, fica lá mesmo. Ou no caso de ser reutilizada, criaria um método na classe NotaFiscalManager, algo NotaFiscalManager.Emitir().

A primeira opção é ruim, pois a inteligência do negócio está na camada de abstração errada. A segunda opção não é tão ruim, mas ainda assim está na classe errada, que não deveria conhecer os outros domínios/módulos dos sistemas.

Uma ultima opção, que não uso hoje, seria criar uma classe Empresa.Commands.EmitirNotaFiscalCommand. Aqui seria o lugar perfeito, no meu ver, para o código acima. Atenção ao fato do namespace ao qual a classe pertence ser Commands, que por definição é permitido chamar vários Managers de domínios distintos.

Mas já que o WF está ai, por que não criar um fluxo de sistema que fizesse o mesmo que EmitirNotaFiscalCommand? E agora com a possibilidade de ver o fluxo de maneira visual!

História contada, livros encomendados, opiniões bem vindas.

update: ver também BPM

Padrão de Código /ou: Arte de Programar

Posted: 12 de dez. de 2007 | . David Lojudice Sobrinho | tags: , 0 comentários

"O importante não é o conteúdo, mas sim a forma."

Ter um padrão de código é fundamental no entendimento do código dos projetos.

Estou disponibilizando o documento usado internamente aqui na equipe.

http://docs.google.com/View?docid=adb7s3pk2jg9_18fnm7z3&pli=1

Porque escrever um código legível é uma arte.... mas como toda arte, pode ser aprendida.