Esempio n. 1
0
def get_flag_by_field(
        name: str,
        value: Union[str, int],
        current_round: int,
) -> Optional[models.Flag]:
    """
    Get flag by generic field.

    :param name: field name to ask cache for
    :param value: value of the field "field_name" to filter on
    :param current_round: current round
    :returns: Flag model instance with flag.field_name == field_value or None
    """
    cached_key = CacheKeys.flags_cached()
    with utils.redis_pipeline(transaction=True) as pipe:
        cached, = pipe.exists(cached_key).execute()
        if not cached:
            cache_helper(
                pipeline=pipe,
                cache_key=cached_key,
                cache_func=caching.cache_last_flags,
                cache_args=(current_round, pipe),
            )

        flag_json, = pipe.get(CacheKeys.flag_by_field(name, value)).execute()

    if not flag_json:
        return None

    flag = models.Flag.from_json(flag_json)

    return flag
Esempio n. 2
0
def cache_last_flags(current_round: int, pipe: Pipeline) -> None:
    """
    Cache all generated flags from last "flag_lifetime" rounds.

    Just adds commands to pipeline stack, don't forget to execute afterwards.

    :param current_round: current round
    :param pipe: redis connection to add command to
    """
    game_config = game.get_current_game_config()
    expires = game_config.flag_lifetime * game_config.round_time * 2

    with utils.db_cursor(dict_cursor=True) as (_, curs):
        curs.execute(
            _SELECT_ALL_LAST_FLAGS_QUERY,
            {'round': current_round - game_config.flag_lifetime},
        )
        flags = curs.fetchall()

    flag_models = list(models.Flag.from_dict(data) for data in flags)

    pipe.set(CacheKeys.flags_cached(), 1)
    for flag in flag_models:
        pipe.set(CacheKeys.flag_by_id(flag.id), flag.to_json(), ex=expires)
        pipe.set(CacheKeys.flag_by_str(flag.flag), flag.to_json(), ex=expires)