Quero passar um formulário para ser avaliado para um pool de threads de destino como um futuro por meio da biblioteca claypoole em clojure.
Tentei passar o corpo de uma função para um pool de threads e esperava que esse corpo fosse avaliado em uma thread em vez de inline.
O código que tenho é parecido com este:
(defn in-thread [thread & body] (claypoole/future thread body))
Que é chamado assim:
(defonce pool (claypoole/threadpool 20))
(defn do-something [pool]
(in-thread pool
(Thread/sleep 5000)
(println "foo")))
Depois de alguns testes, cheguei à conclusão de que isso body
está sendo avaliado quando chamo in-thread
, fazendo com que minha solução inteira não faça nada significativo. Sei que há algum tipo de conceito básico que estou esquecendo, mas toda vez que tento olhar para macros minha cabeça começa a girar.
Como eu transformaria a in-thread
função em uma macro que passa o corpo para o pool de threads para execução, em vez do resultado?
Quando você usa uma função - isto é, uma construção criada com
defn
/fn
- todos os seus argumentos serão avaliados antes que a função em si seja chamada. Então, no seu caso, ain-thread
função é chamada com os resultados de(Thread/sleep ...)
e(println ...)
, e ambos sãonil
.Para passar formulários sem realmente avaliá-los, você precisa citá-los e usá-los
eval
mais tarde ou usar uma macro, que é uma abordagem muito mais comum.No seu caso, seria suficiente substituir a definição de
in-thread
por:No entanto, observe que ele se torna apenas um wrapper
claypoole/future
que não faz nada por si só. Eclaypoole/future
ele próprio já é uma macro - você nem precisa dein-thread
! Tudo o que você precisa já está implementado porclaypoole/future
, então você pode usar apenas isto: