LINUX.ORG.RU

Eping - модуль для node.js. Нормально ли пишу или руки надо оторвать?

 ,


0

1

Собираюсь на досуге поделать (в образовательных целях) свою маленькую систему мониторинга управляемых коммутаторов на node.js. Решил начать с простого — ICMP пинговалки, обновляющей состояния узлов в Redis. Так как рабочего модуля для ноды не оказалось, то написал свой. C++ я не знаю, вообще програмирую редко и мало, поэтому прошу глянуть в мой код и ткнуть носом в жуткие ошибки, чтобы потом не было мучительно больно. Если кому-то пригодится этот модуль, пожелания и предложения приветствуются.


Всегда лучше оторвать.

printf... C++... facepalm...

struct sockaddr r_addr;... struct... C++... facepalm...

typedef struct... C++... facepalm...

Ты вообще определись - ты на С++ пишешь или на С. Если на С - выкинь std::vector и пиши на С.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

Ты вообще определись - ты на С++ пишешь или на С.

И как же мне определиться? libuv и сокеты — чисто сишные, v8 и node — на плюсах. В чём проблема смешения? Я всегда думал, что плюсы — это синтаксический ООП сахар для си. Вот как мне всё это на чистом C++ сделать? Как, например, динамический (не статический метод класса, виртуальный?) метод объекта передать в качестве колбэка в libuv?

Zveroy
() автор топика
Ответ на: комментарий от Zveroy

Я всегда думал, что плюсы — это синтаксический ООП сахар для си

это настолько толсто, что в хромиуме верстку страницы порвало

stevejobs ★★★★☆
()

Можно после всех вызовов printf делать fflush, или даже сделать функцию-обёртку над printf с __attribute__(((format(printf, 1, 2))))

quiet_readonly ★★★★
()
Ответ на: комментарий от Zveroy

В чём проблема? Только аргуменитровано.

Асинхронный код на калбаках всегда выглядит сломанным. А то что выглядит сломанным скорее всего действительно сломано.

Колбаки — самый идиотский способ организации concurrency.

Ну а js — язык, который вообще создавали для… ну явно не для написания приложений.

PolarFox ★★★★★
()
Ответ на: комментарий от Zveroy

Я всегда думал, что плюсы — это синтаксический ООП сахар для си.

А теперь перестань так думать. Один и тот же код, написанный на С и на С++ будет выглядеть очень по разному. Если ты пишешь код для С++ компилятора, то пиши на С++, а не на С.

Pavval ★★★★★
()
Ответ на: комментарий от trashymichael

а чем exec «ping» не устроил?

Две-три тысячи (да столько коммутаторов в моей маленькой сети) exec'ов, пусть даже раз в десять секунд, слишком накладно.

Zveroy
() автор топика
Ответ на: комментарий от DELIRIUM

std::memfun_ptr

Вы имели в виду std::mem_fun_ptr? Я никак не могу найти внятную документацию на эту штуку. В гугле оно встречается почему-то неизменно в связке с MSVC, а найденые примеры мутны до безобразия.

Zveroy
() автор топика
Ответ на: комментарий от quiet_readonly

Я не совсем понял, к чему это было сказано. printf используется только для отладочного вывода, и во время штатной работы весь ввод/вывод происходит только через сырые сокеты. Но про fflush запомню.

Zveroy
() автор топика
Ответ на: комментарий от PolarFox

Асинхронный код на калбаках всегда выглядит сломанным.

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

Колбаки — самый идиотский способ организации concurrency.

Поэтому в ноде есть EventEmitter, promises и другие полезные штуковины.

Ну а js — язык, который вообще создавали для… ну явно не для написания приложений.

JS вполне себе полноценный тьюринг-полный язык программирования, не без проблем конечно, поэтому я использую CoffeeScript.

Zveroy
() автор топика
Ответ на: комментарий от Pavval

Если ты пишешь код для С++ компилятора, то пиши на С++, а не на С.

Но почему? Бох накажэ или где? Мне нравится чистый и незамутнённый C, при этом я не прочь использовать некоторые полезности из C++, облегчающие жизнь. Компилятор же меня понимает, и даже предупреждениями (warnings) не сыпет по этому поводу.

Zveroy
() автор топика

А ничё что для пинга нужен рут? Есть клевый способ проверяния поднятости узла полученим ECONNREFUSED при попытке установить соединение на заведомо закрытый порт. Жаль некоторые дурные л3 свичи не отдают такой ошибки Т_Т

redixin ★★★★
()
Ответ на: комментарий от redixin

А ничё что для пинга нужен рут?

Точнее не для пинга, а для открытия raw socket. Я в курсе. В моём случае это не принципиально, так как пинговалка взаимодействует только с локально запущенной Redis. Но вообще я подумываю над тем, как лучше организовать изоляцию. Может просто открывать один раз сокет, а потом переключаться на непривелигированого пользователя? Ещё я слышал, что вроде бы есть какой-то механизм в ядре (Linux), позволяющий выдавать приложению только определённые права рута, вот только не помню как это зовётся, и есть ли там вообще возможность дать права на открытие сокетов.

