Como posso parar um agente específico no Clojure? Quando seus estados são coletados de lixo?
Pergunta
Se um agente está trabalhando em sua fila em segundo plano em Clojure, como posso parar sem parar todos os agentes?
Quando termino com um agente e deixei que ele caia do escopo e termina de trabalhar em sua fila, ele é coletado de lixo junto com seu estado final?
Solução
Gerenciar agentes como dados não threads
um agente é um estrutura de dados que está associada a um pool de threads e uma fila de eventos. Quando os eventos estão disponíveis para os agentes, os threads nesse pool se revezam trabalhando nos agentes até que o pool de threads fique cheio ou a fila do evento (trabalho) fique vazia. Um agente é coletado de lixo quando a última referência a ele sai do escopo.
Se você vincular um nível superior a ele, ele permanecerá para sempre.
(def foo (agent {}))
Se você o vincular a um nome em uma função, será GCD no final dessa função
(defn foo []
(let [foo (agent {})]
(send do-stuff foo)))
Não vejo uma mensagem direta para cancelar a fila de trabalho de um agente, embora você possa invadir isso por Definir um validador no agente que sempre retorna false. Isso pode fazer com que o agente pare de funcionar e aguarde a limpeza do erro do agente.
Se você deseja matar um agente de código fora do escopo lexical, onde o agente foi criado, precisará armazenar o agente em alguma estrutura mutável como um átomo para que você possa remover a referência ao agente para permitir que ele seja GCD.
(def my-agent (atom nil)) ;a persistent name for a transient agent
(swap! my-agent (make-new-agent)) ;create the agent
(send do-stuff @my-agent) ;use the agent
(swap! my-agent nil) ;clean up