Space4J x Prevayler

11 respostas
N

Alguém deu uma olhada no Space4J ???

http://www.smartjava.com.br/artigo3.jsp

Parece ser uma versão simplificada do Prevayler. A explicação está bem clara e o código também. Quais seriam as desvantagens em relação ao prevayler?

Inté,

Eduardo

11 Respostas

cv1

No fim das contas, sao duas implementacoes simples do mesmo conceito, que nao eh menos simples. Vou brincar com o Space4J numa folguinha qualquer ai e dou minhas opinioes mais tarde. :smiley:

Pelo que eu pude ver logo de cara, a API eh um pouquinho de nada mais “complicada” do que a do Prevayler, mas deve ser soh coisa de primeira impressao.

mcampelo

Na verdade o Space4J é 100% baseado no Prevayler, segundo palavras do próprio autor.

As vantagens ficam por conta de:

  • API MUITO mais simples
  • Load Balance

Vale a pena testar!

saoj

Como eu falo no artigo, eu fiz o Space4J para:

  • Enteder claramente a teoria por trás do prevayler. (Não foi fácil mas acho que consegui!)

  • Criar uma API mais simples, clara e acessível. (Recebi alguns feedbacks positivos. Aguardo mais opiniões!)

  • Suportar cluster de uma forma totalmente transparente. (Acho que consegui. Vejam a diferença entre PhoneBook e PhoneBookCluster. Quase nenhuma!)

Continuo sem entender algumas coisas e com alguns desafios que provavelmente a galera do prevayler já sabe resolver:

  • Como fazer queries complexas com estruturas de dados?
  • Como fazer alterações pesadas sem engargalar o sistema?
  • Como trabalhar com índices compostos?

Algumas diferenças do Space4J para o Prevayler:

  • Os comandos só são logados se forem executados com sucesso. Se uma CommandException é lançado, o comando não é logado. Por que logar um comando que não executou com sucesso ???

  • Pra que utilizar a classe Clock se eu posso guardar a hora real dentro do objeto (Command) que vai ser serializado ? Essa hora será fixa para sempre!

Qualquer ajuda, crítica, dica ou comentário em relação ao Space4J será bem-vinda.

Um abraço a todos,

Sergio Oliveira Jr.

cv1

OGNL! www.ognl.org :smiley:

Existem dois tipos de alteracoes pesadas: as que envolvem a execucao de milhaaaaaaares de transacoezinhas (processamento de um lote de faturamento, por exemplo), e as que envolvem uma unica transacao complicada (que faz todo tipo de malabarismo com o grafo).

A primeira pode ser melhorada transformando-a em uma unica transacaozona-hiper-mega-grande, que envolve todas as menores, ou usando lazy-loading/lazy-evaluation com sabedoria.

No segundo caso, nao tem muito o que fazer, a nao ser lazy-loading/lazy-evaluation mesmo… ou sera que eu tou bobeando?

Vai da sua biblioteca de collections, nao? Como vc trabalharia com indices compostos usando um HashMap da vida? :slight_smile:

saoj

Parece que Lazy-Loading e Lazy-Evaluation é a chave da questão. Qual a teoria por trás disso ? Existe algum lugar na web com informações teóricas sobre isso para eu me familiarizar ? Alguma coisa no site do prevayler?

Quanto a questão do índice composto também estou por fora. Como eu coloco um índice composto num Map ??? Como crio novos índices num Map? Num banco de dados essas questões são encapsulados para o usuário.

Obrigado pela ajuda CV !!

Sergio Oliveira Junior
www.smartjava.com.br

cv1

Lazy-Loading/evaluation envolvem realizar alguma tarefa de forma “preguicosa”, ou seja, se vc tem 1 milhao de objetos pra carregar, voce finge que carregou, e quando alguem precisar deles voce vai e carrega de verdade.

Eager-Evaluation: UPDATE clientes SET credito=40000 WHERE name=‘carlos’ faz com que o sistema corra por todos os elementos onde name vale ‘carlos’, e atualize o conjunto de dados antes de devolver a resposta. Quando alguem acessa algum elemento que foi modificado, nada de especial acontece.

Lazy-Evaluation: UPDATE clientes SET credito=40000 WHERE name=‘carlos’ faz com que o sistema marque o conjunto “clientes” como modificado, e mais nada. Toda vez que alguem carregar um elemento desse conjunto, o sistema checa as atualizacoes que ocorreram naquele elemento e ainda nao foram feitas, e as faz antes de te devolver o dito cujo.

Claro que esse eh um exemplo bobinho, mas dependendo do tipo de sistema que vc tem, nao ha outro jeito de fazer a coisa com uma performance decente sem recorrer a essa solucao :smiley:

cv1

Eu ainda nao entendi o problema com indices compostos…

MeuObjeto x = // ... Map indiceComposto = new HashMap(); indiceComposto.put(new Tuple(x.getNome(), x.getIdade()), x);

Pra isso basta criar uma classe Tuple (que representa um parzinho de dados… claro, da pra fazer alguma coisinha mais inteligente, mas isso acho que ja resolve 99% dos casos :slight_smile:

saoj

Parece que a questão do índice composto era mais simples do que eu pensava. Valeu pela dica.

Só tem que tomar cuidado quando alterarmos algum campo indexado.

  • Remove o Registro com get
  • Altera o campo
  • Altera o índice
  • Recoloca no Map

Se alterar direto no objeto o índice vai ficar errado, certo?

Isso deve ser óbvio pra vc. Estou apenas escrevendo meus pensamentos. :o

cv1

Pois eh, mas esse problema que vc mostrou nao eh taaaaao chato assim. Tem uma solucao melhor:

x = // objeto qqer Map indice = new HashMap(); indice.put(new Tuple(x, "nome", "idade"), x);

Assim, fica baba: é só colocar inteligencia suficiente na Tuple pra chamar o getNome() e getIdade() sempre que vc precisar comparar a tupla com alguma coisa, ou no equals(), hashCode(), etc e tal. :wink:

urubatan

acho que a melhor solução para isto seria por exemplo a solução utilizada pelo Hibernate para mapeamento de chaves compostas:
criar um objeto para a chave.

por exemplo:
public class TesteKey{
  private String Name(){return name;}
  private String OutroCampo(){return outroCampo;}
}

public class Teste{
   private TesteKey id = new TesteKey();
   ....
}


depois, 
HashMap map = new HashMap();
Teste t = new Teste();

map.put(t.getId(),t);

assim a chave sera alterada quando o nome do teste for alterado, e para facilitar a utilização, pode-se criar um metodo delegate (getNome em teste chamando id.getNome())

o que acham desta abordagem??

cv1

Eh legal, mas nao eh muito OO, urubatan: voce esta introduzindo um treco totalmente alien no seu modelo de objetos só pra satisfazer uma necessidade mundana como indexacao :wink:

A tal da Tuple que eu mostrei nao requer nenhuma gambiarra no teu modelo de objetos a nao ser um parzinho de bons e velhos getters e setters :wink:

Criado 12 de março de 2004
Ultima resposta 12 de mar. de 2004
Respostas 11
Participantes 5