Есть клевый способ проверяния поднятости узла полученим ECONNREFUSED при попытке установить соединение на заведомо закрытый порт.

ICMP echo позволяет получить несколько больше информации, чем просто доступность узла.

Жаль некоторые дурные л3 свичи не отдают такой ошибки Т_Т

У меня тот ещё зоопарк.

Zveroy
() автор топика
Ответ на: комментарий от Zveroy

Не, я имел в виду std::memfun, но ошибся. Как сишный коллбек ты его не заюзаешь. Если прям надо звать метод объекта в качестве сишного коллбека, то можно сделать функцию, которая принимает указатель на объект как аргумент и зовёт его метод. Если прям нужен доступ к внутренностям, то можно её объявить как friend для этого класса.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

В итоге я приблизительно так и сделал. Объявил статические методы класса, и передаю именно их в качестве колбэка. Но всё-равно конструкция

void MyObject::on_event (uv_nandler_t *ref, int arg1, int arg2) {
  MyObject *self = (MyObject *) ref->data;
  self->doSomething(ref, arg1, arg2);
}
меня малость вымораживает, учитывая, что нужно делать такую обвязку для каждого колбэка, и нужно обязательно инициализировать ref->data при каждом создании обработчика. Может существет какой-нибудь способ автоматически генерировать адаптеры/делегаторы?

В принципе я себе такой адаптер представляю как маленький кусочек кода хранящийся в памяти объекта, на который можно получить указатель, т.е. C библиотека его может вызвать, а сам он умеет только поправить стек так, чтобы произвести вызов метода объекта, и возврат из метода произошёл прямо туда, откуда был вызван адаптер. Т.е. сигнатуры метода и колбэка совпадают, нужно просто как-то протащить ссылку на this в метод.

Zveroy
() автор топика
Ответ на: комментарий от Zveroy

примерно так:

struct A {
    void f() {}
};

struct B {
    void f() {}
};

#define MAKE_CALLBACK(classname) \
    void classname##_wrapper(classname *obj) {\
        obj->f();\
    }

MAKE_CALLBACK(A);
MAKE_CALLBACK(B);

#undef MAKE_CALLBACK

int main() {
    A a;
    A_wrapper(&a);
}

Можно ещё сделать имя метода параметром и добавить аргументы, но идею, я думаю, ты понял.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от Zveroy

Если программа вылетит, буферы stdout не будут записаны на диск или в консоль. Раз запись идёт только в режиме отладки, то можно fflush'ить не жалеючи. Вот о чём ;0

quiet_readonly ★★★★
()
Ответ на: комментарий от Zveroy

Ах да, в функцию обёртку ещё можно время присобачить, и так же легко убрать, как-то так

#include <sys/time.h>
#include <stdlib.h>
#include <string>

std::string getTimeInAscii()
{
    time_t Time = time(nullptr);
    struct tm *LocalTime = localtime(&Time);

    char Buffer[BUFFER_SIZE];
    size_t Size = strftime(Buffer, SUBBUFFER_SIZE, "%k:%M:%S", LocalTime);

    timeval Timeval;
    if (0 == gettimeofday(&Timeval, nullptr)) { // success
        sprintf(Buffer + Size, ", %3d ms", int(Timeval.tv_usec / 1000));
    }

    return std::string(Buffer);
}
Получает строку вида 8:46:24, 490 ms.

quiet_readonly ★★★★
()
Ответ на: комментарий от Zveroy

Но почему? Бох накажэ или где?

Так, подожди. Ты сюда припёрся для публичного ревью кода. Чего же ты тогда возбухаешь?

Pavval ★★★★★
()
Ответ на: комментарий от quiet_readonly

Если программа вылетит, буферы stdout не будут записаны на диск или в консоль.

Я даже малость засомневался сначала, и проверил. stdout по-умолчанию буфферизируется построчно, stderr вообще не буферизируется. Так что особого смысла fflush'ить и нет вовсе.

Zveroy
() автор топика
Ответ на: комментарий от Pavval

Чего же ты тогда возбухаешь?

Кто возбухает? Где? Покажите мне пальцем этого негодяя!

Мне грозят пальцем и говорят: «Атятя! Так нельзя!», без объяснения причин. Я спрашиваю, почему так, а не иначе. А на ум приходит байка про висящий банан, стремянку и обезьян, которых поливали ледяной водой из шланга. «Потомучто здесь так не принято.»

Zveroy
() автор топика
Ответ на: комментарий от Zveroy

Бох накажэ или где?

фанаты шаблонов и iostream ругаться будут и заснуть не смогут, да и фиг с ними)))

quest ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.