Codemountain, Paulo Suzart's Blog

Clojure + Coherence = Cloherence

leave a comment »

Que combinação! Datagrid Coherence e Clojure! O último post deu uma prévia da abstração simples em cima do Coherence que venho escrevendo. Na verdade não há nada demais nela, a não ser permitir o acesso aos caches e ao processamento de entradas no datagrid de forma mais natural em Clojure. O Cloherence permite duas semânticas, uma que é uma pequena DSL para operações de put, get, remove put de sequencias e processamento no cluster. Vamos a elas:

    (def a1 {:name "Nacho" :breed "Bulldog"})
    (def a2 {:name "Sushi" :breed "Shire"})
    (with-cache "dogs"
        (put-val 1 a1)
        (println (get-val 1)))
;; put a1 into a named cache "dogs" and print the value get from 1
    (with-cache "dogs"
        (put-seq :name (list a1 a2)))
;; put a1 and a2 using :name as key

A função put-seq é interessante pra casos onde alguma função retorna uma lista, e esta pode ser “cacheada” de uma vez. Acontece é que NamedCaches no Coherence são herdeiros de java.util.Map. E isso me deu a ideia de usar a mesma semântica de maps em clojure para tratar os caches Coherence. E ficamos assim:

    (cache-map cats)
    (assoc cats 1 {:name "chico" :breed :unknown})
    (get cats 1) ;; {:name "chico" :breed :unknown}
    (inplace-update cats 1
        (fn [e]
            {:name (.toUpperCase (:name e)) :breed "none"}))
;;put {:name "CHICO" :breed "none"} in the cache with key 1

inplace-update não existe em clojure. A lib oferece uma função update para se assemelhar à função update-in, com a diferença que não permite chaves encadeadas.

A função inplace-update emite um Entry Processor para o grid, e no nó do DataGrid que reside a entrada, a função f é invocada com a entrada passada como argumento. A vantagem é não trazer para a JVM que emite o processador, a entrada encontrada. Escalando isso, livramos a JVM da aplicação de receber possíveis milhares de entradas do cache para efetuar a alteração nas entradas.

Vamos examinar o par EntryProcessor mais a função inplace-update:


;;PProcess é do pacote .core

(deftype CljProcessor
    [f args] java.io.Serializable PProcessor
        (process [this entry]
	(apply f (.getValue entry) args)))

(defn inplace-update
    [cache e-key f & args]
        (with-cache cache
        (process e-key (cloherence.maps.CljProcessor. f args))))

Aqui conto com a função process, com a própria DSL da lib with-cache e com o protocol PProcessor. f de inplace-update é executada assim que a entrada é encontrada, recebendo o valor como primeiro argumento e &args como restante dos argumentos.

Bom, além de divertido, a lib cloherence se propõe a dar uma melhor aderência dos caches Coherence com Clojure. Como próximos passos (não sei se vou fazer, mas pretendo), pretendo implementar inplace-update para várias chaves, iplementar locks e utilizar primitivas de concorrência clojure para algumas operações no cache.

É isso, boa diversão!

@paulosuzart

P.S. Gostaria de um feedback pra saber que nível seria mais adequado abordar Clojure aqui no blog. As vezes sinto que estou escrevendo coisas sem ter feito uma base como fiz com os posts sobre Scala. Quem quiser pode dar um feed.😉

Written by paulosuzart

abril 3, 2011 às 8:00 am

Publicado em clojure, coherence

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: