Ejemplo n.º 1
0
class StartupDaemon :
    def __init__(self, phys_id) :
        self._event_api = EventAPI()
        self._event_api.start()
        self._phys_id = phys_id
        self._running_pids = set([])
        self._running = True

    def _on_startup(self, event) :
        self.terminate_all()
        self._event_api.unsubscribe_all(StartupEvent)
        self._event_api.subscribe(StartSimulationEvent, self._on_sim_start)
        self._event_api.publish(AckStartupEvent(self._phys_id))
        self._world = event.get_world()

    def terminate_all(self) :
        for p in self._running_pids :
            p.kill()
        self._running_pids.clear()

    def _start_entity_process(self, entity) :
        print 'Starting subprocess for uid %s' % entity.get_uid()
        p = subprocess.Popen(('python entity.py %s %s' % (entity.pickle(), self._world.pickle())).split(' '))
        self._running_pids.add(p)

    def _on_sim_start(self, event) :
        local_entities = event.get_mapping()[self._phys_id]
        for e in local_entities :
            self._start_entity_process(e)

    def start(self) :
        self._event_api.subscribe(StartupEvent, self._on_startup)
        self._event_api.subscribe(StopSimulationEvent, self._restart)
        self._event_api.get_thread().join()
#        while self._running :
#            pass

    def _restart(self, event) :
        self.terminate_all()
        self._event_api.clear_subscriptions()
        self._running_pids = set([])

        print 'Got stop event.  State cleared.'
        self._event_api.subscribe(StartupEvent, self._on_startup)
        self._event_api.subscribe(StopSimulationEvent, self._restart)

    def stop(self) :
        self._event_api.stop()
        self.terminate_all()
        self._running = False
Ejemplo n.º 2
0
class Simulation :
    def __init__(self, world_inst) :
        self._event_api = EventAPI()
        self._event_api.start()
        self._startup_acks = set([])
        self._world = world_inst

    def get_world(self) :
        return self._world

    def _on_ack_startup(self, event) :
        print 'Got ack startup:', event.get_daemon_id()
        self._startup_acks.add(event.get_daemon_id())

    def start(self, wait) :
        self._event_api.subscribe(AckStartupEvent, self._on_ack_startup)
        # Do *NOT* change self._world after this point.  It is pickled here and sent to other phy nodes
        self._event_api.publish(StartupEvent(self._world))
        
        time.sleep(wait)
        if len(self._startup_acks) > 0 :
            print 'Got %s startup acks.  Starting simulation.' % (len(self._startup_acks),)
            self._event_api.unsubscribe_all(AckStartupEvent)

            #TODO: Fix the division
            entities_per_phy_node = int(len(self._world.get_entities()) / float(len(self._startup_acks)))
            print '    allocating %s entities per node' % entities_per_phy_node
            mapping = {}
            to_allocate = list(self._world.get_entities())
            for i, phy in enumerate(list(self._startup_acks)) :
                alloc = to_allocate[i*entities_per_phy_node:(i+1)*entities_per_phy_node]
                print i, alloc
                if len(alloc) == 0 :
                    break
                mapping[phy] = alloc

            self._world.initialize()
            self._event_api.publish(StartSimulationEvent(mapping))
        else :
            print 'Got no startup acks.  Quitting...'

    def stop(self) :
        self._event_api.publish(StopSimulationEvent())
        self._event_api.stop()