Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I stop a specific agent in Clojure? When are their states garbage-collected?

Tags:

clojure

agents

If an agent is working through its queue in the background in Clojure, how can I stop it without stopping all agents?

When I am finished with an agent and I let it fall out of scope AND it finishes working on its queue, is it garbage collected along with its final state?

like image 646
Ben Englert Avatar asked Jan 05 '11 21:01

Ben Englert


1 Answers

manage agents as data not threads

an agent is a data structure that is associated with a pool of threads and a queue of events. when events are available for agents then the threads in that pool take turns doing work on the agents until the thread pool gets full or the event (work) queue becomes empty. an agent is garbage collected when the last reference to it goes out of scope.

if you bind a top level var to it it will stick around forever.

(def foo (agent {}))  

if you bind it to a name in a function it will be GCd at the end of that function

(defn foo [] 
  (let [foo (agent {})] 
    (send do-stuff foo))) 

I don't see a direct message for canceling the work queue of an agent though you may be able to hack this by setting a validator on the agent that always returns false. This could cause the agent to stop working and wait for the agent error to be cleared.

if you want to kill an agent from code outside of the lexical scope where the agent was created you will need to store the agent in some mutable structure like an atom so you can remove the reference to the agent to allow it to be 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
like image 151
Arthur Ulfeldt Avatar answered Oct 16 '22 19:10

Arthur Ulfeldt