• На каком движке сделать музыкальный сайт?

    @mezhuev
    Системный администратор
    Странно, что вам не попал в выдачу Subsonic и его форки. Но есть решение лучше — Navidrome — работает быстрее, требует меньше ресурсов и имеет совместимое API, соответственно любое приложение, умеющее работать с Subsonic, будет работать с Navidrome.
    Ответ написан
    Комментировать
  • Есть код на питоне как можно ускорить его мультипроцессность не работает?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Вот в один поток на сях. Только сам скомпилируй. 32 млн строк в секунду. Если писать в /dev/null

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    // habr.com : mayton2019 - 3 Sep 2023
    
    char *hex = "0123456789abcdef";
    char *buf;
    
    void streamer(int max_depth, int level, char *alphabet, int alphabet_size) {
       for(int i = 0 ; i < alphabet_size ; i++) {
          buf[level] = alphabet[i];   
          if ( level < max_depth ) {
            streamer(max_depth, level+1, alphabet, alphabet_size);
          } else {
            buf[level] = '\0';
            printf("%s\n", buf);
            break;
          }
       }
    }
    
    int main(int argc, char** argv) {
      buf = malloc(strlen(hex) + 1);
      streamer(16, 0, hex, strlen(hex));
      free(buf);
      return 0;
    }


    Вот как я мерял.
    gcc hex-gen.c -o hex-gen.exe && ./hex-gen.exe | pv -l -r > /dev/null
    [30.7M/s]
    [30.1M/s]
    [30.3M/s]


    Вот если писать в текстовый файл то скорость чуть медленнее. 24 млн строк за секунду.

    Вот. Проверяй данные. Что я нигде не ошибся.

    UPD: Лишний ноль убрал.
    UPD: +break добавил.
    Ответ написан
    Комментировать
  • Как правильно вычислять vm.dirty_background_bytes и vm.dirty_bytes?

    TaHKucT
    @TaHKucT
    Linux администратор
    У меня ответ больше 10000 символов. Тостер его не пропускает, поэтому разобью его на ответа:

    Я так понимаю что для плавной работы Linux сервера, для плавной записи грязных страниц нужно поправить параметры vm.dirty_background_bytes и vm.dirty_bytes до соразмерных с величинами скорости записи на диск?

    Нет. vm.dirty_background_bytes - сколько байт можно занять под dirty pages до того, как эта память начнем автоматически синхронизироваться на диск. vm.dirty_bytes - сколько всего байт можно занять под dirty pages.

    Например у вас выставлен vm.dirty_background_bytes = 10, vm.dirty_bytes = 30, скорость записи на диск 2 байта в секунду, а скорость записи в ОЗУ 5 байт в секунду (все специально такое маленькое, что бы наглядно было понятно что происходит и не путаться в переводе значений из байт в мегабайты, байт в секунду в мегабиты в секунду и т.п.).
    (Сделаем оговорку что dirty pages работает намного сложнее, чем описанно ниже. Он работает со страницами, а не с байтами, он имеет привязку к конкретным файлам и еще куча нюансов. Ниже очень упрощенный вариант объяснения, что бы получить примерное представление о том, что вообще происходит).

    В Секунду 0 (начало примера) vm.dirty_background_bytes = 0, диск полностью простаивает и ничего не происходит (опустим момент что linux многопоточный и такая ситуация почти нереальна в реальной жизни). Вдруг какой-то процесс начинает писать что-то на диск, фактически он изменяет данные в ОЗУ и помечает страницу как dirty page, фактической записи на диск не происходит (если не происходит вызов fsync, но об этом ниже).
    То есть через секунду, в секунду 1 у нас расклад такой: vm.dirty_background_bytes = 5 (скорость записи в ОЗУ ведь равно 5, дальше будет предполагать что процесс всегда будет писать с этой скоростью, потому что например ему нужно многое записать и все данные к этому уже подготовленны), vm.dirty_bytes = 5 (vm.dirty_bytes - это доступный для dirty page объем памяти, vm.dirty_background_bytes - это часть от vm.dirty_bytes), скорость записи на диск = 0.
    Следующая, 2 секунда: vm.dirty_background_bytes = 10, vm.dirty_bytes = 10, скорость записи на диск = 0.
    Следующая, 3 секунда: vm.dirty_background_bytes = 15, vm.dirty_bytes = 15, скорость записи на диск = 2 (vm.dirty_background_bytes превысил установленные нами условные 10 байт и запускается процесс синхронизации, он выбирает на скорость 2 байта в секунду (как мы условились выше) данные и пишет их на диск) (тут можно спорить в какой именно момент запуститься процесс синхронизации dirty pages на диск, когда vm.dirty_background_bytes будет 9, 10 или 11, но в данном случае этот вопрос не принципиальный).
    Следующая, 4 секунда: vm.dirty_bytes = 18 (+5 записал процесс, -2 синхронизировал процесс синхронизации, итого 15+5-2=18). vm.dirty_background_bytes нас больше не интересует, потому что он синхронизатор уже запустился.
    5 секунда: vm.dirty_bytes = 18
    6 секунда: vm.dirty_bytes = 21
    7 секунда: vm.dirty_bytes = 24
    8 секунда: vm.dirty_bytes = 27
    9 секунда: vm.dirty_bytes = 30
    10 секунда: vm.dirty_bytes = 30 (vm.dirty_bytes уперся в вышеусловленное значение в 30 байт, больше места под dirty page у нас нет, поскольку синхронизирует записывает по 2 байта/с то мы упираемся в 2 байта/с, пока процесс не запишет все свои данные).
    ...
    Энная секунда: (процесс записал все необходимые ему данные): vm.dirty_bytes = 28
    n+1: vm.dirty_bytes = 26 (и т.п.).

    То есть как видно dirty page позволяет нам "сгладить" небольший всплекс на запись, за счет того, что данные, которые нужно записать на диск будут временно храниться в памяти. Причем именно кратковременный всплекс, потому что на долговременном всплекске вы забиваете всю память, отведенную под dirty page и после этого скорость записи падает до скорости работы диска. Очевидно что технология полезная и иногда нужная, но все сильно зависит от ваших парентов нагрузки (именно по этому все совеют разные числа, у кого-то один вариант показывает себя лучше, у кого-то другой.) Увеличивая размер vm.dirty_bytes вы с одной стороны увеличиваете размер пика, который получиться сгладить, с другой увеличиваете объем ОЗУ которое займете под этот пик и время, которое понадобиться на то, что бы разгрести эту ОЗУ.
    При этом я вижу что по дефолту в centos7 выставленны значения vm.dirty_background_ratio = 10 и vm.dirty_ratio = 30 (то есть 30% от всей доступной памяти можно занять под dirty page, запускать синхронизацию если зянято более 10%), vm.dirty_expire_centisecs = 3000 (сбрасывать на диск данные, которые находяться в dirty page больше 30 секунд вне зависимости от того, сколько в данный размер занято под dirty page) и vm.dirty_writeback_centisecs = 500 (синхронизатор должен просыпаться каждые 5 секунд для обработки данных, подподающих под vm.dirty_expire_centisecs).
    На ubuntu (16.04 и 18.04) vm.dirty_ratio = 20, все остальные параметры точно такие-же как у centos.

    Логика тут очень простая: под dirty page память не резервируется. Если она нужна и есть свободная память - она используется (максимум 30% или 20% от всей доступной). Причем доступная память, это не "всего установленно", это именно available память в выводе "free".
    То есть мы получаем "некую автоматическую балансировку" системы по данному параметру в зависимости от "Total RAM - Used RAM", чем доступной памяти больше, тем больше может быть dirty page. Если собираетесь ограничить dirty page в 2-4-8 мегабайт, то хотя бы проведите набор тестов под вашей боевой нагрузкой (не синтетической, а именно боевой) и убедитесь что это хотя-бы не сделает хуже (не снизит производительность). Мой опыт говорит что на моих нагрузках большинство серверов чувствуют себя отлично со значениями по умолчанию.
    Ответ написан
    6 комментариев
  • Как достучаться до VM Hyper-V?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Ну, у виртуалки всегда есть консоль...
    Ответ написан
    Комментировать
  • Смена ОС дистанционно?

    ValdikSS
    @ValdikSS
    В UEFI есть переменная BootNext, в которой можно установить идентификатор загрузочной записи для следующей однократной загрузки. Установить её можно с помощью efibootmgr:

    $ sudo efibootmgr

    BootCurrent: 0019
    Timeout: 0 seconds
    BootOrder: 0019,0009,001A,000A,0006,0007,0008,000B,000C,000D,000E,000F,0010,0011,0012,0013
    Boot0000 Setup
    Boot0001 Boot Menu
    Boot0002 Diagnostic Splash Screen
    Boot0003 Startup Interrupt Menu
    […]
    Boot0017* ATAPI CD:
    Boot0018* PCI LAN
    Boot0019* Fedora
    Boot001A* EFI Shell

    $ sudo efibootmgr --bootnext 001A

    BootNext: 001A
    BootCurrent: 0019
    Timeout: 0 seconds
    BootOrder: 0019,0009,001A,000A,0006,0007,0008,000B,000C,000D,000E,000F,0010,0011,0012,0013
    Boot0000 Setup
    Boot0001 Boot Menu
    Boot0002 Diagnostic Splash Screen
    Boot0003 Startup Interrupt Menu
    […]
    Boot0017* ATAPI CD:
    Boot0018* PCI LAN
    Boot0019* Fedora
    Boot001A* EFI Shell
    Ответ написан
    4 комментария
  • Можно ли импортировать что-то из разных... серверов?

    Vindicar
    @Vindicar
    RTFM!
    И как это сделать?

    sundnl, взять и сделать. Не зная подробностей, тебе никто ничего не подскажет. С такой формулировкой тебя даже на фрилансе пошлют, и будут правы.

    Что за игра, что за сервер? Может, у него уже есть какое-то API, по которому можно вытащить интересующие данные?

    Собственно, что это за данные? Каков их объём? Именно данные, или нужно оповещение о событиях в игре? Разница очень большая, так как будет определять, кто будет проявлять инициативу при отправке данных - сервер или бот.

    Если API нет, есть ли доступ к исходникам сервера? Как организован рабочий цикл сервера? Потребуется ли нам запускать отдельный поток - а значит, синхронизировать доступ к искомым данным? Или же там что-то на базе asyncio, и мы можем просто добавить асинхронную задачу?

    Нужно определиться с форматом отдачи данных - тут лучше не изобретать велосипед, а использовать JSON, если данных не очень много.

    Можно подумать о том, чтобы добавить в серверный скрипт небольшой сервер на Flask, или на базе asyncio streams, или на голых сокетах. Конкретная реализация зависит в том числе от того, кто проявляет инициативу: если бот запрашивает, а сервер отвечает, то Flask позволит обращаться к серверу по HTTP, а не громоздить велосипед на сокетах. Если же сервер может что-то слать по своей инициативе, то тут уже HTTP подойдёт так себе.

    Когда ответишь на все перечисленные вопросы, вот тогда у тебя будет вопрос, стоящий обсуждения. В конце концов, правильно поставленный вопрос - это половина ответа.
    Ответ написан
    Комментировать
  • Как достать из этой строки информацию?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Это JSON. В питоне есть модуль, конвертирующий json-строки в структуры данных питона.
    Ответ написан
    Комментировать
  • Код не видит десятичные числа?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    А вас не смущает, что вы пытаетесь сравнить по принципу больше-меньше строки?
    Ответ написан
    Комментировать
  • Можно ли пропустить первый аргумент по умолчанию в Python?

    aRegius
    @aRegius
    Python Enthusiast
    Как вариант, можете посмотреть в сторону partial

    >>> def total(a=5, *b):
           return(a, b)
    
    >>> total_first_fixed = partial(total, 5)
    
    >>> a, b = total_first_fixed(6)
    >>> a
    5
    >>> b
    (6,)
    >>> a, b = total_first_fixed(1, 2, 3)
    >>> a
    5
    >>> b
    (1, 2, 3)
    Ответ написан
    Комментировать
  • Можно ли пропустить первый аргумент по умолчанию в Python?

    @kamenyuga
    Конечно, это возможно. В питоне можно все, потому что все доступно в любой момент времени. Вопрос только в сложности и обработке всех возможных вариантов. В таких случаях помогает модуль inspect. Но, если до такого дошло в прикладном коде, значит дела идут не важно и не туда.

    import inspect
    
    def get_default_args(func):
        signature = inspect.signature(func)
        return {
            k: v.default
            for k, v in signature.parameters.items()
            if v.default is not inspect.Parameter.empty}
    
    def f1(a=5, *b):
        print(a)
        print(b)
    
    if __name__ == '__main__':
        f1(1, 2, 3)
        f1(*get_default_args(f1).values(), 1, 2, 3)
    Ответ написан
    Комментировать
  • Python sqlite3 как избежать ошибку?

    AlexNest
    @AlexNest Куратор тега Python
    Работаю с Python/Django
    Для подстановки - используйте методы, описанные в документации к модулю sqlite а не форматирование.
    Ответ написан
    4 комментария
  • Как соеденить две линии интернета?

    ValdikSS
    @ValdikSS
    Ответ написан
    Комментировать
  • Что означает: аргументе функции?

    Vindicar
    @Vindicar
    RTFM!
    Аннотация типа аргумента. Интерпретатор питона его игнорирует, но IDE и статические анализаторы могут использовать эти сведения, чтобы поймать ситуации, когда в функцию передаются данные неверного типа.

    Также сама программа при желании может получить доступ к этим аннотациям. Есть библиотеки, которые этим пользуются.
    Ответ написан
    Комментировать
  • Что нужно знать для того чтобы пользоваться wireshark?

    @Zerg89
    Osi tcp/ip инкапсуляция
    Ответ написан
    Комментировать
  • Какой дистрибутив Linux лучше всего подходит для игр?

    smorman
    @smorman
    When In Rome do as The Romans do...
    Тебе уже ответили, что никакой, но!
    Linux сам по себе захватывающе в миллион раз любой самой навороченной игрушки!
    Ответ написан
    1 комментарий
  • Как данные перемещаются в сети интернет, всегда конвертируются в кадры Ethernet или остаются в пакетах IP?

    CityCat4
    @CityCat4 Куратор тега Сетевое администрирование
    Внимание! Изменился адрес почты!
    Олиферы прочитаны?

    Если нет, то тогда вот такая вот история:
    - ты берешь кило картошки и высыпаешь его в пакет, на котором пишешь "кило картошки"
    - потом упаковываешь это в другой пакет, на котором пишешь "квартира 29"
    - потом упаковываешь это в другой пакет, на котором пишешь "3-я ул. Строителей, дом 12"
    - потом упаковываешь это в другой пакет, на котором пишешь "В доставку" и зовешь курьера.

    Курьер приезжает в доставку и снимает свой пакет.
    Доставка видит адрес, довозит пакет до дома, передает его консьержу и снимает свой пакет
    Консьерж зовет коридорного, который подымает пакет к двери квартиры и снимает свой пакет, потом звонит в дверь
    Адресат открывает дверь и видит пакет с надписью "кило картошки".

    Разве картошка по пути следования в что-то "преобразовывалась"?
    Ответ написан
    5 комментариев
  • Как отправить запрос к сайту через определенный DNS-сервер в python?

    Vindicar
    @Vindicar
    RTFM!
    Есть довольно старый ответ на стэковерфлоу. requests под капотом использует urllib3, а та содержит функцию urllib3.util.connection.create_connection(), ответственную за установку TCP соединения. Соответственно, можно попробовать подменить эту функцию на свою реализацию, и использовать пакет dnspython для запросов.
    from urllib3.util import connection
    import dns.resolver
    
    def your_dns_resolver(hostname: str) -> str:
        """Получает на вход доменное имя, возвращает IP адрес в виде строки."""
        resolver = dns.resolver.Resolver(configure=False)
        resolver.nameservers = ["8.8.8.8"]  # список используемых DNS серверов.
        answer = resolver.resolve(hostname, "A")  # A-запись для IPv4 адреса, AAAA-запись для IPv6 адреса
        if len(answer) == 0:
            raise Exception("No A record found")
        return str(answer[0])
    
    _orig_create_connection = connection.create_connection
    
    def patched_create_connection(address, *args, **kwargs):
        """Wrap urllib3's create_connection to resolve the name elsewhere"""
        host, port = address  # оригинальный адрес для запроса
        hostname = your_dns_resolver(host)  # сами определяем IP по имени
        return _orig_create_connection((hostname, port), *args, **kwargs)  # дёргаем оригинальную функцию, чтобы создать соединение
    
    connection.create_connection = patched_create_connection

    Код не проверял, это скорее концепт чем готовый инструмент.
    Ответ написан
    9 комментариев
  • Как в больших организациях присваиваются ip-адреса для всех устройств?

    Adler_lug
    @Adler_lug
    Ведь, максимумом является 255 IP-адресов в одной сети
    Кто вам такое сказал?

    Гуглите "подсеть" и "маска сети".
    Ответ написан
    3 комментария
  • Syntax Error ошибка что делать, как чинить?

    idegree
    @idegree
    Senior Workaround Developer
    У вас же в ошибке все написано: SyntaxError: 'await' outside function.
    Нельзя использовать ключевое слово await вне ассинхронной функции.

    async def myfunc():
        await my_async_func()
    Ответ написан
    Комментировать