def poll(self, session_id): key = '{}:weblab:active:{}'.format(self.key_base, session_id) last_poll = _current_timestamp() pipeline = self.client.pipeline() pipeline.hget(key, "max_date") pipeline.hset(key, "last_poll", last_poll) max_date, _ = pipeline.execute() if max_date is None: # If the user was deleted in between, revert the last_poll self.client.delete(key)
def find_expired_sessions(self): expired_sessions = [] for active_key in self.client.keys('{}:weblab:active:*'.format( self.key_base)): session_id = active_key[len('{}:weblab:active:'.format(self. key_base)):] session_id_key = '{}:weblab:active:{}'.format( self.key_base, session_id) pipeline = self.client.pipeline() pipeline.hget(session_id_key, 'max_date') pipeline.hget(session_id_key, 'last_poll') pipeline.hget(session_id_key, 'exited') max_date, last_poll, exited = pipeline.execute() if max_date is not None and last_poll is not None: # Double check: he might be deleted in the meanwhile # We don't use 'active', since active takes into account 'exited' time_left = float(max_date) - _current_timestamp() time_without_polling = _current_timestamp() - float(last_poll) user_exited = exited in ('true', '1', 'True', 'TRUE') if time_left <= 0: expired_sessions.append(session_id) elif time_without_polling >= self.weblab.timeout: expired_sessions.append(session_id) elif user_exited: expired_sessions.append(session_id) return expired_sessions
def __str__(self): return 'Expired user (id: {!r}): {!r} ({!r}), max date in {:.2f} seconds. Redirecting to {!r}'.format(self._session_id, self._username, self._username_unique, self._max_date - _current_timestamp(), self._back)
def __str__(self): return 'Current user (id: {!r}): {!r} ({!r}), last poll: {:.2f} seconds ago. Max date in {:.2f} seconds. Redirecting to {!r}'.format(self._session_id, self._username, self._username_unique, self.time_without_polling, self._max_date - _current_timestamp(), self._back)
def time_left(self): """ Seconds left (0 if time passed) """ return max(0, self.max_date - _current_timestamp())
def time_without_polling(self): """ Seconds without polling """ return _current_timestamp() - self.last_poll
def _process_start_request(request_data): """ Auxiliar method, called also from the Flask CLI to fake_user """ client_initial_data = request_data['client_initial_data'] server_initial_data = request_data['server_initial_data'] # Parse the initial date + assigned time to know the maximum time start_date_timestamp = server_initial_data.get( 'priority.queue.slot.start.timestamp') if start_date_timestamp: # if the time is available in timestamp, use it start_date = datetime.datetime.fromtimestamp( float(start_date_timestamp)) else: # Otherwise, to keep backwards compatibility, assume that it's in the same timezone # as we are start_date_str = server_initial_data['priority.queue.slot.start'] start_date_str, microseconds = start_date_str.split('.') difference = datetime.timedelta(microseconds=int(microseconds)) start_date = datetime.datetime.strptime( start_date_str, "%Y-%m-%d %H:%M:%S") + difference slot_length = float(server_initial_data['priority.queue.slot.length']) max_date = start_date + datetime.timedelta(seconds=slot_length) locale = server_initial_data.get('request.locale') full_name = server_initial_data['request.full_name'] experiment_name = server_initial_data[ 'request.experiment_id.experiment_name'] category_name = server_initial_data['request.experiment_id.category_name'] experiment_id = '{}@{}'.format(experiment_name, category_name) # Create a global session session_id = create_token() # Prepare adding this to backend user = CurrentUser( session_id=session_id, back=request_data['back'], last_poll=_current_timestamp(), max_date=float(_to_timestamp(max_date)), username=server_initial_data['request.username'], username_unique=server_initial_data['request.username.unique'], exited=False, data={}, locale=locale, full_name=full_name, experiment_name=experiment_name, experiment_id=experiment_id, category_name=category_name, request_client_data=client_initial_data, request_server_data=server_initial_data, start_date=float(_to_timestamp(start_date))) backend = _current_backend() backend.add_user( session_id, user, expiration=30 + int(float(server_initial_data['priority.queue.slot.length']))) kwargs = {} scheme = current_app.config.get(ConfigurationKeys.WEBLAB_SCHEME) if scheme: kwargs['_scheme'] = scheme weblab = _current_weblab() if weblab._on_start: _set_weblab_user_cache(user) weblab._set_session_id(session_id) try: data = weblab._on_start(client_initial_data, server_initial_data) except Exception as error: traceback.print_exc() current_app.logger.warning( "Error calling _on_start: {}".format(error), exc_info=True) try: dispose_user(session_id, waiting=True) except Exception as nested_error: traceback.print_exc() current_app.logger.warning( "Error calling _on_dispose after _on_start failed: {}". format(nested_error), exc_info=True) return dict(error=True, message="Error initializing laboratory") else: if data: user.data = data user.data.store_if_modified() update_weblab_user_data(response=None) link = url_for('weblab_callback_url', session_id=session_id, _external=True, **kwargs) return dict(url=link, session_id=session_id)