Permalink
Browse files

Moved Activator and Clock at the beginning of the file.

  • Loading branch information...
1 parent 98bb4fb commit ddb03abc556d04e754a8b86730b7d17deb61bbba @rik0 committed Nov 21, 2012
Showing with 149 additions and 149 deletions.
  1. +149 −149 pynetsym/simulation.py
View
298 pynetsym/simulation.py
@@ -37,6 +37,155 @@
'Clock'
]
+class Activator(core.Agent):
+ """
+ The Activator chooses what happens at each step of the simulation.
+
+ The tick method is called at each simulation step. The default behavior
+ is to call choose_node to select a random node and send it an activate
+ message.
+
+ tick, simulation_ended and choose_node are meant to be overrode by
+ implementations.
+ """
+ name = 'activator'
+ activator_options = {}
+
+ def __init__(self, graph, **additional_arguments):
+ activator_options = gather_from_ancestors(
+ self, 'activator_options')
+ activator_arguments = extract_subdictionary(
+ additional_arguments,
+ activator_options)
+ self.graph = graph
+ vars(self).update(activator_arguments)
+
+ def activate_nodes(self):
+ node_ids = self.nodes_to_activate()
+ for node_id in node_ids:
+ self.send(node_id, 'activate')
+
+ def destroy_nodes(self):
+ self.dying_nodes = self.nodes_to_destroy()
+ for node_id in self.dying_nodes:
+ # notice: this is "beautifully" queued
+ self.send(node_id, 'kill')
+
+ def create_nodes(self):
+ to_create = self.nodes_to_create()
+ node_ids = SequenceAsyncResult(
+ [self.send(NodeManager.name, 'create_node',
+ cls=node_class, parameters=node_parameters)
+ for node_class, node_parameters in to_create])
+ self.fresh_nodes = node_ids.get()
+
+ def simulation_ended(self):
+ return self.send(NodeManager.name, 'simulation_ended').get()
+
+ def tick(self):
+ self.destroy_nodes()
+ self.create_nodes()
+ self.activate_nodes()
+
+ def signal_termination(self, reason):
+ self.send(TerminationChecker.name, 'require_termination',
+ reason=reason).get()
+
+ def nodes_to_activate(self):
+ return [self.graph.random_selector.random_node()]
+
+ def nodes_to_destroy(self):
+ return {}
+
+ def nodes_to_create(self):
+ return {}
+
+
+class SyncActivator(Activator):
+ """
+ This Activator variant always waits for the nodes to acknowledge the
+ activate message, thus making it essentially serial.
+ """
+
+ def activate_nodes(self):
+ node_ids = self.nodes_to_activate()
+ for node_id in node_ids:
+ done = self.send(node_id, 'activate')
+ done.get()
+
+
+class BaseClock(core.Agent):
+ name = 'clock'
+ activator_can_terminate = false()
+ clock_loop_g = Instance(gevent.Greenlet)
+
+ active = true(transient=True)
+ observers = List
+
+ def register_observer(self, name):
+ self.observers.append(name)
+
+ def unregister_observer(self, name):
+ self.observers.remove(name)
+
+ def join(self):
+ try:
+ return super(BaseClock, self).join()
+ except LinkedCompleted:
+ return True
+
+ def start_clock(self):
+ """
+ Here the clock actually starts ticking.
+ """
+ self.active = True
+ self.clock_loop_g = gevent.spawn_link(self.clock_loop)
+
+ def positive_termination(self, originator, motive):
+ if originator == TerminationChecker.name:
+ self.clock_loop_g.join()
+
+ def clock_loop(self):
+ raise NotImplementedError()
+
+ def send_tick(self):
+ for observer in self.observers:
+ self.send(observer, 'ticked')
+ return self.send(Activator.name, 'tick')
+
+ def send_simulation_ended(self):
+ return self.send(Activator.name, 'simulation_ended')
+
+ def simulation_end(self):
+ self.active = False
+ self.send_simulation_ended().get()
+
+ def ask_to_terminate(self):
+ return self.send(
+ termination.TerminationChecker.name, 'check',
+ requester=self.name)
+
+
+class AsyncClock(BaseClock):
+ remaining_ticks = Int
+
+ def clock_loop(self):
+ while self.remaining_ticks:
+ self.send_tick()
+ self.remaining_ticks -= 1
+ else:
+ self.simulation_end()
+
+
+class Clock(BaseClock):
+ def clock_loop(self):
+ while self.active:
+ waiting = self.send_tick()
+ waiting.get()
+ should_terminate = self.ask_to_terminate()
+ self.active = not should_terminate.get()
+ else:
+ self.simulation_end()
class Simulation(object):
"""
@@ -316,152 +465,3 @@ def motive(self):
return self.termination_checker.motive
-class Activator(core.Agent):
- """
- The Activator chooses what happens at each step of the simulation.
-
- The tick method is called at each simulation step. The default behavior
- is to call choose_node to select a random node and send it an activate
- message.
-
- tick, simulation_ended and choose_node are meant to be overrode by
- implementations.
- """
- name = 'activator'
- activator_options = {}
-
- def __init__(self, graph, **additional_arguments):
- activator_options = gather_from_ancestors(
- self, 'activator_options')
- activator_arguments = extract_subdictionary(
- additional_arguments,
- activator_options)
- self.graph = graph
- vars(self).update(activator_arguments)
-
- def activate_nodes(self):
- node_ids = self.nodes_to_activate()
- for node_id in node_ids:
- self.send(node_id, 'activate')
-
- def destroy_nodes(self):
- self.dying_nodes = self.nodes_to_destroy()
- for node_id in self.dying_nodes:
- # notice: this is "beautifully" queued
- self.send(node_id, 'kill')
-
- def create_nodes(self):
- to_create = self.nodes_to_create()
- node_ids = SequenceAsyncResult(
- [self.send(NodeManager.name, 'create_node',
- cls=node_class, parameters=node_parameters)
- for node_class, node_parameters in to_create])
- self.fresh_nodes = node_ids.get()
-
- def simulation_ended(self):
- return self.send(NodeManager.name, 'simulation_ended').get()
-
- def tick(self):
- self.destroy_nodes()
- self.create_nodes()
- self.activate_nodes()
-
- def signal_termination(self, reason):
- self.send(TerminationChecker.name, 'require_termination',
- reason=reason).get()
-
- def nodes_to_activate(self):
- return [self.graph.random_selector.random_node()]
-
- def nodes_to_destroy(self):
- return {}
-
- def nodes_to_create(self):
- return {}
-
-
-class SyncActivator(Activator):
- """
- This Activator variant always waits for the nodes to acknowledge the
- activate message, thus making it essentially serial.
- """
-
- def activate_nodes(self):
- node_ids = self.nodes_to_activate()
- for node_id in node_ids:
- done = self.send(node_id, 'activate')
- done.get()
-
-
-class BaseClock(core.Agent):
- name = 'clock'
- activator_can_terminate = false()
- clock_loop_g = Instance(gevent.Greenlet)
-
- active = true(transient=True)
- observers = List
-
- def register_observer(self, name):
- self.observers.append(name)
-
- def unregister_observer(self, name):
- self.observers.remove(name)
-
- def join(self):
- try:
- return super(BaseClock, self).join()
- except LinkedCompleted:
- return True
-
- def start_clock(self):
- """
- Here the clock actually starts ticking.
- """
- self.active = True
- self.clock_loop_g = gevent.spawn_link(self.clock_loop)
-
- def positive_termination(self, originator, motive):
- if originator == TerminationChecker.name:
- self.clock_loop_g.join()
-
- def clock_loop(self):
- raise NotImplementedError()
-
- def send_tick(self):
- for observer in self.observers:
- self.send(observer, 'ticked')
- return self.send(Activator.name, 'tick')
-
- def send_simulation_ended(self):
- return self.send(Activator.name, 'simulation_ended')
-
- def simulation_end(self):
- self.active = False
- self.send_simulation_ended().get()
-
- def ask_to_terminate(self):
- return self.send(
- termination.TerminationChecker.name, 'check',
- requester=self.name)
-
-
-class AsyncClock(BaseClock):
- remaining_ticks = Int
-
- def clock_loop(self):
- while self.remaining_ticks:
- self.send_tick()
- self.remaining_ticks -= 1
- else:
- self.simulation_end()
-
-
-class Clock(BaseClock):
- def clock_loop(self):
- while self.active:
- waiting = self.send_tick()
- waiting.get()
- should_terminate = self.ask_to_terminate()
- self.active = not should_terminate.get()
- else:
- self.simulation_end()

0 comments on commit ddb03ab

Please sign in to comment.