Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - exkalibr

Stran: 1 ... 21 22 [23] 24 25
331
Teď jsem opakoval T7 jen s 6 cyklama a jen ze dvou prohlížečů a přesto došlo ke 4 kolizím. Oproti tomu T8 s 10 cyklama ze čtyř firefoxů udělal jen 1 chybu ... za bez použití file_exists. Ale taky se dívám že výsledná doba čekání u toho selhání byla poměrně malá 0.864s.


332
Čím si vysvětluješ, že ani flock nepomůže k zajištění atomicity?

333
Původně mi šlo o testování rychlosti během čtení/zápisu na server při spuštěných 4 procesech současně. T7 se povedlo otestovat s malým množstvím chyb, ale nyní těch chyb je kopa, to nemá cenu počítat. Nevím co se změnilo. Tak by T8 možná mohl vyjít spolehlivěji, ale ve výsledku ani jedna operace není dokonale spolehlivá.

334
Při T5-T7 je problém při zápisu do souboru fwrite, fflush. To jsem už psal.

Zamknuté to je. Stručně:

Kód: [Vybrat]
$locked = flock($fp, LOCK_SH);
$s = fread($fp, $fsize );
$success = flock($fp, LOCK_UN);
$success = fclose($fp);
$fp = fopen($tname, "w");
$locked = flock($fp, LOCK_EX);
$success = fwrite($fp, $s);
$success = fflush($fp);
$success = flock($fp, LOCK_UN);
$success = fclose($fp);

Ale teď se dívám, že jsem tam mohl dát LOCK_EX místo LOCK_SH, to LOCK_SH tam nedává smysl. Ale má to vliv?

Kód: [Vybrat]
$locked = flock($fp, LOCK_SH)

OK, tak jsem to testnul a řekněte mi jestli ten kód je dobře:

