2017-10-01 1 views
0

Je suis perdu avec toutes ces librairies async/multithreaded et capacités clojure natives.allouer le fil par demande clojure

J'ai un webservice qui appelle une API externe, la transforme et répond au client. En ce moment est écrit en Python. Je voudrais laisser chaque client exécuter sa requête dans un thread séparé afin qu'ils n'attendent pas l'un l'autre pour finir, ou que le serveur soit asynchrone. Il n'y a pas de gros calculs impliqués, seulement en attente d'IO.

Je pensais que ce serait facile avec clojure mais il me manque quelque chose ... Aleph est un serveur asynchrone, non? Cependant, lorsque je simule un gestionnaire de requêtes wait, le serveur entier attend, pas seulement le client. Donc, je ne vois pas vraiment l'intérêt d'être asynchrone ici? À mon avis, ce qui peut être faux, est-ce qu'un serveur asynchrone ne bloque jamais pour les opérations d'E/S? Peut être sleep est un mauvais moyen de simuler l'attente d'IO?

EDIT J'ai créé un service d'attente stupide que j'invoque à partir du serveur Aleph de Clojure, et encore, le traitement de la demande est séquentielle

(ns aleph-t.core 
(:require [aleph.http :as http] 
      [aleph.netty :as netty])) 

(defn heavy [] (Thread/sleep 10000) "hello!") 

(defn handler [req] 
    {:status 200 
    :headers {"content-type" "text/plain"} 
    :body (heavy)}) 
; need to wait otherwise server is closed 
(defn -main [& args] 
    (netty/wait-for-close (http/start-server handler {:port 8080})) 
) 

Répondre

3

Lors de l'écriture d'un back-end asynchrone, vous devez garder à l'esprit que vous devez n'utilisez pas les appels de méthode de blocage car ceux-ci bloqueront vos threads de travail asynchrones et ainsi votre backend entier. L'idée de base de la programmation asynchrone est de faire en sorte que vos threads de travail effectuent un travail CPU réel et utilisent des rappels (ou des canaux ou des flux ou des collecteurs, etc.) pour toute autre opération potentiellement bloquante. De cette façon, la programmation asynchrone peut donner à votre application un débit plus élevé.

Dans votre exemple, le (Thread/sleep .) bloque un thread de travail. Lors de l'utilisation de aleph pour HTTP, vous pouvez utiliser la bibliothèque manifold pour les E/S asynchrones.

Il existe quelques examples d'utilisation d'aleph avec collecteur. Par exemple, vous pouvez utiliser les délais d'expiration core.async pour simuler une tâche de longue durée, comme illustré dans this example.