Advertisement
Guest User

Untitled

a guest
May 28th, 2015
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. (ns mini_projects.actors.actors
  2. (:require [clojure.core.async :as async]))
  3.  
  4. (defprotocol Actor
  5. "Actor interface"
  6. (in-chan [this] "Returns the in-channel of the actor")
  7. (out-chan [this] "Returns the out-channel of the actor")
  8. (get-state [this] "Returns the state of the actor")
  9. (shut-down! [this] "Shuts down the actor"))
  10.  
  11.  
  12. (defn create-actor!
  13. "Creates an actor who processes messages coming to its in-channel.
  14. Its behaviour is a (state,msg)=>(state,[msg]) function.
  15. The output messages are put on its out-channel.
  16. If it's shut down, it will consume and discard incoming messages."
  17. [{:keys [in out init-state behaviour]}]
  18. (let [alive? (atom true)
  19. state (atom init-state)
  20. actor (reify Actor
  21. (in-chan [this] in)
  22. (out-chan [this] out)
  23. (get-state [this] @state)
  24. (shut-down! [this]
  25. (reset! alive? false)
  26. (async/close! out)))
  27. send-msgs! (fn [ms] (async/go (doseq [m ms]
  28. (async/>! out m))))]
  29. (async/go-loop []
  30. (when-let [msg (async/<! in)]
  31. (when @alive?
  32. (let [r (behaviour {:state @state :msg msg})]
  33. (send-msgs! (:msgs r))
  34. (reset! state (:state r))))
  35. (recur)))
  36. actor))
  37.  
  38. (defn keep-and-report
  39. "A valid function for an actor's behaviour. Attaches the message to the state and sends out the state as a message."
  40. [{:keys [state msg]}]
  41. (let [new-state (conj state msg)]
  42. {:state new-state
  43. :msgs [(str "state: " new-state)]}))
  44.  
  45. ;; Create a simple actor
  46. (def actor-1 (create-actor! {:in (async/chan)
  47. :out (async/chan)
  48. :init-state nil
  49. :behaviour keep-and-report}))
  50.  
  51. (def in (in-chan actor-1))
  52. (def out (out-chan actor-1))
  53.  
  54. ;; Print out the messages sent by the actor
  55. (async/go-loop []
  56. (when-let [msg (async/<! out)]
  57. (println (str "Message sent by actor: " msg))
  58. (recur)))
  59.  
  60. (async/>!! in 1)
  61. ;;Message sent by actor: state: (1)
  62. (async/>!! in 2)
  63. ;;Message sent by actor: state: (2 1)
  64. (assert (= [2 1] (get-state actor-1)))
  65.  
  66. (shut-down! actor-1)
  67.  
  68. (async/>!! in 3)
  69. (async/>!! in 4)
  70. ;;shut down actor ignores messages
  71. (assert (= [2 1] (get-state actor-1)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement