• Как реализовать атомарное обновление 2 файлов?

    AshBlade
    @AshBlade Автор вопроса
    Просто хочу быть счастливым
    В итоге пришел к такому решению:
    Моя основная проблема - не как атомарно обновить 2 файла, а создавать снапшот приложения и очищать лог (чтобы размер не становился огромным) так, чтобы согласованность не нарушалась.

    Моя проблема заключалась в изначально неправильном проектировании файловой структуры - было только 2 файла: снапшот и лог.
    Спустя время нашел следующее решение:
    - Файл снапшота 1 - для его обновления создается временный файл снапшота, который атомарно переименовывается (системный вызов rename атомарный - так прописано в документации)
    - Вместо единого файла лога используется сегментированный лог - весь лог хранится в нескольких меньших файлах. Т.е. теперь я работаю с логическим файлом лога, который состоит из нескольких физических сегментов. Сегменты лога не удаляются при создании снапшота - этим может заниматься фоновый поток, который удаляет те сегменты все записи которых по индексу меньше индекса примененной записи в снапшоте.

    Так как я использую RAFT, то необходимость в UNDO логе при записи в лог отпадает:
    - запись append only, т.е. закоммиченные записи перезаписываться не будут
    - лог может быть в несогласованном состоянии только если не до конца будут перезаписаны незакоммиченные записи, но это можно понять по чек-суммам, которые идут после каждой записи (можем откатить лог)

    Также нашел недостаток в моей реализации - я храню индекс последней закоммиченной записи на диске (хранил в логе). Этого можно не делать и спокойно хранить в памяти, инициализируя на старте в 0 (ничего не закоммичено). Такой подход я также нашел в реализации рафт от HashiCorp (точнее есть открытый issue). Этот индекс будет инициализирован либо существующим лидером, либо при старте он будет корректно выставлен согласно консенсусу.

    В итоге работа со снапшотами будет примерно следующей:
    - Добавляем (при необходимости перезаписываем) записи в лог
    - Если размер сегмента превысил максимальный, то создаем новый и закрываем старый (работа будет вестить с новым файлом)
    - Новый снапшот создаем во временном файле
    - Когда снапшот готов, то атомарно вызовом rename перемещаем его в целевой файл (замена)
    - Фоновый поток в один момент обнаружит, что есть файлы лога с неактуальными записями и тогда их (старые сегменты лога) удалит

    Похожие идеи я нашел в:
    - etcd - создание новых файлов сегментов через атомарный rename
    - kafka - все записи хранит в xxxxxxx.log файле, где xxxxxxx означает офсет первой записи
    Ответ написан
    Комментировать
  • Обновление nodejs api после деплоя через докер и безопасность. Каков путь?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Как обновить приложение при обнове исходников?

    Собираешь новый образ с новым тэгом
    Повторить процесс удалив контейнер?

    Да
    Примерно так
    docker stop my-container
    docker rm my-container
    docker run --name=my-container my-image:new-tag

    Какие подводные по настройке безопасности?

    root-less контейнеры
    маунтить отдельные файлы и по возможности ro
    порты не привилегированные использовать
    вообще, докер это не про безопасность, а про скорость
    Стоит ли держать бд на одном vps с api или поднять еще один.

    Если инстанс контейнера один, то лучше на одном - локальность данных
    Если горизонтально масштабируешься + отказоустойчивость повысить хочешь, то лучше раздельные
    Ответ написан
  • Как исправить ошибку vector subscript out of range?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Скорее всего ты выходишь за пределы массива.
    Ответ написан
    Комментировать
  • Как решить проблему с типами данных?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    HealthBarImage.fillAmount = (float) HealthBossNow / HealthBoss;
    Ответ написан
  • Почему функция is_palindrome не видит метода .lower()?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    исходное слово тоже к нижнему регистру привести надо, а вообще не надо приводить к нижнему иначе логика неправильная - регистр тоже надо учитывать
    Ответ написан
    Комментировать
  • Как быстро освоить c#, если я работаю на c++?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Пролистываешь метанит параллельно повторяешь примеры.
    Это за 1-2 дня можно сделать.
    Синтаксис довольно простой и немного похож на C++, поэтому изучится легко. Дальше уже идешь в проект и изучаешь какие библиотеки/фичи платформы там используются - их много поэтому лучше не распыляться на них во время обучения
    Ответ написан
    Комментировать
  • Как разместить N файлов по папкам?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    1. Сортируешь все файлы по размеру
    2. Берешь самый большой файл и помещаешь в первую папку
    3. Дальше каждый файл по убыванию размера:
    1. Находишь папку с наименьшим оставшимся размером, который позволяет добавить туда файл
    2. Если таких нет - создаешь новую папку и кладешь туда
    Ответ написан
    7 комментариев
  • Как защитить данные от повреждения при INSERT?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Уровни безопасности:
    1. Бизнес-логика - триггеры, ограничения
    2. Операции обновления - транзакции
    3. Хранение записей - репликация, RAID массивы, бэкапы
    4. Загрузка - проверка файловой системы при старте ОС, фс с возможностью восстановления

    Самый надежный способ
    Использовать PostgreSQL
    Ответ написан
    Комментировать
  • Linux cервер не видит потоки процессора?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Человек тут тоже с такой проблемой столкнулся.
    Он включил Hyper-threading в BIOS и выполнил update -initramfs -u -k all
    Ответ написан
    Комментировать
  • Как правильно реализовать взаимодействия с сервером авторизации на стороне c#?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    В OAuth используюся jwt токены преимущественно - про то чтобы передавать в куках не слышал/не реализовывал.
    Так как используется OAuth 2.0 , то все зависит от роли бэка на шарпе:
    - Если это просто API без вьюшек (HTTP), то тут лучше пользователя заставить самому предоставлять JWT и валидировать его на своей стороне
    - Если это веб-приложение, то нужно использовать Authorization Code flow

    В обоих случаях, когда токен протухнет тебе передаст сервер с успешным ответов в поле expires_in.
    Вот тут про OAuth flow - https://kinde.com/guides/authentication/protocols/...
    А вот тут что поддерживает Spring Boot OAuth - https://docs.spring.io/spring-security-oauth2-boot...
    Ответ написан
    Комментировать
  • Как ограничить кол-во символов после точки при вводе данных в С++?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Если нужно округление до определенного кол-ва знаков после запятой, то вот это может помочь:
    unsigned int powers[] = {1, 10, 100, 1000, 10000, 100000};
    
    double round_precision(double number, unsigned int precision) {
      unsigned int coef = powers[precision];
      long temp = number < 0 ? -number * coef : number * coef;
      return (double)temp / coef;
    }


    Также есть вариант записывать число в std::stringstream с нужной точностью, а потом десериализовывать, но т.к. это затратно для этого случая не описал.
    Ответ написан
    Комментировать
  • Как правильно мержить в main из dev, если там есть незаконченные фичи?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Решение более правильное - не делать так. Мержить надо когда все работает, а если есть неработающий функционал, то:
    - Либо комментировать функциональность которая еще не работает
    - Либо сделать эту функциональность доступной через фича-флаги. Эти флаги соответственно никто не должен выставлять
    - Либо мержить только работающие ветки, а та, в которой не работает/не закончена - в нее мержить уже готовую мастер ветку

    Мержить через cherry-pick - такое себе: одна ошибка и ты ошибся (фатально)
    Ответ написан
    Комментировать
  • Как настроить caprover и docker?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Но, теперь он ругается что у меня закрыт 80 порт, хотя это не так, порты открыл.

    Попробуй убрать пробрасывание портов у nginx.
    Судя по всему Caprover подключается к 80 и 443 портам, которые заняты
    Ответ написан
  • Как сделать алгоритм фокусировки?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Нашел этот ответ на SO - https://stackoverflow.com/a/28722407
    В кратце, нужно сравнить 2 изображения - с применой фокусировкой и без. Фокусировка реализуется через применения оператора Лапласа
    cv::Laplacian(src_gray, dst, CV_64F);
    
    cv::Scalar mu, sigma;
    cv::meanStdDev(dst, mu, sigma);
    
    double focusMeasure = sigma.val[0] * sigma.val[0];


    Для оптимизации предлагаю следующие варианты:
    1. Всегда фокусироваться
    2. Через определенные промежутки времени (либо кол-во кадров, не суть), брать сампл изображения и для него вычислять размытость - если изображение размыто, то дальше применяем фокусировку

    P.S. под фокусировкой я понял резкость/размытость изображения
    Ответ написан
    1 комментарий
  • Как сделать преобразование переменной в С++?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Если вопрос в том - как возвращать ошибку в качестве ответа, то есть решения:
    - Создать специальный класс Result, который будет содержать либо ответ, либо строку ошибки
    - Возвращать double.NaN - маркер ошибки
    - Кидать исключение

    UPD: если функция возвращает double, а ты хочешь передать std::string, то ничего не получится - типизация строгая
    Ответ написан
    1 комментарий
  • Почему нельзя инициализировать динамический массив в списке инициализации конструктора класса?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Список инициализации выставляет значения в том порядке, в котором объявлены поля.
    Просто поменяй местами аллокацию массивов и полей размеров (в списке инициализации)
    Ответ написан
    1 комментарий
  • Генетический алгоритм в pygame?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Судя по описанию - это можно реализовать и без генетических алгоритмов/глубокого обучения и т.д.
    Алгоритм прост:
    1. На каждой итерации находишь расстояние до всех доступных противников
    2. Рассчитываешь "опасность" исходя из его класса/расстояния/скорости/жизни и тому подобное. Самое простое - атакуй ближайшего к себе
    3. На каждой итерации рассчитывай эти веса и выбирай того, у которого этот вес больше
    Ответ написан
    Комментировать
  • Как реализовать функцию статистики просмотра страницы за некий период?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Тут подходит какая-нибудь аналитическая СУБД. Например, ClickHouse практически для этого и создавался (Click Stream + Ware House).
    Хранить можно следующим образом:
    1. Есть общая таблица по посещениям/визитами с примерно такой структурой [page_id, visit_date] (больше и не надо)
    2. Для хранения статистики создаешь материализованные представления для дня/недели/года

    У них есть тестовые данные для плейграунда сбора аналитики по посещениям/хитам - https://clickhouse-docs.vercel.app/docs/en/getting...
    Ответ написан
    3 комментария
  • Какие есть песочницы (fiddle) для NoSQL баз данных?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Redis - https://try.redis.io/
    MongoDB - https://www.humongous.io/app/playground/mongodb/new
    ClickHouse - https://play.clickhouse.com/play?user=play
    Neo4j - https://console.neo4j.org/
    ElasticSearch - https://www.elastic.co/demos

    Дополнительно - устанавливаешь докер, качаешь нужный образ, находишь сиды различных БД и играешься
    Ответ написан
    Комментировать
  • Есть ли какой-нибудь способ конвертировать массив или коллекцию List в synchronizedCollection?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    SynchronizedCollection<T> - это легаси из .NET фреймворка, в современном рантмайме ты его не найдешь.
    Могу предложить использовать:
    - BlockingCollection<T>
    - Channel<T>

    Если есть возможность, то конвертируй задачу на Scatter/Gather манеру и необходимость в этих структурах данных отпадет.
    Ответ написан
    Комментировать