CPL 2016, week 14 Clojure agents Oleg Batrashev Institute of - - PowerPoint PPT Presentation

cpl 2016 week 14
SMART_READER_LITE
LIVE PREVIEW

CPL 2016, week 14 Clojure agents Oleg Batrashev Institute of - - PowerPoint PPT Presentation

CPL 2016, week 14 Clojure agents Oleg Batrashev Institute of Computer Science, Tartu, Estonia May 9, 2016 Overview Last weeks Clojure language core Immutable data structures Clojure simple state and design Software


slide-1
SLIDE 1

CPL 2016, week 14

Clojure agents Oleg Batrashev

Institute of Computer Science, Tartu, Estonia

May 9, 2016

slide-2
SLIDE 2

Overview

Last weeks

◮ Clojure language core ◮ Immutable data structures ◮ Clojure simple state and design ◮ Software transactional memory (STM)

This week

◮ Agents in Clojure

slide-3
SLIDE 3

Clojure agents 81/90

  • Scope

◮ Agent programming is a term used in many contexts

◮ concurrent entities ◮ intelligent agents ◮ agents with goals ◮ cooperating agents ◮ etc

We are primarly interested in properties arising from concurrency.

slide-4
SLIDE 4

Clojure agents 82/90

  • General

◮ Agent in Clojure is a reference type (mutable holding state)

that can be changed by sending it an action (function)

◮ uncoordinated – independent of changes of other agents ◮ asynchronous – changes are away from the thread that

schedules an action

◮ immediate return: no wait for the completion of an action

◮ 2 characteristics of Clojure agents

◮ I/O may be used safely with agents unlike in STM ◮ agents are STM aware

slide-5
SLIDE 5

Clojure agents 83/90

  • Agent mechanics

◮ reading agent’s state deref/@ – non-blocking ◮ (send a action-fn & args) – send agent a an action

◮ action-fn takes agent state, args and returns new agent state ◮ as with (apply action-fn state-of-agent args)

◮ actions are stored into the queue for each agent

◮ processed sequentially by threads, mutating its state ◮ thread from one of two thread pools

◮ thread pools

◮ fixed size – actions delivered from send ◮ unlimited size – actions delivered from send-off ◮ needed for blocking IO

slide-6
SLIDE 6

Clojure agents 84/90

  • Agent example

◮ agent with the state of single integer – counter ◮ await is only needed to show the result, in general agents

must be asynchronous

(def counterAgent (agent 0)) (send counterAgent inc) (send counterAgent (fn [state] (+ state 3))) (send counterAgent (fn [state msg] (+ state msg )) 10) (await counterAgent ) (println @counterAgent )

slide-7
SLIDE 7

Clojure agents 85/90

  • Diagram

◮ black actions are CPU bound (send)

◮ threads t2 and t3 are from fixed size pool ◮ threads t18 and t9 are from unbounded pool

◮ for single agent all actions still are sequential, although may be

running in different threads

◮ *agent* is the agent currently run by the thread

slide-8
SLIDE 8

Clojure agents 86/90

  • Semantics of agents

◮ agents != threads

◮ usually number of threads <‌< number of agents ◮ agents still run concurrently -> green threads

◮ not as in typical Remote Procedure Call (RPC), where

◮ allow to enter multiple threads instead of one ◮ state is not declarative

◮ reduce – value from a list + operation = action (fun + args)

◮ intermediate reduction values = states

◮ await/await-for – wait for all actions from current thread

to complete

slide-9
SLIDE 9

Clojure agents 87/90

  • Errors in agents

◮ agent on exception goes to error state

◮ agent-error returns exception or nil ◮ sending actions to agent throw the exception

◮ (restart-agent agent new-state & options) – clears error state

◮ :clear-actions also clears the action queue

◮ when creating an agent

◮ :error-mode, either :fail (default) or :continue ◮ agent is not failed on ’continue’ mode ◮ :error-handler – provide function that is called in ’continue’

mode

◮ set-error-mode!, set-error-handler!

slide-10
SLIDE 10

Clojure agents 88/90

  • IO/STM/nested sends

◮ synchronization point for IO

◮ exclusive access to file,socket,stream ◮ others schedule actions on this agent

◮ unlike refs/atoms that should avoid side-effects because of

possible transaction restarts

◮ STM aware: any actions sent within a transaction are held

until it commits

◮ nested send: any actions sent within an agent are withheld

until current action is finished

slide-11
SLIDE 11

Clojure agents 89/90

  • Watches

◮ watch the reference (atom, ref, or agent) ◮ watch – function that is called when the reference is changed (defn watchFun [key identity

  • ld new]

(println identity "changed value from " old "to" new )) (def counterAgent (agent 0)) (add -watch counterAgent :mywatch watchFun) (send counterAgent inc) (send counterAgent (fn [state] (+ state 3))) (send counterAgent (fn [state msg] (+ state msg )) 10)

◮ identity is atom, ref, or agent ◮ key allows to attach several watch functions and detach them

◮ identity may already have different value, when watch function

is called

slide-12
SLIDE 12

Clojure agents 90/90

  • Example: log the game

◮ Add watchers to game atoms, refs ◮ watchers send states to logging agent(s)

◮ watcher callback is called in the transaction thread,

presumably before releasing the ref

◮ correct order of ref states are queued to the agent(s)

◮ logging game changes and not states requires interception of

game methods

◮ must be done (!) in the transaction because of possible

transaction restarts

◮ log action is delayed until commit