Kód: [Vybrat]
function atomicFuse($n, $c, $disableDelay = false){
  $start = false;
 
  if ( @mkdir("$n.t") )
   $start = true;
  if ( !$disableDelay ){
    if ( $start == false )
     {
     $n = $n*30;
  ...
V té funkci je $start = true když je povoleno provádět atomicitní operaci jinak je false.

Výsledek:
FF1 - failed 0x
Chrome - failed 0x
FF2 - failed 2x
Opera - failed 5x
Celkem atomicity failed 7x - což ale nutně neznamená, že je to lepší. Někdy může být selhání více, někdy méně, jak tu bylo řečeno, tohle závisí na OS, který proces si zrovna upřednostní. Závěr ale je, že k porušení atomicity došlo.

335
Jenže těch 50 mikrosekund nemá na výsledek grafu žádný vliv. My se pohybujeme v řádů setin až desetin. To se zaokrouhlí a průměry se nezmění. Vliv to má na chování programu. Já si už u T7 všiml, že když odstraním delay je to spolehlivější než když ten čas navyšuju. Ta prodleva je zdrojem problémů u T8. Proto bych v praxi raději volil metodiku T7, která je dvakrát rychlejší. V praxi stejně ke kolizi dojde málokdy a když k ní dojde tak ověřením ji mohu obnovit ze zálohy.

Pro mě výsledek testu znamená, že registraci nemusím dělat do db. Nemusím dokonce dělat ani vzkazník do db. Co ale musím udělat do db je anketa, kde budou uživatelé klikat pomocí AJAXu, a tam se obávám, že by ke kolizím mohlo snadno dojít (zápis do toho samého souboru).

Rename jsem ale zavrhl kvůli tomu, že nadělá strašnou paseku, pokud operace selže. Kdo to pak má přejmenovávat všechny ty soubory?

336
Máš pravdu, musíš si prostě v hlavě odečíst 50 mikrosekund u každé hodnoty :(

337
Selhání

Ještě bych dodal, že u T5-T7 šlo o jiná selhání než u T8. Selhání T8 se týkají atomicity - akce není provedena vůbec. T5-T7 tam jde o problém se zápisem dat - po zapsání fwrite není správná velikost dat, ačkoliv byl použít flock.

338
Graf s T8, atomicity tester with directoryFuse.


339
Ahoj ještě nevím. Data budu za chvíli zpracovávat. Mám na to několik tabulek a grafů. Podle toho pak poznám o čem to svědčí. Co si myslím teď se ještě může změnit. Jisté je jen to, že ty prodlevy, které tam jsou, jsou závislé na tom typu testu - php skript se smyčkou. Kdyby si podnikl jiný druh "útoku" na server například smyčkou v JS odeslal požadavky post() AJAXEM a já bych každý jednotlivý požadavek zpracoval jako načtení a zápis, tak by se to zcela určitě chovalo úplně jinak. Myslím, že tento test co jsem prováděl byl dost vytěžující, ale jinak než běžné přístupy nebo než DOS útoky. Každopádně jsem ti vděčný za poznání druhé metody, která se chová trochu jinak, obě metody mají něco do sebe. Tento test jsem pojmenoval jako T8. Dokonalé to asi nebude nikdy.

340
Konec testů.

Shrnutí
Hlavním faktorem úspěšnosti testu je délka smyčky neboli počet cyklů. Pokud je počet cyklů větší než 6, tak začne vykazovat pár chyb. Nad deset je chybovost vyšší a s dalšími desítkami se zvyšuje. Nejde zde o velikost souboru, i velký soubor např 6MB se zpracuje rychle. Problém je v tom, že se v jednom okamžiku očekává mnoho úloh. Například skript jedna zpracovává 6 požadavků a druhý skript musí čekat. Chyby se objevují na začátku. Při posledním testu s 50 cykly jsem dostal následující chybovost:

požadavek z Chrome: 6 neprovedených úkonů (4x 523kB a 2x 948kB)
požadavek z FF1: 5 neprovedených úkonů (prvních 5 souborů ~523kB)
požadavek z Opery: 0 neprovedených úkonů (100% OK)
požadavek z FF2:   0 neprovedených úkonů (100% OK)

Aktuální funkce:

Kód: [Vybrat]
function atomicFuse($n, $c, $disableDelay = false){
  $start = false;
  if ( !file_exists("$n.t") )
   $start = mkdir("$n.t");
  if ( !$disableDelay ){
    if ( $start == false )
     {
     $n = $n*30;
     switch($c):      // Delay example increase:
       case 0: break; // 0,01569 total
       case 1: break; // 0,03138 total
       case 2: $n = $n*2; break; // 0,06276 total
       case 3: $n = $n*4; break; // 0,12552 total
       // case 4: You need at least *6 or *8 to get out of problems with extrem times
       case 4: $n = $n*8; break; // 0,25104 t.(upper limit)
       // In case of heavy traffic:
       case 5: $n = $n*8; break; // 0,36087 total extrem
       case 6: $n = $n*10; break; // 0,51777 total extrem
       case 7: $n = $n*20; break; // 1,03554 total extrem
       default: $n = $n*8; break;
     endswitch;
     usleep($n);
     echo ($n)."<br>";
     }
    }
  return $start;
}

341
Kód: [Vybrat]
function atomicFuse($n, $c, $disableDelay = false){
  $start = false;
  if ( !file_exists("$n.t") )
   $start = mkdir("$n.t");
  if ( !$disableDelay ){
    if ( $start == false )
     {
     $n = $n*30;
     switch($c):      // Delay example increase:
       case 0: break; // 0,01569 total
       case 1: break; // 0,03138 total
       case 2: $n = $n*2; break; // 0,06276 total
       case 3: $n = $n*4; break; // 0,12552 total
       // case 4: You need at least *6 or *8 to get out of problems with extrem times
       case 4: $n = $n*6; break; // 0,21966 t.(upper limit)
       case 5: $n = $n*6; break; // 0,3138 total extrem
       case 6: $n = $n*4; break; // 0,36087  total extrem
       case 7: $n = $n*4; break; // 0,42363 total extrem
       default: break;
     endswitch;
     usleep($n);
     echo ($n)."<br>";
     }
    }
  return $start;
}

implementace.
Kód: [Vybrat]
      $start = atomicFuse($n,0);
      if (!$start) $start = atomicFuse($n,1);
      if (!$start) $start = atomicFuse($n,2);
      if (!$start) $start = atomicFuse($n,3);
      if (!$start) $start = atomicFuse($n,4);
      if (!$start) $start = atomicFuse($n,5);
      if (!$start) $start = atomicFuse($n,6);
      if (!$start) $start = atomicFuse($n,7);
      if (!$start) $start = atomicFuse($n, false);
      if (!$start) echo "<b>Atomicity failed.</b> ";
      if ( $start )
         {
         echo "<b>Atomicity OK.</b> ";
         // perform atomic action
         $success = rmdir("$n.t"); // remove atomic fuse
         }

Zatím testuju se smyčkou 10 cyklů.

Dám příklad ~500kB s aktuálními chybama:
CHROME OK - první dva požadavky na soubor jsou za 0.003s a 0.047s
FF1 OK - za 0,2196s
FF2 OK - 0,45501s
OPERA hned na jednou začátku selže: protože má čas 0,45501 ...

Vysvětlení chyby: Ten požadavek z Opery se začne vyhodnocovat později např. při 0,45500s a v té době se požadavek od FF2 ještě vyřizuje. Takže řešením je jedině zvýšit počet požadavků na čekání nebo prodloužit prodlevu.

342
Už to jede zatím test jen se dvěma cykly.

Chyba byla rmdir v nesprávné větvi, delay byl trochu malý a je třeba víckrát opakovat test existence souboru. Tady se může opakovat až 15x. Problém je totiž ve velkém rozsahu hodnot (prodlev), které mohou nastat. Původně jsem to totiž nastavoval na průměry a nepodíval jsem se do skutečných hodnot. U půl megabajtového souboru jdou minima a maxima od 0,001 až na 0,2s.

343
Ok, tak už to asi mám, ale není to úplně ideální občas tam mám chybu "atomicity failed" (to by mohlo nastat pokud čeká moc dlouho). Občas je tam chyba zápisu do souboru.

Celý kód

clearstatcache();
$_DEBUG_ = false;

echo "Atomicity tester.".time()."
";
die;

while ( time()<1570950820 )
 {
 usleep(500);
 }

function atomicFuse($n, $disableDelay = false){
  $start = false;
  if ( !file_exists("$n.t") )
   $start = mkdir("$n.t");
  if ( !$disableDelay ){
    if ( $start == false )
     {
     usleep($n*3);
     echo ($n*3)."
";
     }
    }
  return $start;
}
function test($n, $p, $_DEBUG_){
  $fp = null;
  $sname = "$n";    // source
  $tname = "$n.txt";// target
  echo "<h4>$n at ".time()."</h4>";
  for ($i = 0; $i<2; $i++ ){
    $start_time = microtime(true);
      {
      $start = atomicFuse($n);
      // If n*16 used then 6 time repeat:
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n, false);
      if (!$start) echo "Atomicity failed. ";
      if ( $start )
         {
         /////////////////////////////
         // CHECK FILESIZE VALIDITY //
         /////////////////////////////
         clearstatcache(); // needed for filesize and touch   
         $st = stat("$sname");
         $original_size = $st['size'];
         if ( $_DEBUG_ )
           echo "; 1) prevAccess by ".$st['mtime']." fsize ".$st['size']."; ";
         $fsize = filesize($sname);
         if ( $original_size <> $fsize )
           die("; fsize total FAILTURE; ");
         if ($fsize === 0)
          echo "! The fsize is 0: stat(): ".$st['size']." ;";   
         ///////////////////
         // OPEN THE FILE //
         ///////////////////
         $fp = fopen($sname, "r");
         $s = fread($fp, $fsize );
         $success = fclose($fp);
         if ( $success === false  )
           die("; fclose failed; ");
         // 10 - data načtená , $p - prohlížeč
         if ( $success )
           {
           $result = touch("$sname",strlen($s),$p);
           if ( $_DEBUG_ )
              echo "; TOUCH: $result;";
           }
         else
           die("fclose FAIL.");
         if ( strlen($s)<60 )
            echo "*$s LENGTH:".strlen($s)."
";
         } 
      }
    if ( $start )
      {
      clearstatcache();
      $st = stat("$tname");                               
      if ( $_DEBUG_ )
        echo "; 2) prevAccess by ".$st['mtime']." fsize is ".$fsize."; ";
 
      // WRITE OPERATION WITH LOC_EX
      $fp = fopen($tname, "w");
      if ( true ) {  // acquire an exclusive lock
          $success = fwrite($fp, $s);
          if ( $success === false)
            echo "; w FAILED;";
          else
            if ( $_DEBUG_ )
                  echo " $success B written; ";
          $success = fflush($fp);// flush output before releasing the lock
          if ( $success === false )
            echo "; flush FAILED; ";
          if ( $success === false )
            echo "; release FAILED; ";
          $success = fclose($fp);
          if ( $success === false )
            echo "; fclose FAILED; ";
          clearstatcache(); // needed for filesize and touch
          $fsize = filesize($tname);
          if ($original_size>$fsize)
              {
              echo "; WRITE FAILED, restoring;";
              $original_fname = "$n";
              $result = copy($original_fname, $tname);
              if ($result == false )
                die(" TOTAL FAILTURE: copy failed.");
              else
                echo " RESTORED;";
              }
          else
            {
              if ($fsize === 0)
               echo "! THE FILE WAS NOT WRITTEN: data length: ".strlen($s)." fsize: $fsize RESOURCE: $fp
";   
              if ( $success )
                  touch("$tname",$fsize,$p);
            }
          } else {
              echo "Couldn't get the lock!";
             }
      } // start
     else
       echo "skipped";
     $success = rmdir("$n.t"); // remove atomic fuse
       if ( $success )
         echo "<h4>DIR REMOVED</h4>";
       else
         echo "<h4>DIR NOT REMOVED</h4>";
     $time_elapsed_secs = microtime(true) - $start_time;
     if ( $time_elapsed_secs === 0 )
       echo " FAILED ";
     echo "time: $time_elapsed_secs s
";
  } // for
}

switch ( $_SERVER['HTTP_USER_AGENT'] ):
  // FF 1:
  case "":
    $p = 1; break;
  // Chrome:
  case "":
    $p = 2; break;
  // OPERA:
  case "": 
    $p = 3; break;
endswitch;

copy("523","523.txt");
copy("948","948.txt");
copy("1371","1371.txt");
copy("1913","1913.txt");
copy("2701","2701.txt");
copy("4495","4495.txt");
copy("6758","6758.txt");

test("523",$p,$_DEBUG_);
test("948",$p,$_DEBUG_);
test("1371",$p,$_DEBUG_);
test("1913",$p,$_DEBUG_);
test("2701",$p,$_DEBUG_);
test("4495",$p,$_DEBUG_);
test("6758",$p,$_DEBUG_);
die;

344
Zatím se mi to nedaří rozjet. Kontrola kódu:

function atomicFuse($n){
  $start = false;
  if ( !file_exists("$n.t") )
   $start = mkdir("$n.t");
  if ( $start == false )
   usleep($n*16);
  return $start;
}

  for ($i = 0; $i<2; $i++ ){
    $start_time = microtime(true);
      {
      $start = atomicFuse($n);
      // If n*16 used then 6 time repeat:
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) $start = atomicFuse($n);
      if (!$start) echo "Atomicity failed. ";
      if ( $start )
         {
         .... do této větve se nedostane
         }
     }
     $time_elapsed_secs = microtime(true) - $start_time;
     if ( $time_elapsed_secs === 0 )
       echo " FAILED ";
   }

Pro srozuměnou: n je velikost souboru v kb.
Pro n= 948 tak vychází prodleva 16116 čili 0,016116 mikrosekund.

Výstup:

523 at 1570949057
Atomicity failed. skippedtime: 0.050755023956299 s
Atomicity failed. skippedtime: 0.050696134567261 s
948 at 1570949057
Atomicity failed. skippedtime: 0.091481924057007 s
Atomicity failed. skippedtime: 0.091547012329102 s
1371 at 1570949057
Atomicity failed. skippedtime: 0.13213992118835 s
Atomicity failed. skippedtime: 0.13215684890747 s
1913 at 1570949057
Atomicity failed. skippedtime: 0.18418097496033 s
Atomicity failed. skippedtime: 0.1841561794281 s

345
Dneska vyzkouším ten mkdir.

Stran: 1 ... 21 22 [23] 24 25