2 Stimmen

Warum ist es nicht möglich, mehr als Nachrichten (Strings) an gegabelte Unterprozesse zu senden?

Die Frage

Warum ist es in NodeJS nicht möglich, mehr als Nachrichten (Strings) an geforkte Unterprozesse zu senden? Diese Antwort besagt einfach, dass es nicht möglich ist, erklärt aber nicht warum.

Wie ist diese Frage entstanden

Ich muss Datenbankverbindungen an Unterprozesse senden, um zu verhindern, dass mehrmals eine Verbindung zu diesen Datenbanken hergestellt wird.

Mein Programm verbindet sich mit vier verschiedenen Diensten: Redis, OrientDB, Postgres und ElasticSearch.

Ich leiste schwere Arbeit und muss mehrere Prozesse verwenden und alle Prozesse mit diesen Diensten verbinden. Ich habe ein Objekt erstellt, um all diese Clients zu halten:

var clients = {
    redisClient: /* redis Verbindung */
    orientClient: /* orientdb Verbindung */
    pgClient: /* postgres Verbindung */
    elasticClient: /* elasticsearch Verbindung */
};

Aber wenn ich die Clients an Unterprozesse sende:

var child = cp.fork(__dirname + '/singleCrawler.js');
child.send(clients);

Bekomme ich den folgenden Fehler:

TypeError: Kreisförmige Struktur wird zu JSON umgewandelt
    at Object.stringify (native)
    at ChildProcess.target.send (child_process.js:451:23)

Ich bin nicht der einzige, der dieses Problem hat.

Meine Lösung für das Problem

Ich werde einen anderen Prozess starten, der die Dienste behandelt. Die anderen Prozesse werden mit diesem Prozess kommunizieren, um mit den Diensten zu interagieren.

1voto

Laurent Perrin Punkte 14279

Der Grund, warum Sie kein beliebiges JavaScript-Objekt an einen Kindprozess übergeben können, liegt darin, dass er einen komplett separaten V8-Prozess ausführt, der keinen Speicher mit dem Elternprozess teilt.

In Ihrem Fall würde ich für jeden Prozess einen separaten Satz Verbindungen öffnen. Da Sie nicht Hunderte von Node-Prozessen haben werden, wird dies keine enorme Belastung für Ihre dbs sein und Ihren Code vereinfachen.

(Abseits)

Tatsächlich gibt es eine Ausnahme, was Sie an einen anderen Prozess übergeben können: Sie können einen Dateideskriptor übergeben:

child.send(message, [sendHandle])

Die sendHandle-Option für child.send() dient zum Senden eines TCP-Servers oder Socket-Objekts an einen anderen Prozess. Das Kind wird das Objekt als sein zweites Argument für das message-Ereignis erhalten.

Dies wird vom Cluster-Modul verwendet. Das ist in Ihrem Fall nicht sehr nützlich, aber ich dachte, ich würde das erwähnen :)

1voto

robertklep Punkte 195047

Ein Grund, warum das nicht möglich ist, liegt darin, dass es nicht trivial ist: Wenn Sie eine Verbindung zu Redis hätten, die von mehreren Prozessen gemeinsam genutzt wird, wie würden gleichzeitige Lese-/Schreibvorgänge behandelt werden?

Zumindest bei Unix-ähnlichen Betriebssystemen können Dateideskriptoren zwischen Prozessen übergeben werden, aber das löst nicht das Problem der gleichzeitigen Zugriffe. Es ist auch sehr Low-Level und jeder Node-Treiber (Redis, OrientDB, Postgres, ElasticSearch) müsste irgendwie unterstützen, einen Dateideskriptor übergeben zu bekommen (was sie nicht tun, und ich frage mich, ob es überhaupt möglich ist).

Ihre Lösung mit einem Prozess, der alle Datenbankverbindungen verwaltet, ist eine gute Lösung, obwohl ich mich frage, warum ein paar zusätzliche Datenbankverbindungen ein so großes Problem sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X