Ergebnis 1 bis 5 von 5

Thema: Prozess im Controller starten ohne Response-Zeit zu verlängern

  1. #1
    Contao-Nutzer Avatar von agonyz
    Registriert seit
    10.09.2020.
    Beiträge
    36

    Standard Prozess im Controller starten ohne Response-Zeit zu verlängern

    Hallo liebes Forum,

    da mir hier mal ans Herz gelegt wurde, auch mal nachzufragen, wenn man sich bei der Umsetzung eines Vorhabens nicht sicher ist, wollte ich genau dies mal tun.
    Folgendes Problem habe ich gerade.

    Ich habe ein Bundle, welches über einen Cronjob (oder auch ein Command) mehrere asynchrone API-Requests an eine Google API versendet, die im Schnitt zwischen 30-60 Sekunden benötigen.
    Da dies beim Aufruf eines Controllers zu lange dauert, lasse ich im Cronjob/Command eine Cache-Item erzeugen, welches die Responses beinhaltet.

    Soweit so gut und auch funktionell.
    Im Controller prüfe ich dann, ob das Cache-Item vorhanden ist: Bei Fehlkonfiguration gebe ich eine Fehlermeldung aus, bei vorhandenem Item, gebe ich die Responses aus, aber wenn das Cache-Item gerade nicht vorhanden ist, gebe ich einen Text aus, der sagt, dass die Requests gerade generiert werden und der Benutzer noch warten muss.

    Nun ist mein Problem, dass ich keine Möglichkeit habe, zu prüfen, ob dieses Cache-Item gerade durch meinen Cronjob/mein Command generiert wird oder einfach so nicht vorhanden ist.

    Gibt es an dieser Stelle eine Möglichkeit zu prüfen, ob das Command/Der Cronjob oder deren Funktionalität gerade laufen bzw. das Cache-Item gerade generiert wird?

    Als zweite Möglichkeit habe ich versucht das Command bzw. den zugehörigen Service im Controller aufzufrufen, falls das Cache-Item nicht vorhanden ist, aber dann dauert die Response sehr lange.
    Gibt es hier vielleicht eine Möglichkeit den Service quasi im Hintergrund zu triggern und dem Benutzer dennoch eine Response auszugeben, ohne dass dieser so lange warten muss, bis der Service abgeschlossen ist?

    Bei Symfony habe ich dazu den Process-Component gefunden, aber mit diesem habe ich es noch nicht hinbekommen, mein Command zum Laufen zu bekommen (https://symfony.com/doc/current/components/process.html)

    Bin für alle Inputs an dieser Stelle dankbar

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.088
    Partner-ID
    10107

    Standard

    Zitat Zitat von agonyz Beitrag anzeigen
    Gibt es an dieser Stelle eine Möglichkeit zu prüfen, ob das Command/Der Cronjob oder deren Funktionalität gerade laufen bzw. das Cache-Item gerade generiert wird?
    Das müsstest du halt selbst bauen. Also du müsstest selbst irgendwo festhalten, welche Requests gerade verarbeitet werden.

    Vielleicht ist es aber auch am besten, wenn du eine Request Queue (in der Datenbank) implementierst? Das Frontend generiert dann so ein Queue Item (wenn der Request noch nicht im Cache vorhanden ist oder in der Queue noch nicht auf "processing" ist) und der (minütlich) laufende Cronjob verarbeitet dann immer das jeweils nächste item, dass noch nicht "processed" oder "processing" ist. Nur mal so als Idee (ohne jetzt die Details deiner Applikation zu kennen).
    » sponsor me via GitHub or PayPal or Revolut

  3. #3
    Contao-Nutzer Avatar von agonyz
    Registriert seit
    10.09.2020.
    Beiträge
    36

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Das müsstest du halt selbst bauen. Also du müsstest selbst irgendwo festhalten, welche Requests gerade verarbeitet werden.

    Vielleicht ist es aber auch am besten, wenn du eine Request Queue (in der Datenbank) implementierst? Das Frontend generiert dann so ein Queue Item (wenn der Request noch nicht im Cache vorhanden ist oder in der Queue noch nicht auf "processing" ist) und der (minütlich) laufende Cronjob verarbeitet dann immer das jeweils nächste item, dass noch nicht "processed" oder "processing" ist. Nur mal so als Idee (ohne jetzt die Details deiner Applikation zu kennen).
    Das mit der Request-Queue scheint mir eine echt gute Idee zu sein. Das wäre ja dann so, wie in Symfony mit Messages und der Queue in der Datenbank, oder?
    Gibt es da für Symfony ggf. schon ein Bundle oder eine eigene Componente, die das vereinfachen könnte?

    Habe gerade auf die schnelle das hier gefunden: https://github.com/php-enqueue/enqueue-dev

    Also nur, falls du das gerade zufällig weißt

  4. #4
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.088
    Partner-ID
    10107

    Standard

    Nein, weiß ich leider nicht .
    » sponsor me via GitHub or PayPal or Revolut

  5. #5
    Contao-Nutzer Avatar von agonyz
    Registriert seit
    10.09.2020.
    Beiträge
    36

    Standard

    Zitat Zitat von Spooky Beitrag anzeigen
    Nein, weiß ich leider nicht .
    Danke jedenfalls für den Denkanstoß, ich habe nun eine Möglichkeit implementiert.

    Ich habe aber noch ein kleines Problem, welches mir gerade auf meinem Remote-System aufgefallen ist.

    Wenn ich mein Bundle auf einem lokalen System von mir teste (WSL2), dann funktioniert mein Caching-System ohne Probleme.
    In meinem Remote-System (Gleiche Contao-Version, ähnlich leere Installation) funktioniert es leider nicht.

    Mein Code für mein Caching:


    PHP-Code:
    ...

    public function 
    createCacheKey(): bool
        
    {
            
    $this->requestDatabaseHandler->createRequestCheck();
            
    $this->requestDatabaseHandler->setRequestRunning(true);

            
    $cache = new FilesystemAdapter();
            
    $result $cache->getItem($this->cacheKey);
            
    $result->expiresAfter($this->cacheTtl);

            if (!(
    $domainResults $this->getDomainResults->getDomainResults())) {
                
    $result->set('error');
                
    $cache->save($result);
                
    $this->requestDatabaseHandler->setRequestRunning(false);

                return 
    false;
            }
            
    $result->set($domainResults);
            
    $cache->save($result);
            
    $this->requestDatabaseHandler->setRequestRunning(false);

            return 
    true;
        }
    ... 

    So sieht es im Service aus. Dieser Service wird von einem Command/Cronjob immer wieder ausgeführt.

    Im Controller versuche ich dann folgendermaßen auf meinen Cache zuzugreifen:

    PHP-Code:
    public function index(): Response
        
    {
            
    $cache = new FilesystemAdapter();
            
    $result $cache->getItem($this->cacheKey);

            if (!
    $result->isHit()) {
                if (!
    $this->requestDatabaseHandler->isRequestRunning()) {
                    
    $pageSpeedInsights 'restart';
                } else {
                    
    $pageSpeedInsights 'running';
                }
            } else {
                
    $pageSpeedInsights $result->get();
            }

            ....
        } 
    Leider ist mein im Service erstelltes Cache-Item dann nicht mehr im Controller vorhanden.
    Wenn ich es am Ende meines Services abrufe, ist es aber vorhanden.
    Die ttl meines Cache-Objekts ist ebenfalls hoch genug eingestellt.

    Hat jemand eine Idee, woran das liegen könnte? Bzw. wieso es auf meinem lokalen Test-System funktioniert und Remote nicht?
    Muss ich das Cache-Item ggf. anders erstellen?

    Vielen Dank für eure Ideen

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •