2017-10-19 7 views
0

Je souhaite que les demandes expirent après un certain temps, disons 20 secondes. Si l'application prend plus de 20 secondes pour envoyer une réponse, Phoenix devrait annuler l'exécution et répondre immédiatement avec une erreur (de préférence un HTTP 503).Configurer le délai d'attente de demande à Phoenix?

J'ai parcouru les documents de Phoenix, mais je n'ai trouvé aucune mention d'une option de délai d'attente de demande. Il semble que Cowboy a une option :timeout, que j'essayé de placer 10 ms, mais il encore permis une demande de prendre 8951 ms:

config :app, SomeApp.Endpoint, 
    http: [port: 4000, timeout: 10] 

Il se trouve la documentation de cow-boy définissent cette option comme:

Temps en ms sans requêtes avant que Cowboy ne ferme la connexion.

ce qui n'est pas ce que je cherche.

Est-il possible de définir un délai d'attente de demande dans Phoenix?

Répondre

1

Ceci n'est en aucun cas une responsabilité du web-server/framework. Cowboy n'a aucune idée (et il ne devrait pas avoir!) Sur ce qui se passe dans l'application, il sert les connexions. Phoenix pourrait prendre soin de cela, mais cela violerait SRP. Après tout, le délai d'attente mentionné ci-dessus concerne davantage la logique métier. Imaginez que cowboy/phoenix essaye de gérer le timeout: que se passe-t-il avec le gestionnaire en cours d'exécution? Cela dit, l'application devrait gérer ce type de délai d'attente et c'est relativement facile: il suffit d'envelopper l'exécution sous-jacente dans la tâche avec un délai que vous voulez. De cette façon, il serait flexible, fiable et vous pourriez spécifier quels contrôleurs/actions devraient se comporter de cette façon, et lesquels ne devraient pas.

Dans un pseudo-code (c'est un vrai code, mais je ne le tester):

def create(conn, params) do # or any other action 
    fn -> prepare_result end 
    |> Task.async() 
    |> Task.yield(10) # ⇐ HERE!!! 
    |> case do 
    {:ok, result} -> # success 
     conn 
     |> put_status(200) 
     |> json(%{ok: result}) 
    nil -> # not finished yet; do smth with the task itself! 
     conn 
     |> put_status(503) 
     |> json(%{error: :timeout}) 
    {:exit, reason} -> # should not happen [see Task.yield/2 docs] 
     conn 
     |> put_status(500) # internal server error; unexpected 
     |> json(%{error: reason}) 
    end 
end 

Task.yield/2.


Sidenote: bien sûr, si vous avez besoin de ce comportement dans toute l'application, déclare juste une macro faisant cela, ou comme.

+0

Sidenote: SRP = Principe de responsabilité unique. https://en.wikipedia.org/wiki/Single_responsibility_principle – raarts

+0

@raarts merci, je pensais que cet acronyme est largement connu; Je mets le lien directement dans la réponse. – mudasobwa