def is_lambda_running(context, dbname, lambda_suffix=None, dynamodb_handler=None): """ Retrieves the last recorded process information for this lambda. This is used to determine if the lambda is already running. :param context: :param string dbname: the database holding a list of lambda run times :param string lambda_suffix: name of the lambda handler :return: """ if not context: return False if dynamodb_handler: db = dynamodb_handler(dbname) else: db = DynamoDBHandler(dbname) lambda_name = context.function_name if lambda_suffix: lambda_name = '{}.{}'.format(lambda_name, lambda_suffix) request = db.get_item({"lambda": lambda_name}) if request: start_time = arrow.get(request['started_at']).to('local') expires_time = start_time.shift(minutes=request['expires'] / 60000) return arrow.now() > expires_time else: return False
def lambda_sec_remaining(context, dbname, lambda_suffix=None, dynamodb_handler=None): """ Returns the time remaining in seconds before the lambda times out :param context: :return: """ if not context: return timedelta(seconds=0) if dynamodb_handler: db = dynamodb_handler(dbname) else: db = DynamoDBHandler(dbname) lambda_name = context.function_name if lambda_suffix: lambda_name = '{}.{}'.format(lambda_name, lambda_suffix) request = db.get_item({"lambda": lambda_name}) if request: start_time = arrow.get(request['started_at']).to('local') # TRICKY: expires is in milliseconds expires_time = start_time.shift(microseconds=(int(request['expires']) * 1000)) return expires_time - arrow.now() else: return timedelta(seconds=0)
def is_lambda_running(context, dbname, lambda_suffix=None, dynamodb_handler=None): """ Retrieves the last recorded process information for this lambda. This is used to determine if the lambda is already running. :param context: :param string dbname: the database holding a list of lambda run times :param string lambda_suffix: name of the lambda handler :return: """ if not context: return False if dynamodb_handler: db = dynamodb_handler(dbname) else: db = DynamoDBHandler(dbname) lambda_name = context.function_name if lambda_suffix: lambda_name = '{}.{}'.format(lambda_name, lambda_suffix) request = db.get_item({ "lambda": lambda_name }) if request: last_time = arrow.get(request['started_at']).to('local') # TRICKY: we use this lambda's expires time instead of the recorded value avoid delays in applying changes to expiration times. timeout = arrow.now().shift(minutes=-lambda_min_remaining(context)) return last_time > timeout else: return False
def add_error(self, message): """ Adds an error to the report :param string|list message: :return: """ if isinstance(message, list): self.logger.info('Reporting Error: {}'.format(json.dumps(message)), exc_info=1) elif isinstance(message, str) or isinstance(message, unicode): self.logger.info('Reporting Error: {}'.format(message), exc_info=1) else: self.logger.warning( 'Unable to report error. Invalid type "{}"'.format( type(message)), exc_info=1) return db = DynamoDBHandler(self.__table_name) # load report if not self._report: item = db.get_item({'lambda': self.__reporter}) if not item: item = {} self._report = { 'errors': [], 'lambda': self.__reporter, 'reporters': [] } self._report.update(item) # start new report if self.__request_id not in self._report['reporters']: self._report['errors'] = [] self._report['reporters'].append(self.__request_id) # append errors to report if isinstance(message, list): timestamp = arrow.utcnow().isoformat() for m in message: self._report['errors'].append({ 'message': m.decode('utf-8'), 'timestamp': timestamp }) else: self._report['errors'].append({ 'message': message.decode('utf-8'), 'timestamp': arrow.utcnow().isoformat() })