LINUX.ORG.RU

Node.js & Callbacks

 , ,


1

1

Требуется из расширения Node.js на C++ периодически вызывать колбэк в Node.js. Оказалось, что это страшная боль в пятой точке, благодаря чудесной архитектуре v8. Насколько я понял, вызывать нодовские колбэки можно только из главного потока libuv. Если сами события, по которым должен осуществляться вызов, генерируются в других потоках, то делается это примерно так: http://stackoverflow.com/questions/36987273/callback-nodejs-javascript-functi... Вопрос: как это делать эффективно, если само событие генерируется сторонней библиотекой, при этом в качестве параметра передаётся большой массив данных, который и нужно прокинуть колбэку? Копировать этот массив и временно сохранять копию? Сторонняя библиотека, генерирующая событие, тоже с v8, но другой версии нежели в node.js. Или же можно как-то вызвать колбэк из другого потока?

★★★★★

думаю, лучше всего будет организовать ИПЦ между этими библиотеками, независимо запущеными в разных потоках, делая обычный os.exec(«node lib.js --input-file=/tmp/data.json») или (более изящно) подняв сервер на принимающей стороне и отсылая в него запрос (без временной записи данных, быстрее но все равно сущность прокладки останется)

anonymous ()

лезть в апи либува и вскрывать ноды не вижу смысла, с асинхронностью и дебрями движков будет себе дороже. как вариант смержить библиотеки и крутить код в одном потоке на одной ноде, просто передавая данные в между функциями (вызов коллбека). короче говоря, как и в любом случае любого обмена между любыми программами, в чем вопрос ТС??

anonymous ()
Ответ на: комментарий от eao197

Ну, в принципе, в 4-й части описывается хоть и не совсем то, но близко: https://blog.scottfrees.com/c-processing-from-node-js-part-4-asynchronous-addons

О кривизне решения можно судить уже по вот этой конструкции:

struct Work {
  uv_work_t  request;
  Persistent<Function> callback;

  std::vector<location> locations;
  std::vector<rain_result> results;
};

и тому, как она потом используется:

    // kick of the worker thread
    uv_queue_work(uv_default_loop(),&work->request,
        WorkAsync,WorkAsyncComplete);
В NAN есть обертка вокруг всего этого, которая придаёт решению более человеческий вид: https://github.com/nodejs/nan/blob/master/doc/asyncworker.md#api_nan_async_wo... Но основную проблему перекидывания данных между потоками это, к сожалению, не решает... Видимо, придется с ней жить.

asaw ★★★★★ ()
Последнее исправление: asaw (всего исправлений: 1)

ты от этого никуда не уйдешь, тебе надо так делать и это правильно.

Нода — это однотредная софтина, которая умеет работать только и исключительно в одном треде.

То, что ты там что-то где-то схитрил — это молодец, но теперь возвращайся в единственный тред и отдавай данные туда.

Главная причина этого — шаринг данных между тредами. В ноде такого нет. Ты же ведь не обращаешься к данным в ноде из другого треда?

Хочешь полный мультикор — бери erlang или совсем на крайний случай какую-нибудь жабку. Но лучше конечно эрланг.

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

как-будто ерланг не в одном треде работает, пфф. очередной советчик категории «спиздануть»

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

А еще фортран програмируют на перфокартах, а компьютрьі ламповьіе. Вчера человек полетел в космос а сегодня карибский кризис

anonymous ()

Слушай анонимуса. Он верно говорит. Конкретнее задачу можно рассказать - не понимаю зачем такие костыли пока.

silver-bullet-bfg ()
Ответ на: комментарий от anonymous

ты смешной такой =)

Эрланг именно что на всех ядрах работает и в нём куча кода по управлению этими тредами.

но тебе этого в школе не расскажут.

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