Ankündigung

Einklappen
Keine Ankündigung bisher.

Prozesse "sperren" für Parallelnutzung

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Prozesse "sperren" für Parallelnutzung

    So ich hab mal ne Frage.

    Ich muss mittels ImageMagick einige Bilder erzeugen. Nur hat ImageMagick ein Problem mit "ungeduldigen" Usern.

    Sprich: Der Server hängt sich auf, wenn man die Seite die die Bilder erzeugt mehrere Male aufruft. Also "ungeduldig" ist.
    So muss ich also den Prozess bei "paralleler Nutzung" sperren.
    Ich ruft die ImageMagick Kommandos per "exec()" so auf :

    PHP-Code:
    <?php
    exec
    ('convert ... ');
    exec('composite ...  ');
    exec('montage ... ');
    ?>
    Kann ich das irgendwie so abschirmen das der Befehl gelockt ist ?
    Wie mache ich das ?
    Oder soll ich dann den Link, wenn er einmal angeklickt ausblenden ?

    Wäre dankbar für ein Paar ratschläge.

  • #2
    Hi.

    Ich werd nicht ganz schlau, auf welcher Ebene du locken möchtest.

    Funktion für alle Benutzer sperren:
    Lockfile im FS

    Funktion für einen Benutzer sperren:
    Benutzerspezifisches Lockfile oder z.B. blocken, wenn die Session gelockt ist

    Mehrmaliges Aufrufen eines URL verhindern:
    Challenge-ID erzeugen und in die Session und den Link speichern, bei "Aktivierung" löschen;

    Wichtig ist nur, dass du einen Mechanismus einbaust, der ein Lockfile wieder löscht, falls dieses durch einen gekillten Prozess liegen geblieben ist.

    Basti

    Kommentar


    • #3
      Zitat von Basti
      Mehrmaliges Aufrufen eines URL verhindern:
      Challenge-ID erzeugen und in die Session und den Link speichern, bei "Aktivierung" löschen;

      Wichtig ist nur, dass du einen Mechanismus einbaust, der ein Lockfile wieder löscht, falls dieses durch einen gekillten Prozess liegen geblieben ist.
      Also die Datei locken brauch ich nicht da ich die Bilddatei nur einmal bearbeiten lasse. Und jedes Bild nur einen Benutzer hat. Und wenn das gewünschte bild schon vorhanden ist wird ImageMagick auch nicht mehr ausgeführt.

      Das mit der Challenge-ID klingt interessant. So wie ich das in Erfahrung gebracht habe müsste ich in die Session einen md5() des timestamps machen. Soweit richtig ?
      Nachdem alles abgearbeitet ist lösch ich die ID wieder. Soweit so richtig ?
      Aber wie reagiert der Server wenn man ein 2. mal drauf klickt, die ID nicht gelöscht ist aber der Prozess auch noch nicht abgearbeitet war ?

      Ist irgendwie doch ein wenig kniffliger als ich's mir vorgestellt hab.

      *hm* Ich bin auch schon am überlegen ob ich 's nicht einfach durch 'n JavaScript verhindere.

      grundsätzliche Frage: Was passiert wenn der Link erneut angeklickt wird ? Wird das PHP-Script SOFORT unterbrochen ? Wird der Prozess (wie in meinem Fall exec('convert...')) noch zuende ausgeführt oder wird der Prozess gekillt ?

      Möglich wäre noch ihn auf eine "preload-Seite" weiterschicken. Nur müsste ich dann wissen wann der exec() befehl abgearbeitet wurde.

      kann man das prüfen ? dann könnte ich ihn, wenn er fertig geladen hat weiterleiten, weil bisher könnte es auch so aussehen als ob die Seite 'n hänger hat, da sie schon mal so ca 10 Sek's laden kann, je nach Bildgröße.

      .........

      Kommentar


      • #4
        Hi.

        Zitat von M3g4Star
        Also die Datei locken brauch ich nicht da ich die
        Bilddatei nur einmal bearbeiten lasse. Und jedes Bild nur einen Benutzer
        hat. Und wenn das gewünschte bild schon vorhanden ist wird
        ImageMagick auch nicht mehr ausgeführt.
        Ich meinte auch nicht, die Datei locken, sondern eine Lockdatei setzen:
        PHP-Code:
        <?php
        if (file_exitst(LOCKFILE)) {

            
        // Alter der Datei pruefen, ggf loeschen, andernfalls abbrechen
        }

        touch(LOCKFILE);
        do_something();
        rm(LOCKFILE);
        ?>
        Das mit der Challenge-ID klingt interessant. So wie ich das in
        Erfahrung gebracht habe müsste ich in die Session einen md5() des
        timestamps machen. Soweit richtig ?
        Neun, denn das Phänomen/Problem tritt ja genau dnn auf, wenn Benutzer
        zeitlich eng beieinander eine Aktion durchführen. Deshalb wäre eine es ein
        Schuß ins Knie, die Eindeutigkeit einer Anfrage anhand der Uhreit
        festmachen zu wollen!

        $sHash = md5(uniqid(rand(), true));

        Nachdem alles abgearbeitet ist lösch ich die ID wieder. Soweit so richtig ?
        Aber wie reagiert der Server wenn man ein 2. mal drauf klickt, die ID
        nicht gelöscht ist aber der Prozess auch noch nicht abgearbeitet war ?
        Das Vorgehen hängt vom gewünschten Ergebnis ab.

        Du möchtest einfach nur ein Reload bzw. ein mehrfaches Klicken aus der
        selben (nicht zwischenzeitlich aktualisierten) Seite heraus verhindern:

        1. Request der Seite mit dem Link:
        a) Challenge-ID erzeugen;
        b) CID in Session speichern;
        c) CID an Link ankleben;

        2. Request der Folgeseite:
        a) Challenge-ID aus Request extrahieren;
        b1) Wenn Challenge-ID in Session, dann;
        1) Challenge-ID aus Session löschen;
        2) Aktion durchführen;
        b2) andernfalls abweisen;

        Damit bekommst du aber auch einfach eine neue Challenge-ID, wenn du
        die Seite mit dem Link neu lädst bzw. Benutzer in einer anderen Session
        bist.

        Du willst verhindern, dass ein Benutzer eine Aktion mehrfach gleichzeitig
        durchführt:

        PHP-Code:
        <?php
        if (!isset($_SESSION['myAction']) || $_SESSION['myAction'] < time() - MAX_EXEC_TIME) {
            
        $_SESSION['myAction'] = time();
            
        myAction();
            unset(
        $_SESSION['myAction']);
        } else {
            die (
        'locked!');
        }
        ?>
        *hm* Ich bin auch schon am überlegen ob ich 's nicht einfach
        durch 'n JavaScript verhindere.
        Ich würd die Absturzsicherheit meines Servers (wenn ich einen betreiben
        würde) sicher nicht an eine JavaScript-Funktion auf einem Client-Rechner
        hängen!

        grundsätzliche Frage: Was passiert wenn der Link erneut
        angeklickt wird ? Wird das PHP-Script SOFORT unterbrochen ? Wird der
        Prozess (wie in meinem Fall exec('convert...')) noch zuende ausgeführt
        oder wird der Prozess gekillt ?

        Das 1. Skript läuft zu Ende weiter, auch denn der Client inzwischen
        wegbricht und das 2. Skript wird einfach ausgeführt, auch wenn das 1.
        noch laufen sollte.

        Möglich wäre noch ihn auf eine "preload-Seite" weiterschicken.

        Nur müsste ich dann wissen wann der exec() befehl abgearbeitet wurde.

        kann man das prüfen ? dann könnte ich ihn, wenn er fertig geladen hat
        weiterleiten, weil bisher könnte es auch so aussehen als ob die Seite 'n
        hänger hat, da sie schon mal so ca 10 Sek's laden kann, je nach
        Bildgröße.
        Du die Aktion natürlich auch per JS oder z.B. img-Tag anticken, klar.

        Ich würde in dem Fall dann eher prüfen, ob das Sktipt inzwischen fertig ist
        anstatt den Startzeitpunkt (den du selbst setzen müsstest) auszulesen.

        Da gibts verschiedene Möglichkeiten, aber schön wirds natürlich erst mit
        JavaScript (AJAX würde sich hier natürlich anbieten). Hängt davon ab, was
        du willst/in welchem Kontext die Aktion ausgeführt wird etc.

        Basti

        Kommentar


        • #5
          OK .. Erstmal danke für die umfassende Antwort.
          Ich hab's jetzt zunächsteinmal so gemacht das ich den Login nur durch JavaScript erlaube um so erstmal sicher zu stellen das der "unwissende" User nicht zufällig was falsch macht.

          Er loggt sich ein und kommt auf eine preload-Seite die keine Verlinkungen besitzt. Und wird SOFORT (wenn die Seite fertig geladen ist) weiter geleitet.

          Somit hab ich das zunächst ohne weiteren größeren Aufwand erledigt.

          PHP-Code:
          <?php
          if (file_exitst(LOCKFILE)) {

              
          // Alter der Datei pruefen, ggf loeschen, andernfalls abbrechen
          }

          touch(LOCKFILE);
          do_something();
          rm(LOCKFILE);
          ?>
          das klingt soweit nicht schlecht. Werd ich sicherlich mit einarbeiten. nicht genauso wie's da steht aber zumindest so ähnlich. Den kompletten Content kann ich hier nicht niederschreiben, da es vllt doch ein wenig zu "umfangreich" wäre das ganze ausführlich hier zu erklären.

          In Flash hab ich das ganze schon gelöst, da kann man auch feine Sachen mit PHP und ImageMagick machen, falls notwendig. Und auch direkt auf die "abarbeitung" verschiedener Prozesse zugreifen.

          Naja .. Ich denk mal wenn jemand was "böses" will schafft er's eh immer solang das notwendige Wissen da ist. und den "zufälligen" Fehler hab ich verhindert und sicherer wird's mit einer der von dir genannten Methoden auch.

          Dank dir für deine Ideen

          Kommentar

          Lädt...
          X