def before_request(): """ Before each client request is processed, refresh the session. If the session is new, instantiate a BOS for the client. Note: Each session gets its own sandbox. I.e. it's own BOS and sims. so that each web client can have it's own "sandbox" BOS. """ global bos_sessions def refresh_sess(): bos_web.permanent_session_lifetime = timedelta(minutes=WEB_EXPIRE) flask.session.permanent = True flask.session.modified = True # TODO: Test timeout # If session exists, refresh it to prevent expire bos_ID = flask.session.get('bos_id') if bos_ID and bos_sessions.get(bos_ID): # print('Request from existing client received: ' + str(bos_ID)) # debug refresh_sess() # Else, init a new BOS & flag session as dirty so change is registered. # The association is necessary because the BOS obj is not serializable. else: # Init a new boss associated with a random 16 bit ID bos_ID = randrange(65536) bos_sessions[bos_ID] = BOS() bos_sessions[bos_ID].start() sleep(.5) # Ample time to start # Associate session with it's BOS flask.session['bos_id'] = bos_ID refresh_sess() bos_log.info('New client session started: ' + str(bos_ID))
def run(self): """ Checks msg broker for new status msgs every REFRESH_TIME sec. """ bos_log.info('Starting Sandbox...') self.broker_sim.start() self.track_sim.start() bos_log.info('BOS Started.') while True: # Fetch the next available status msg, if any msg = None try: msg = self.msg_client.fetch_next_msg(BOS_EMP) except Queue.Empty: bos_log.info('Msg queue empty.') except Exception: bos_log.warn('Could not connect to broker.') # Process loco status msg. Msg should be of form given in # docs/app_messaging_spec.md, Msg ID 6000. if msg and msg.msg_type == 6000: try: locoID = msg.payload['loco'] location = Location(msg.payload['milepost'], msg.payload['lat'], msg.payload['long']) active_conns = eval(msg.payload['conns']) # evals to dict # Eiter reference or instantiate loco with the given ID loco = self.track.locos.get(locoID) if not loco: loco = Loco(locoID, self.track) # Update the BOS's loco object with status msg params loco.update(msg.payload['speed'], msg.payload['heading'], msg.payload['direction'], location, msg.payload['bpp'], active_conns) # Update the last seen time for this loco self.track.set_lastseen(loco) bos_log.info('Processed status msg for ' + loco.name) except KeyError: bos_log.error('Malformed status msg: ' + str(msg.payload)) elif msg: bos_log.error('Fetched unhandled msg type: ' + str(msg.msg_type)) sleep(REFRESH_TIME)
def main_set_sessionvar_async(): """ Accepts a key value pair via ajax and updates session[key] with the given value. Key must be in PUBLIC_SESSVARS, for safety. """ try: key = flask.request.json['key'] newval = flask.request.json['value'] if key in PUBLIC_SESSVARS: flask.session[key] = newval bos_log.info('Set: ' + key + '=' + str(newval)) # Update time sim if that var was updated if key == 'time_iplier': try: bos_sessions[flask.session['bos_id']].set_tplier(newval) except: return 'BOS association failure. Try restarting your browser.' else: return 'ERROR' return 'OK' except Exception as e: bos_log.error(e) return 'ERROR: + ' + str(e)