Clojure - eine Reihe von HTTP-Anfragen parallel ausführen - pmap?

8

Ich muss 200 oder so HTTP-Anfragen machen. Ich möchte, dass sie parallel oder stapelweise laufen, und ich bin nicht sicher, wo ich anfangen soll, um das in Clojure zu machen. pmap scheint den gewünschten Effekt zu haben, zum Beispiel mit http.async.client:

%Vor%

Aber ich kann nicht beweisen, dass die Anfragen tatsächlich parallel ausgeführt werden. Muss ich die Thread-APIs der JVM aufrufen? Ich suche herum und komme mit anderen Bibliotheken wie Netty, Lamina, Aleph - sollte ich eines davon verwenden? Bitte weisen Sie mich einfach in die richtige Richtung, um etwas über die beste Praxis / einfachste Lösung zu erfahren.

    
Rob Lourens 30.01.2014, 05:53
quelle

3 Antworten

7

Was Sie beschreiben, ist eine vollkommen gute Verwendung von pmap , und ich würde es auf ähnliche Weise angehen.

Soweit es "beweist", dass es parallel läuft, müssen Sie darauf vertrauen, dass jede Iteration von pmap die Funktion in einem neuen Thread ausführt. Ein einfacher Weg, um sicher zu sein, ist einfach die Thread-ID als Plausibilitätsprüfung auszudrucken:

%Vor%

Da die Thread-Nummern tatsächlich unterschiedlich sind - was bedeutet, dass Clojure jedes Mal einen neuen Thread erstellt - können Sie sicher sein, dass die JVM Ihren Code parallel ausführt.

Sehen Sie sich auch andere parallele Funktionen wie pvalues ​​ und pcalls . Sie geben Ihnen unterschiedliche Semantiken und könnten je nach Problem die richtige Antwort sein.

    
leonardoborges 30.01.2014, 06:12
quelle
11

Idealerweise wollen Sie keinen Thread verknüpfen, der auf das Ergebnis jeder HTTP-Anfrage wartet, also sind pmap oder andere threadbasierte Ansätze keine wirklich gute Idee.

Was Sie wirklich tun möchten, ist:

  • Alle Anfragen asynchron absetzen
  • Warte auf die Ergebnisse mit nur einem Thread

Mein vorgeschlagener Ansatz besteht darin, Ссылка zu verwenden, um alle asynchronen Anforderungen auf einmal abzusetzen und eine Abfolge von Versprechen zu erstellen. Sie müssen dann alle diese Versprechen in einem einzigen Thread dereferenzieren, was den Thread blockiert, bis alle Ergebnisse zurückgegeben sind.

Etwas wie:

%Vor%     
mikera 31.01.2014 06:03
quelle
0

Sieh dir Claypoole an. Beispielcode:

%Vor%

Der Grund, warum Sie in diesem Fall com.climate.claypoole/pmap über clojure.core/pmap bevorzugen sollten, ist, dass letzterer die Anzahl der Threads basierend auf der Anzahl der CPUs festlegt und nicht überschrieben werden kann. Bei Netzwerk- und anderen E / A-Vorgängen, die nicht an die CPU gebunden sind, möchten Sie die Anzahl der Threads in der Regel basierend auf der gewünschten E / A-Anzahl und nicht basierend auf der CPU-Kapazität festlegen.

Oder verwenden Sie einen nicht blockierenden Client wie Ссылка , für den kein Thread pro Verbindung erforderlich ist, wie < a href="https://stackoverflow.com/a/21473485/108326"> vorgeschlagen von mikera .

    
markusk 06.04.2016 07:35
quelle

Tags und Links