Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2016-02-06T09:35:48+01:00Les derniers messages parus sur le forum de Zeste de Savoir.Arrêter l'exécution de coroutines via une websocket, message #976742016-02-06T09:35:48+01:00Javier/@Javierhttps://zestedesavoir.com/forums/sujet/4630/arreter-lexecution-de-coroutines-via-une-websocket/?page=1#p97674<p>Clairement y'a un problème de compréhension dans ton post. Si tu arrêtes une event-loop, au mieux il t'engueule (et il a raison), au pire il cesse complètement de fonctionner.</p>
<p>Pour prendre un parallèle un peu foireux : c'est comme si, pour tuer un processus en particulier, tu disais au processeur : "éteins ton ordonnanceur".</p>
<p>La solution du "flag" positionné par ailleurs est souvent celle que j'utilise pour résoudre ce genre de soucis.</p>Arrêter l'exécution de coroutines via une websocket, message #973612016-02-04T10:44:53+01:00inso/@insohttps://zestedesavoir.com/forums/sujet/4630/arreter-lexecution-de-coroutines-via-une-websocket/?page=1#p97361<p>Salut,</p>
<p>Je vois deux solutions à ton problème. La première est d'annuler la coroutine démarrée dans la loop asyncio à la place de réaliser un <code>loop.stop</code>. Il faut garder la task quelquepart d'accessible pour ton <code>ChargeSMTPSocket</code> puis faire un <code>task.cancel()</code>. Attention à attraper l'exception <code>CancelledException</code> qui risque d'être lancée au niveau de ton <code>loop.run_until_complete(...)</code>.</p>
<p>L'autre solution, que je trouve plus propre, est d'avoir une variable <code>must_stop</code> à <code>False</code> tant que ta boucle infinie tourne. Ton <code>ChargeSMTPSocket</code> pourrait alors la faire passer à <code>True</code>, la boucle s'arrêterait alors d'elle même.</p>
<p>Ton post est ancien, ça m'intéresse de savoir comment tu as fait finalement ?</p>Arrêter l'exécution de coroutines via une websocket, message #861502015-11-13T12:31:48+01:00artragis/@artragishttps://zestedesavoir.com/forums/sujet/4630/arreter-lexecution-de-coroutines-via-une-websocket/?page=1#p86150<p>Bonjour,</p>
<p>cela fait pas mal de temps que je galère sur un problème et j'ai besoin d'un regard neuf si ce n'est d'une solution à mon problème.</p>
<p>Côté techno j'utilise : </p>
<ul>
<li>python 3</li>
<li>tornado</li>
<li>asyncio</li>
</ul>
<div class="information ico-after">
<p>Je ne suis même pas sûr de bien concevoir la chose, alors si vous pensez qu'il faut que je revoie ma manière de faire, je le ferai</p>
</div>
<p>J'ai un projet dans ma boîte, qui me demande d'envoyer un certain nombre de documents, soit par mail soit selon d'autres méthodes (mais pour l'instant gardons le mail, c'est plus simple) et d'observer les réponses des serveur qui recevront les documents.</p>
<p>Comme l'observation des réponses doit se faire "en temps réel", j'ai donc choisi cette architecture :</p>
<ol>
<li>affichage du portail de configuration des envois + ouverture d'une websocket</li>
<li>appui sur le bouton de soumission du formulaire -> envoie d'une requête POST en ajax</li>
<li>à chaque réponse du serveur (rejet du mail, acceptation mise en quarantaine) on affiche dynamiquement cette réponse</li>
</ol>
<p>Mon "architecture" marche très bien quand je connais à l'avance le nombre de documents/mails que je dois envoyer.</p>
<p>Par contre on me demande de pouvoir faire un "envoi à l'infini jusqu'à ce qu'on appui sur "stop" ou que la connexion soit perdue".</p>
<p>Je fais donc ceci :</p>
<h3>le handler du post</h3>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46</pre></div></td><td class="code"><div class="codehilite"><pre><span class="k">class</span> <span class="nc">ChargeSMTPHandler</span><span class="p">(</span><span class="n">RequestHandler</span><span class="p">):</span>
<span class="n">env</span> <span class="o">=</span> <span class="n">Environment</span><span class="p">(</span><span class="n">loader</span><span class="o">=</span><span class="n">FileSystemLoader</span><span class="p">(</span><span class="n">join</span><span class="p">(</span><span class="n">dirname</span><span class="p">(</span><span class="n">__file__</span><span class="p">),</span> <span class="s">"templates"</span><span class="p">)))</span>
<span class="n">nb_recipients</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">nb_recipients_min</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">nb_recipients_max</span> <span class="o">=</span> <span class="mi">0</span>
<span class="nd">@asynchronous</span>
<span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">"""lauch email charge</span>
<span class="sd"> :param args:</span>
<span class="sd"> :param kwargs:</span>
<span class="sd"> :return:</span>
<span class="sd"> """</span>
<span class="n">context</span> <span class="o">=</span> <span class="p">{</span><span class="s">"pending"</span><span class="p">:</span> <span class="bp">True</span><span class="p">}</span>
<span class="n">data_json</span> <span class="o">=</span> <span class="n">json_decode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">body</span><span class="p">)</span>
<span class="n">server</span><span class="p">,</span> <span class="n">port</span> <span class="o">=</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'server'</span><span class="p">),</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'port'</span><span class="p">)</span>
<span class="n">from_addr</span><span class="p">,</span> <span class="n">to_addr</span> <span class="o">=</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'from'</span><span class="p">),</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'to'</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">)</span>
<span class="n">nb_threads</span> <span class="o">=</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'nb_threads'</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">finish</span><span class="p">()</span>
<span class="k">if</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"type_nb_rec"</span><span class="p">)</span> <span class="o">==</span> <span class="s">"nb"</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"nb_rec"</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients_min</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"nb_rec_1"</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients_max</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients_min</span><span class="p">,</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"nb_rec_2"</span><span class="p">))</span>
<span class="k">if</span> <span class="n">data_json</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">"mode_param"</span><span class="p">)</span> <span class="o">==</span> <span class="n">MODE_RAND_INFINITE</span><span class="p">:</span>
<span class="n">ChargeSMTPHandler</span><span class="o">.</span><span class="n">charge_randomly_infinite</span><span class="p">(</span><span class="n">data_json</span><span class="p">[</span><span class="s">"corpus"</span><span class="p">],</span> <span class="n">server</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span>
<span class="n">from_addr</span><span class="p">,</span> <span class="n">to_addr</span><span class="p">,</span> <span class="n">nb_threads</span><span class="p">,</span>
<span class="n">nb_recipients</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients</span><span class="p">,</span>
<span class="n">nb_recipients_min</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients_min</span><span class="p">,</span>
<span class="n">nb_recipients_max</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">nb_recipients_max</span><span class="p">,</span>
<span class="n">mail_from</span><span class="o">=</span><span class="n">data_json</span><span class="p">[</span><span class="s">"from"</span><span class="p">],</span>
<span class="n">rcpt_to</span><span class="o">=</span><span class="n">data_json</span><span class="p">[</span><span class="s">"to"</span><span class="p">],</span>
<span class="n">helo</span><span class="o">=</span><span class="n">data_json</span><span class="p">[</span><span class="s">"helo"</span><span class="p">])</span>
<span class="nd">@staticmethod</span>
<span class="k">def</span> <span class="nf">charge_randomly_infinite</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">server</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">from_addr</span><span class="p">,</span> <span class="n">to_addrs</span><span class="p">,</span> <span class="n">nb_threads</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">corpus</span> <span class="o">=</span> <span class="p">[</span><span class="n">join</span><span class="p">(</span><span class="n">SAMPLE_DIR</span><span class="p">,</span> <span class="n">mail_file</span><span class="p">)</span> <span class="k">for</span> <span class="n">mail_file</span> <span class="ow">in</span> <span class="n">data</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span><span class="o">.</span><span class="n">run_until_complete</span><span class="p">(</span><span class="n">send_corpus_mails_infinite</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">from_addr</span><span class="p">,</span> <span class="n">to_addrs</span><span class="p">,</span> <span class="n">handle_mail</span><span class="p">,</span> <span class="n">nb_threads</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="o">*</span><span class="n">corpus</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
<span class="k">pass</span>
</pre></div>
</td></tr></table>
<p>Puis, dans ma websocket je mets :</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27</pre></div></td><td class="code"><div class="codehilite"><pre><span class="k">class</span> <span class="nc">ChargeSMTPSocket</span><span class="p">(</span><span class="n">WebSocketHandler</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="c">#init</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">on_close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c"># todo: close as on_message("stop")</span>
<span class="k">pass</span>
<span class="k">def</span> <span class="nf">on_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">message</span> <span class="o">==</span> <span class="s">"stop"</span><span class="p">:</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_event_loop</span><span class="p">()</span>
<span class="k">if</span> <span class="n">loop</span><span class="o">.</span><span class="n">is_running</span><span class="p">():</span>
<span class="n">loop</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span>
<span class="n">loop</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">"No mail was being sent."</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">"Unknown message recieved : "</span> <span class="o">+</span> <span class="n">message</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">write_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">binary</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<span class="c">## render</span>
<span class="k">pass</span>
</pre></div>
</td></tr></table>
<p>Seulement deux problèmes s'offrent à moi :</p>
<ul>
<li>dans la version que je viens de donner, la boucle ne s'arrête pas (dans une ancienne, elle s'arrêtait mais impossible de la redémarrer ou alors le serveur s'éteignait)</li>
<li>python me dit qu'on ne peut pas "close a running event loop"</li>
</ul>
<p>En fait, il faudrait que je génère un événement qui dise à la loop "arrête ce que tu es en train de faire maintenant" mais je n'arrive pas à le faire.</p>