Avatar billede rasmuspalm Nybegynder
07. februar 2008 - 09:39 Der er 8 kommentarer

Sessions tvinger side til at vente

Vi har behov for at se status på et php script jeg kører under dets kørsel. Til det fandt vi følgende løsning.
3 filer klarer jobbet:
index.php kører 2 iframes.
viewer.php kører i den ene iframe og læser fra filen test.txt
writer.php kører i den anden iframe og skriver sin status ned i test.txt (i dette eksempel nedskriver den $i som kører i et for loop)

index.php
[code]
<html>
  <head>
    <title> php problem example working</title>
  </head>
  <body>
    index.php
    <iframe src='viewer.php' width='100%' height='80%'></iframe>
    <iframe src='writer.php' width='100%' height='20%'></iframe>
  </body>
</html>
[/code]

viewer.php
[code]
<html>
  <head>
    <title> php problem example working</title>
    <meta http-equiv="refresh" content="0.2;url=">
  </head>
  <body>
    viewer.php
    <br />
    <br />
    <?php
      readfile('test.txt');   
    ?>
  </body>
</html>
[/code]

writer.php
[code]
<html>
  <head>
    <title> php problem example working</title>
  </head>
  <body>
    writer.php
    <br />
    <br />
    <?php
      for($i=0;$i<50;$i++){
        usleep(300000);
        $myFile = "test.txt";
        $fh = fopen($myFile, 'w') or die("can't open file");
        fwrite($fh, "i = $i");
        fclose($fh);
      }
      echo "loop done";
    ?>
  </body>
</html>
[/code]

Live demo på: http://bergpalm.dk/working

Så langt så godt. Men vores system bruger en adgangskontrol baseret på sessions. Da dette blev inkorporeret (<?php include(protected.php) ?> i toppen af filen) begyndte viewer.php at vente på at writer.php var færdig med at eksekvere.
Jeg har lavet følgende eksempel filer.
Det er det samme system som før, men nu bruges sessions til at styre update hastigheden på viewer således at den burde stoppe med at opdatere når at writer.php var færdig.

index.php
[code]
<?php
  session_start();
  $_SESSION['update']=0.2;
?>
<html>
  <head>
    <title> php problem example failing</title>
  </head>
  <body>
    index.php
    <iframe src='viewer.php' width='100%' height='80%'></iframe>
    <iframe src='writer.php' width='100%' height='20%'></iframe>
  </body>
</html>
[/code]

viewer.php
[code]
<?php
  session_start();
  $update=$_SESSION['update'];
?>
<html>
  <head>
    <title> php problem example failing</title>
    <meta http-equiv="refresh" content="<?php echo $update; ?>;url=">
  </head>
  <body>
    viewer.php
    <br />
    <br />
    <?php
      readfile('test.txt');   
    ?>
  </body>
</html>
[/code]

writer.php
[code]
<?php session_start(); ?>
<html>
  <head>
    <title> php problem example failing</title>
  </head>
  <body>
    writer.php
    <br />
    <br />
    <?php
      for($i=0;$i<50;$i++){
        usleep(300000);
        $myFile = "test.txt";
        $fh = fopen($myFile, 'w') or die("can't open file");
        fwrite($fh, "i = $i");
        fclose($fh);
      }
      echo "loop done";
      $_SESSION['update']=-1;
    ?>
  </body>
</html>
[/code]

Live demo på: http://bergpalm.dk/failing

Nogen ideer til hvordan vi kan få det til at virke som planlagt?
Avatar billede jakobdo Ekspert
07. februar 2008 - 12:13 #1
Skal det laves i frames?
Avatar billede rasmuspalm Nybegynder
07. februar 2008 - 17:57 #2
Nej det er ikke nødvendigt. Vi skal bare eksekvere et php script og kunne se status af det mens det kører på en eller anden måde.
Avatar billede jakobdo Ekspert
07. februar 2008 - 20:21 #3
I disse ajax tider, kunne man så ikke kalde scriptet i intervaller med et ajax kald?
Avatar billede rasmuspalm Nybegynder
09. februar 2008 - 22:58 #4
Hmmm... ser du, vi optager nogle php script til automatiseret testing af websider med selenium IDE, og det er status af disse test vi skal se på. Det vil altså kræve ret stor omskrivning af disse genererede scripts for at få AJAX kald til at virke.
Desuden har ingen af os arbejdet med ajax så vi ville hellere finde en anden hurtigere løsning.
Efter mange timers googling fandt jeg en henslængt kommentar om at hvis 2 sider bruger de samme sessions, venter de på hinanden. Dette er for at undgå race-conditions hvor at de 2 script begge skriver til sessions filen samtidigt.
Problemet lader sig altså ikke lige løse lader det til.

Overvejer om man kunne gemme den gamle session, oprette nogle nye og efter endt kørsel genoprette den gamle session...

Spaghetti løsning men...
Avatar billede softspot Forsker
10. februar 2008 - 01:41 #5
Nu er jeg ikke PHP-kyndig, men jeg ved det samme er problemet i ASP og her ville jeg foreslå at bruge Application-objektet i stedet for Session-objektet. Spørgsmålet er om dette også kan lade sig gøre i PHP (det vil jeg umiddelbart tro). Application-objektet udemærker sig (i det mindste i ASP) ved, at være multithreaded og dermed bedre egnet til at håndtere opgaven. Man skal blot huske at låse adgangen for andre når man opdaterer tælleren, ellers risikerer man konkurrerende opdateringer...
Avatar billede jakobdo Ekspert
10. februar 2008 - 07:11 #6
softspot: Der er desværre ikke et Application-object i php. :o(
Avatar billede softspot Forsker
03. april 2008 - 12:40 #7
Hvad med $GLOBALS[], er det noget som eksisterer på tværs af requests eller er det bare et global array, som kan bruges til at kommunikere værdier på tværs af funktioner og objekter under ét request...?
Avatar billede jakobdo Ekspert
03. april 2008 - 15:26 #8
Globals er ikke noget som kan bruges på tværs, men det kan bruges pr request.
Dog anbefales det altid at lade vær med at bruge globale variabler ala globals.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester