Задать вопрос
  • Как повторять цикл в дочернем потоке с заданным интервалом для последних актуальных данных?

    bingo347
    @bingo347
    Crazy on performance...
    Примерно так это можно реализовать:
    use chrono::Utc;
    use std::{
        io::{self, BufRead as _},
        sync::mpsc::{self, RecvTimeoutError, Sender},
        thread,
        time::{Duration, Instant},
    };
    
    enum Op {
        Add(String),
        Del(String),
    }
    
    const PRINT_INTERVAL: Duration = Duration::from_secs(10);
    
    fn main() {
        println!("---\n{}\n---\n", Utc::now());
    
        let (tx, rx) = mpsc::channel();
        start_stdin_thread(tx);
    
        let mut strings = Vec::new();
        let mut last_print = Instant::now();
        loop {
            match rx.recv_timeout(PRINT_INTERVAL - last_print.elapsed()) {
                Err(RecvTimeoutError::Disconnected) => break,
                Err(RecvTimeoutError::Timeout) => {
                    println!("---\n{}\n{:?}\n---\n", Utc::now(), strings);
                    last_print = Instant::now();
                }
                Ok(Op::Add(s)) => {
                    strings.push(s);
                }
                Ok(Op::Del(s)) => {
                    strings.retain(|v| v != &s);
                }
            }
        }
    }
    
    fn start_stdin_thread(tx: Sender<Op>) {
        #[derive(Clone, Copy)]
        enum OpRaw {
            Add,
            Del,
        }
    
        thread::spawn(move || {
            let mut stdin = io::stdin().lock();
            let mut buf = String::with_capacity(1024);
            let mut read_line = |buf: &mut String| -> io::Result<()> {
                buf.clear();
                stdin.read_line(buf).map(|_| ()).inspect_err(|err| {
                    eprintln!("Ошибка чтения stdin: {err}");
                })
            };
    
            loop {
                println!("1. Добавить текст");
                println!("2. Удалить текст");
                print!("Введите номер операции: ");
                if read_line(&mut buf).is_err() {
                    break;
                }
    
                let op = match buf.trim() {
                    "1" => OpRaw::Add,
                    "2" => OpRaw::Del,
                    _ => {
                        eprintln!("Некорректная операция");
                        continue;
                    }
                };
    
                println!(
                    "Введите текст на {}:",
                    match op {
                        OpRaw::Add => "добавление",
                        OpRaw::Del => "удаление",
                    }
                );
                if read_line(&mut buf).is_err() {
                    break;
                }
    
                let text = buf.trim().to_string();
                let op = match op {
                    OpRaw::Add => Op::Add(text),
                    OpRaw::Del => Op::Del(text),
                };
    
                if tx.send(op).is_err() {
                    break;
                }
            }
        });
    }
    Ответ написан
    1 комментарий
  • Как поправить код для отдельного потока, чтобы обрабатывать данные по заданному времени?

    bingo347
    @bingo347
    Crazy on performance...
    Во-первых, следует понять, что канал по своей природе - это очередь.
    То есть, если пользователь успеет за отведённое время сделать 5 изменений, то наш дочерний поток получит 5 копий вектора, а судя по задаче там ожидается только актуальная последняя копия.
    Гораздо логичнее просто пошарить между потоками единственный вектор обёрнутый в Arc<RwLock<...>> или Arc<Mutex<...>>, заодно и памяти меньше сожрём и не будем греть проц бесполезными аллокациями памяти и копированием вектора.

    Но если всё же задача другая, то у Receiver канала помимо метода recv, который блокирует поток до получения сообщения, есть ещё методы try_recv (не блокирует поток вообще) и recv_timeout (блокирует, но не дольше переданного таймаута).
    https://doc.rust-lang.org/std/sync/mpsc/struct.Rec...
    https://doc.rust-lang.org/std/sync/mpsc/struct.Rec...

    P.S.
    Duration::from_millis(10)
    тут явно не 10 секунд...

    P.S.S. Перформанс сия кода ушёл в отставку:
    В коде есть лишние итерации по вектору.
    В коде куча лишних аллокаций и копирования памяти.
    Всю задачу можно вообще решить на одном потоке и оно будет работать быстрее ибо про синк кэшей проца тоже не надо забывать.

    Ну и так по мелочи:
    if console.0 == 1 {
        h_add_del_txt.insert(1, console.1);
    } else if console.0 == 2 {
         h_add_del_txt.insert(2, console.1);
    } else {  
         // ...
    }
    match, enum вместо u8

    et mut g = String::new();
         io::stdin().read_line(&mut g).expect("Failed to read line");
         let g: String = g.trim().parse().expect("Please type a ...");
    WTF?

    Ну и паниковать на каждый чих так себе идея...
    Ответ написан
    1 комментарий
  • Возможно ли вытащить диски с synology с RAID-5 и воткнуть их в хранилку другого производителя Ugreen к примеру. Восстановится ли РАИД?

    bingo347
    @bingo347
    Crazy on performance...
    С Ugreen не сталкивался, а вот от Synology отказался совсем недавно.
    RAID у них сделан софтверно на базе LVM, это немного более навороченная технология чем mdadm, о котором написали до меня, но суть не меняется - подцепит любой Linux.
    А вот захочет ли с этим дружить нормально Ugreen - не факт. Так что самое надёжное - подцепить диски к любому компу с Linux (можно даже в live-usb загрузиться) и скопировать куда-либо свои данные, а уже после вставлять диски в новый NAS и пусть спокойно переразмечает их по своему (с потерей данных)
    Ответ написан
    Комментировать
  • OOM killer убивает cron. Как быть?

    bingo347
    @bingo347
    Crazy on performance...
    У Вас же наверняка современная система в которой есть systemd?
    1. Делаем systemd service unit для запуска нашего скрипта
    2. Ограничиваем сервису память через cgroups чтобы из-за протекающего сервиса не вызывать проблемы в системе в целом
    3. Делаем systemd timer unit, который будет запускать наш сервис и полностью заменит нам cron
    4. systemctl enable --now my-unit.timer
    Ответ написан
    Комментировать
  • Как ожидать инициализации в nodejs при обработке первого запроса?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Если long_init_operation синхронная, то она всё равно заблокирует выполнение и запросы обрабатываться не будут. Как вариант - перезапускать инстансы кластера по очереди, уведомляя управляющий процесс по мере готовности, тогда пока 1 инстанс запускается остальные будут обрабатывать запросы.

    Если же можно сделать инициализацию асинхронной, то можно резолвить промис по её завершении, а в запросах ждать его резолва
    Ответ написан
    Комментировать
  • В каких случая стоит использовать usize?

    bingo347
    @bingo347
    Crazy on performance...
    Для операций сводящихся к арифметике указателей.
    Помимо непосредственно арифметики указателей сюда относятся индексация и длина слайсов/массивов/векторов/строк, capacity вектора/строки, размеры и выравнивание типов, смещение полей относительно начала структуры.
    Но в целом, где удобно, там и используйте, никто не запрещает использовать usize/isize как и другие int типы
    Ответ написан
    2 комментария
  • Как проверить перемещается ли в памяти объект при "перемещении"?

    bingo347
    @bingo347
    Crazy on performance...
    При перемещении адрес на стеке изменится, а адрес памяти выделенной на куче - нет.
    Тут очень тонкий момент, который нужно понимать, данные которые мы помещаем в Box или Vec будут размещены на куче, но сами Box и Vec - это такие же структуры, как и любые другие, просто на них есть некоторая логика для управления памятью на куче, в случае 64 битной архитектуры и T: Sized, Box<T> будет занимать 8 байт на стеке и размер T на куче, а Vec<T> - 24 байта на стеке (указатель на начало, длина и фактически выделенная память) и размер T умноженный на capacity на куче.

    fn main() {
        let a = Box::new(42);
        println!("Stack address of a: {:p}", &a);
        println!("Heap address of a: {:p}", &*a);
        
        let b = a;
        println!("Stack address of b: {:p}", &b);
        println!("Heap address of b: {:p}", &*b);
    }
    Stack address of a: 0x7fff59586010
    Heap address of a: 0x58cf76717b10
    Stack address of b: 0x7fff59586018
    Heap address of b: 0x58cf76717b10
    Ответ написан
    Комментировать
  • Rust как подключить внешний файл в модуле?

    bingo347
    @bingo347
    Crazy on performance...
    Структура модулей в крейте с точностью повторяет структуру файлов на диске, даже если модуль объявлен внутри модуля не вынесеного в отдельный файл.
    То есть одно и то же объявление mod db;будет искать файл в разных местах, в зависимости от того, где оно написано:
    • если написать в корне src/lib.rs то будет искать src/db.rs или src/db/mod.rs
    • если написать в модуле cmd внутри src/lib.rs то будет искать src/cmd/db.rs или src/cmd/db/mod.rs

    Но у меня большое подозрение, что Вы вообще не понимаете, как работает ключевое слово mod, ибо напихали его где только можно, включая сам db.rs (там будет искать src/db/db.rs кстати). Ключевое слово mod подключает модуль как дочерний того модуля, где оно написано. А для импорта имён нужно использовать use.

    И как верно подметил fenrir, если бы Вы внимательно прочитали растбук, то Вы бы это поняли.
    Ответ написан
    3 комментария
  • Простой счётчик без БД (допустим на основе txt файла)?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Что-то вроде такого:
    cat /var/log/nginx/access.log | grep 'GET /path/to/page' | awk '{print $1}' | sort | uniq | wc -l

    где /path/to/page - web путь к странице
    Ответ написан
    1 комментарий
  • Есть ли разница каким способом добавлять обработчик события в js, конкретно элементу или всему документу, смотря со стороны производительности?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Первый вариант предпочтительнее, когда у нас есть один единственный элемент с такой логикой и этот элемент существует на момент добавления обработчика.
    Второй вариант предпочтительнее, когда таких элементов много, или когда они появляются динамически.

    По перфомансу:
    метод closest не бесплатный и здесь он будет вычислятся на любой клик по документу
    создание функций тоже не бесплатно, но можно навешивать одну и ту же функцию на множество событий

    хотя по последнему моменту, в коде типичной react-макаки будет создаваться по тысяче функций на каждый чих и никто особо не парится (код то работает на девайсах юзера, за оперативку, проц и электричество платят юзеры, а не те кто свои поделия клепает)
    Ответ написан
    Комментировать
  • Как создают панорамные сайты с возможностью 360° вращения вокруг объекта?

    bingo347
    @bingo347
    Crazy on performance...
    Здесь самое настоящее 3D на webgl.
    Создаётся сфера, на неё натягивается текстура - та самая фотка, камера размещается в центре сферы и вращается по событиям мыши.
    Ну и фотка должна быть специально для этого снята, такое умеют 3D камеры.
    Ответ написан
    2 комментария
  • Возможно ли организовать сеть таким образом (схема)?

    bingo347
    @bingo347
    Crazy on performance...
    У меня ровно такая схема как на картинке, с уточнением, что роутер 1 и роутер 2 имеют разные подсети.
    В качестве роутера 1 используется мини пк с 4 ethernet, в 2 подключены 2 провайдера между которыми балансируется нагрузка, 2 других объеденены в бридж и рулят подсетью 192.168.32.0/28 и 1 идет в WAN порт роутера 2, а второй в мой рабочий комп.
    В качестве роутера 2 - обычный бытовой роутер, для WiFi и тд, он рулит подсетью 192.168.0.0/19 рабочий комп к нему так же подключен второй сетевухой, дабы иметь доступ в локалку.
    Ответ написан
    1 комментарий
  • Как в код сервера axum внести счётчик ответов на запросы клиента из браузера?

    bingo347
    @bingo347
    Crazy on performance...
    https://doc.rust-lang.org/std/sync/atomic/struct.A...

    use std::sync::atomic::{AtomicU32, Ordering};
    
    async fn create_user(
        Json(payload): Json<FromBrowser>,
     ) -> (StatusCode, Json<User>) {
        static COUNTER: AtomicU32 = AtomicU32::new(0);
    
        // подготавливаю данные на отправку в браузер:
        let user = User {
           id: payload.id,
           username: payload.username,
           tm: payload.tm,
           cnt: COUNTER.fetch_add(1, Ordering::SeqCst),   // считаю отправки; 
        };
    
        (StatusCode::CREATED, Json(user))
     }
    Ответ написан
    1 комментарий
  • Как инициировать скрипт при определенной ширине экрана?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Во-первых, стоит убедится, что запрос матчится, во-вторых возможно имеет смысл запускать скрипт по событию change
    Ответ написан
    Комментировать
  • Как скрыть подключение прокси/впн на пк?

    bingo347
    @bingo347
    Crazy on performance...
    Если речь о прокси, то скрыть его от конечного приложения никак, разве что превратить в псевдовпн через tun2socks

    А вот vpn уже можно поднять на отдельной машине (например взять у того же хостера самую дешевую виртуалку), поднять между машинами vlan (многие хостеры делают его между машинами одного пользователя) и завернуть на целевой машине весь трафик в этот vlan + прописать на интерфейсе ip виртуалки в качестве шлюза. А на виртуалке уже завернуть весь или только нужный трафик в vpn.

    Ну и как отметили выше, ничего не поможет если сервису не нравится ip vpn
    Ответ написан
    Комментировать
  • Слайс на неинициализированную память?

    bingo347
    @bingo347
    Crazy on performance...
    MaybeUninit под капотом - это union, то есть компилятор ничего не знает, инициализированное там значение или нет и перекладывает эту ответственность на программиста. А значит UB здесь не будет.
    То есть спокойно делаете &mut [MaybeUninit<*mut State>], инициализируете элементы и после std::mem::transmute в &mut [*mut State]
    Ответ написан
    2 комментария
  • Как заменить $('#more').ready(function() { на чистом js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    document.addEventListener('DOMContentLoaded', () => {
        // ...
    }, {once: true});
    Ответ написан
    2 комментария
  • Возможно ли собрать данные из итератора в уже созданный буфер?

    bingo347
    @bingo347
    Crazy on performance...
    let arr: [i32; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let mut arr2: [i32; 10] = [0; 10];
    
    arr.iter()
        .zip(arr2.iter_mut())
        .filter(|(el, _)| **el % 2 == 0)
        .for_each(|(el, target)| {
            *target = *el;
        });
    Ответ написан
    Комментировать
  • Почему на многих крупных сайтах не используются смысловые теги main,section, article, aside, header, footer?

    bingo347
    @bingo347
    Crazy on performance...
    Во-первых, по тому что большинство разработчиков работает чисто чтоб закрывать задачки в джире, и напрягать голову сверх задачи не видит смысла.
    Во-вторых, менеджеры порой на задачи ставят такие сроки, что напрягать голову особо и нет времени, тяп ляп и в продакшн.
    В-третьих, большинству бизнеса, который вкладывает в разработку сайта деньги, это нафиг не сдалось. Если сам бизнесмен не имеет ни каких ограничений по здоровью во взаимодействии с сайтом (а именно ради этого нужна семантическая разметка, а не ради какого-то СЕО), то вот он потыкал успешно пальцем на своём ойФоне - сайт работает, значит ок, зачем выделять деньги на большее.

    То, что кто-то совсем не сможет пользоваться сайтом имея ограничения по зрению или со сломанной рукой или с ребёнком на руках - никого в этой цепочке не волнует.
    Да банально попробуйте купить мышку онлайн не пользуясь мышкой/тачпадом/тачскрином. Но при этом мышки успешно продаются, а значит ничего меняться не будет.
    Ответ написан
  • Как исправить ошибку error: linking with `link.exe` failed: exit code: 1120?

    bingo347
    @bingo347
    Crazy on performance...
    Попробуйте добавить build скрипт (файл build.rs на том же уровне где Cargo.toml) со следующим содержимым:
    fn main() {
        println!("cargo:rustc-link-lib=dylib=Gdi32.dll");
    }
    Ответ написан