namespace AppEventListener;\n\nuse PsrLogLoggerInterface;\nuse SymfonyComponentHttpKernelEventTerminateEvent;\nuse SymfonyComponentRoutingRouterInterface;\n\nclass HeavyTaskListener\n{\n \/**\n * @var RouterInterface\n *\/\n private $router;\n \/**\n * @var LoggerInterface\n *\/\n private $logger;\n\n public function __construct(RouterInterface $router, LoggerInterface $logger)\n {\n $this->router = $router;\n $this->logger = $logger;\n }\n\n\n public function onKernelTerminate(TerminateEvent $event)\n {\n \/\/ Ci facciamo dire qual \u00e8 la route dell'attuale richiesta.\n $currentRoute = \n$this->router->match($event->getRequest()->getPathInfo());\n if ('perform_heavy_task' === $currentRoute['_route']) {\n \/\/ Siamo nella route interessata: via con il task.\n $this->logger->info(\"Starting heavy task...\");\n\n \/\/ Complesso task assolutamente cruciale per la buona riuscita del nostro progetto.\n sleep(10);\n\n $this->logger->info(\"*puff puff* Heavy task completed!\");\n }\n }\n}<\/pre><\/td><\/tr><\/tbody><\/table><\/div>Configuriamo il listener in services.yaml\u2026<\/p> <\/colgroup>\u00a0 \u00a0 AppEventListenerHeavyTaskListener<\/span>:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0arguments:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0- '@router'\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0- '@logger'\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0tags:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0- { name: kernel.event_listener, event: kernel.terminate }<\/pre><\/td><\/tr><\/tbody><\/table><\/div>…con la action di prima che modifichiamo cos\u00ec.<\/p> <\/colgroup>\u00a0 \u00a0 public function performHeavyTask(LoggerInterface $logger)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0 $logger->info(\"Sending response...\");\n\n\u00a0\u00a0\u00a0\u00a0 return $this->json(['message' => 'About to perform the heavy task!']);\n\u00a0\u00a0\u00a0\u00a0}<\/pre><\/td><\/tr><\/tbody><\/table><\/div>Proviamo il tutto, e vediamo subito la differenza: questa volta la risposta viene mandata immediatamente, e soltanto in seguito il task viene lanciato e completato.<\/p> <\/colgroup>[2020-03-09 19:50:44] request.INFO: Matched route \"perform_heavy_task\"...\n[2020-03-09 19:50:44] app.INFO: Sending response... [] []\n[2020-03-09 19:50:44] app.INFO: Starting heavy task... [] []\n[2020-03-09 19:50:54] app.INFO: *puff puff* Heavy task completed! [] []<\/pre><\/td><\/tr><\/tbody><\/table><\/div>Molto meglio!<\/strong><\/p>In chiusura, qualche nota su questo evento.<\/p> Come detto, gli eventi del componente HttpKernel, come appunto il kernel.terminate, vengono lanciati durante l\u2019elaborazione di tutte le richieste ricevute dall\u2019applicazione, per cui bisogna implementare un sistema per \u201criconoscere\u201d la richiesta nel listener. Nell\u2019esempio abbiamo usato il riconoscimento della route, ma ovviamente non \u00e8 l\u2019unica tecnica possibile: un\u2019altra possibilit\u00e0 \u00e8 usare un servizio, iniettato sia nel controller che nel listener, che tenga traccia dello stato della richiesta. Questo \u00e8 un ottimo modo, fra l\u2019altro, per passare dati fra il controller e il listener.<\/p><\/li> Dato che la risposta viene spedita prima dell\u2019avvio del listener, si capisce che il client nessuna informazione riguardo un eventuale fallimento del task svolto nel listener stesso. Se \u00e8 importante notificare gli errori al chiamante, dovremo ingegnarci per farglieli avere in un altro modo, ad esempio con una email.<\/span><\/p><\/li>Al momento in cui scrivo, soltanto i server PHP-FPM sono in grado di continuare l\u2019elaborazione della richiesta dopo l\u2019invio della risposta: se il nostro server non utilizza questa tecnologia, il listener girer\u00e0, ma la risposta arriver\u00e0 al client solo alla fine dell\u2019elaborazione, rendendo di fatto inutile l\u2019evento.<\/p><\/li><\/ul> Al di l\u00e0 di queste precisazioni, abbiamo visto come con kernel.terminate possiamo velocizzare le chiamate lato client senza per questo doverci affidare ad altri servizi o tecnologie.<\/strong><\/p>Quindi facciamo la gioia dei nostri client! Affidiamo i nostri task troppo pesanti ai listener! E non dimentichiamoci il motto che ogni sviluppatore che si rispetti dovrebbe avere: se c\u2019\u00e8 del lavoro che pu\u00f2 essere rimandato, rimandalo.
Andrea Cioni<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":" Sei uno sviluppatore o una sviluppatrice web\/server? Lavori in PHP, magari su Symfony? Ti trovi in difficolt\u00e0 nello sviluppo di una o pi\u00f9 applicazioni perch\u00e9 ci sono alcune richieste che devono svolgere operazioni molto pesanti e finiscono per avere tempi di risposta lunghissimi? Sei in crisi perch\u00e9 non sai come consegnare i quattro progetti che […]<\/p>\n","protected":false},"author":1,"featured_media":8075,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"footnotes":""},"categories":[57],"tags":[],"class_list":["post-23765","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sviluppo-software"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/posts\/23765","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/comments?post=23765"}],"version-history":[{"count":1,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/posts\/23765\/revisions"}],"predecessor-version":[{"id":24298,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/posts\/23765\/revisions\/24298"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/media\/8075"}],"wp:attachment":[{"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/media?parent=23765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/categories?post=23765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/odc.oimmei.dev\/it\/wp-json\/wp\/v2\/tags?post=23765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}
| | | |