def _check_syncthing(self, services): status = INACTIVE_STATE display_name = 'File Sync Service' try: syncthing_config = syncthing_utils.config() device_stats = syncthing_utils.device_stats() except Exception as err: current_app.logger.error( 'Syncthing check failed with {err_type}: {err_msg}'.format( err_type=type(err), err_msg=str(err), ) ) self._add_or_update_service(services, display_name, status) return status # Add 1 second to the interval for avoiding false negative interval = syncthing_config['options']['reconnectionIntervalS'] + 1 min_last_seen = datetime.utcnow() - timedelta(seconds=interval) for device_id, stats in device_stats.items(): last_seen = parse_datetime_string(stats['lastSeen']) # Syncthing is valid when at least one device was seen recently if last_seen > min_last_seen: status = ACTIVE_STATE break self._add_or_update_service(services, display_name, status) return status
def _is_status_report_updated(report): """ The report is considered updated, if the time passed since the report was sent is maximum twice the frequency interval (Nyquist sampling theorem). """ reporting_delta = int(report['reporting_freq']) * 2 report_time = parse_datetime_string(report['timestamp']) return (report_time + timedelta(seconds=reporting_delta) > datetime.utcnow())
def _parse_scheduled_time(self, scheduled_time): scheduled_utc = parse_datetime_string(scheduled_time) if scheduled_utc <= datetime.utcnow(): raise manager_exceptions.BadParametersError( 'Date `{0}` has already passed, please provide' ' valid date. \nExpected format: YYYYMMDDHHMM+HHMM or' ' YYYYMMDDHHMM-HHMM i.e: 201801012230-0500' ' (Jan-01-18 10:30pm EST)'.format(scheduled_time)) return scheduled_utc
def _update_manager_last_seen(node_id): report = request.json.get('report', {}) if report.get('status') != ServiceStatus.HEALTHY: current_app.logger.debug( "The manager with node_id: {0} is not healthy, so it's " "last_seen is not updated".format(node_id)) return storage_manager = get_storage_manager() manager = storage_manager.get(models.Manager, None, filters={'node_id': node_id}) manager_time = parse_datetime_string(manager.last_seen) report_time = request.json.get('timestamp') if report_time and manager_time < parse_datetime_string(report_time): manager.last_seen = get_formatted_timestamp() manager.status_report_frequency = request.json.get( 'reporting_freq') storage_manager.update(manager)
def _verify_report_newer_than_current(node_id, report_time, status_path): if not (path.exists(status_path) and path.isfile(status_path)): # Nothing to do if the file does not exists return with open(status_path) as current_report_file: current_report = json.load(current_report_file) if report_time < parse_datetime_string(current_report['timestamp']): current_app.logger.error('The status report for {0} at {1} is before' ' the latest report'.format( node_id, report_time))
def _other_device_was_seen(syncthing_config, device_stats): # Add 1 second to the interval for avoiding false negative interval = syncthing_config['options']['reconnectionIntervalS'] + 1 min_last_seen = datetime.utcnow() - timedelta(seconds=interval) for device_id, stats in device_stats.items(): last_seen = parse_datetime_string(stats['lastSeen']) # Syncthing is valid when at least one device was seen recently if last_seen > min_last_seen: return True return False
def write_status_report(node_id, model, node_type, report): current_app.logger.debug('Received new status report for ' '{0} of type {1}...'.format(node_id, node_type)) _verify_syncthing_status() _create_statues_folder_if_needed() _verify_node_exists(node_id, model) _verify_status_report_schema(node_id, report) report_time = parse_datetime_string(report['timestamp']) _verify_timestamp(node_id, report_time) report_path = get_report_path(node_type, node_id) _verify_report_newer_than_current(node_id, report_time, report_path) _save_report(report_path, report) current_app.logger.debug('Successfully updated the status report for ' '{0} of type {1}'.format(node_id, node_type))
def _last_manager_in_cluster(): storage_manager = get_storage_manager() managers = storage_manager.list(models.Manager, sort={'last_seen': 'desc'}) active_managers = 0 for manager in managers: # Probably new manager, first status report is yet to arrive if manager.status_report_frequency is None: active_managers += 1 else: # The manager is considered active, if the time passed since # it's last_seen is maximum twice the frequency interval # (Nyquist sampling theorem) interval = manager.status_report_frequency * 2 min_last_seen = datetime.utcnow() - timedelta(seconds=interval) if parse_datetime_string(manager.last_seen) > min_last_seen: active_managers += 1 if active_managers > 1: return False return True