2015-11-05 5 views
-1

Недавно я начал смотреть на JS и Node.js. Однако мне не понравилось писать код обратного кода, поэтому я начал писать небольшую основу для Node. Я завершил его, но теперь я пытаюсь заставить его работать на многоядерном процессоре с Node Cluster. Проблема в том, что я не могу отправить генератор от мастера к рабочему, поскольку моя инфраструктура основана на генераторах, и я должен заставить рабочих запускать генераторы. Как я могу превратить объект-генератор в JSON, который затем мог бы отправить моим работникам или какой-нибудь другой подход для отправки генератора рабочему? Я попытался просто превратить генератор в JSON, но это привело к пустующему объекту без следующего метода или метода throw.Включите генератор в JSON JS

Вот как пример того, что пинг-понга будет выглядеть так:

Thr.setNumCPUs(require("os").CPUS.length-1) 
//not to have one extra because of the master 
function ping(times){ 
    var chan = new Thr.Chan();//create new channel 
    Thr.spwn(function*(){//start a new thr, on any of the cpus 
     var chan2 = pong(chan); 
     for (var i= 0;i < times;i++){ 
      yield* chan.send("ping, for the "+(i+1)+" timth"); 
      //wait untill chan is empty, then send a value 
      console.log(yield* chan2.rcv()); 
      //wait until received the value 
     } 
     chan.close(); 
     //close the channel so now on can access it 
    } ,[]); 
} 


function pong(chan){ 
    var chan2 = new Thr.Chan(); 
    Thr.spwn(function*(){ 
     var i = 0; 
     while (!chan.closed){ 
      console.log(yield* chan.rcv()); 
      yield* chan2.send("pong, for the "+(++i)+" timth"); 
     } 
     chan2.close(); 
    } ,[]); 
    return chan2; 
} 
if (cluster.isMaster){ 
    ping(5); 
} 
+1

Собственный анализатор JSON не может оценивать функции в JSON, они недействительны. –

+0

Я знаю это, но есть ли другой способ разобрать его или отправить результат другому человеку. Я даже не могу получить функцию * .next к строке. – Coder3000

+0

Вам нужно будет реализовать собственный анализатор JSON (!) –

ответ

0

JSON это формат для serialising данных, а не исполняемых функций *. Чтобы передать генератор в виде JSON, вам действительно нужно выполнить итерацию через генератор, чтобы получить все значения, сохранить их в чем-то вроде массива, а затем просто добавить этот массив к объекту, который вы превращаете в JSON. Вероятно, это удалит любую выгоду от использования генератора, но это легко сделать.

У меня еще не было возможности использовать кластер, но у меня создалось впечатление, что вы можете использовать его для простого запуска разных экземпляров всего узла в качестве кластера, тем самым устраняя необходимость вручную обрабатывать процессы, чтобы использовать несколько процессоры.

Если вам нравится использовать генераторы для асинхронного кода, существует библиотека с именем co, которая делает именно это, что вы, возможно, только что изобрели.

+0

Только для недетерминированных генераторов. Генераторы все еще имеют toString() и могут быть восстановлены с помощью функции GeneratorFunction = Object.getPrototypeOf (function *() {}). constructor; 'передача функции как json проста. Добавление информации о состоянии также будет легким. Генераторы - это просто объекты. – Blindman67

+0

Хорошо, но у меня другой подход, чем использование генераторов в сочетании с обещаниями, у моей библиотеки есть каналы, очень похожие на Golang и CO не многоядерные, библиотека, которую я создал, отлично работает на одном ядре. – Coder3000

+0

Blindman, есть также способ получить код функции генератора, который я могу переключить на JSON после создания объекта-генератора, потому что библиотека принимает объект-генератор, а не функцию *, я мог бы, конечно, изменить так что он принимает функцию и аргументы, большое спасибо. – Coder3000

0

Я действительно знаю, что нашел ответ на свой вопрос после исследования генераторов и комментариев Блиндмана. Первое, что мне нужно сделать, это создать конструктор для генератора: var GeneratorFunctionConstructor = Object.getPrototypeOf(function*(){}).constructor. Затем, когда я отправляю задание одному из рабочих, я создаю объект JSON с функцией * как String и переданными ей аргументами. Затем я создаю новый объект Generator с конструктором, получая аргументы функции * и тела функции *. Затем я вызываю Generator.apply(this,args) и запускаю его асинхронно.

+0

Обратите внимание, что через это вы потеряете все переменные закрытия. Было бы более разумно создавать экземпляр вашей структуры несколько раз (на каждом узле кластера) и передавать данные только не генераторам. – Bergi

+0

Это хорошая идея, но как вы знаете, какой генератор должен передавать какие данные. – Coder3000

+0

Зависит от вашего кода и того, что он делает. Я предполагаю, что вы все равно выполняете межпроцессное общение через каналы? Тогда один подход может состоять в том, чтобы просто создавать все генераторы повсюду и передавать данные только тем, которые должны работать. Или если вы обеспокоены тем, что создавать, где нужно и нужно делать это динамически, тогда поместите все функции генератора в огромный объект, в котором они могут быть идентифицированы по их имени свойства. – Bergi

Смежные вопросы