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 - Kit

Stran: 1 ... 29 30 [31] 32 33 ... 47
451
OK kit, tak jsem to udělal, ale ke kolizím stále dochází:

Kód: [Vybrat]
        $success = fflush($fp);// flush output before releasing the lock
        if ( $success === false )
          echo "; flush FAILED; ";
        $st = fstat($fp);
        if ($original_size>$st['size'])
            {
            echo "; <b>WRITE FAILED, restoring</b>;";

Je to tak nějak furt stejné.

Hmm, kde máš zámek?

452
A jsi si jistý, že je možné správně zjistit velikost souboru, když je soubor otevřený pro zápis?

Místo vyptávání by sis měl napsat test. Malá nápověda: fstat()

453
Kit, děláš mi to rozhodování čím dál těžší. Flock sice spolehlivý je, ale nezaručuje že mezi otevřením a flockem se k souboru, nedostane jiný proces.  :o

To vadí? Mně tedy ne.

Nabourává to ten script, takže není atomicitní.

Nenabourá. Jen je třeba výsledek flock() testovat a zachovat se podle toho.

454
Kit, děláš mi to rozhodování čím dál těžší. Flock sice spolehlivý je, ale nezaručuje že mezi otevřením a flockem se k souboru, nedostane jiný proces.  :o

To vadí? Mně tedy ne.

455
Správně se to dělá tak, že se proces nejprve pokusí zamknout všechny soubory, které bude potřebovat ke své práci. Pokud některý ze zámků selže, všechny odemkne, počká náhodnou dobu a pokusí se znovu nasadit všechny zámky.
Já bych ten soubor mohl mít jen jeden, ale pokud použiju rejstříky a indexy - další dva soubory pro urychlení parsování/hledání - tak to budou 3.

Tak si zamkni jen jeden a říkej mu semafor.

Rejstříky, indexy,... přiznej se, že ty v PHP vyrábíš databázi?

456
Pokud skript spadne, tak spadne. Obvykle to ničemu nevadí a je to zcela běžné. Klient si ho spustí znovu.

Pokud spadne tak tam zůstane ten vytvořený adresář, který nikdo nesmazal. Ten script pak nepůjde provést. Musel bych tam spouštět čas od času udržovací script, který by promazal ty staré adresáře - ale to je zase zátěž na víc a navíc to neřeší problém úplně. Protože nějakou dobu to spustit nepůjde.

Nepoužívám mkdir(), ale flock(), který je spolehlivý a při zavření souboru (i při pádu procesu) se sám odemkne.

457
Myslím, že flock není atomický - https://www.reddit.com/r/PHP/comments/9ec4tz/a_locking_file_cache_in_php/e6cqg19/
Začíná se mi pomalu vybavovat, proč jsem se tenkrát rozhodl využít pro zamykání mkdir ;)
V podstatě tam píší jen to, že mezi voláním fopen() a flock() si ten soubor může zamknout někdo jiný. Tedy nic, co by se nedalo ošetřit testem návratové hodnoty flock().
Zamykání přes mkdir() má nevýhodu v tom, že když ten proces spadne, kdo to po něm uklidí?
Ano uklízení po mkdir() musíš ošetřit ručně. Nevím jak je to přesně u flock(), ale předpokládám, že i tam se ti zámek může seknout a pak musíš mít nějakou vlastní funkci, která ji natvrdo odblokuje.

Nevýhodu vidím v tom, že testem návratové hodnoty flock() vytvoříš smyčku mezi flock() a fopen(). Pokud bys pustil vytěžující scripty (o což se Exkalibr snaží), tak by se smyčka nemusela stihnout dokončit do konce běhu PHP scriptu a script by spadl. Pokud si uděláš vlastní funkcí pomocí mkdir(), tak ji zavoláš ještě před fopen().

Proto se do toho zamykacího cyklu vkládá náhodná prodleva, aby se snížilo riziko náhodné kolize.

Flock je automaticky odstraněn zavřením souboru. Není třeba řešit jeho odstranění ručně.

Pokud skript spadne, tak spadne. Obvykle to ničemu nevadí a je to zcela běžné. Klient si ho spustí znovu.

458
Správně se to dělá tak, že se proces nejprve pokusí zamknout všechny soubory, které bude potřebovat ke své práci. Pokud některý ze zámků selže, všechny odemkne, počká náhodnou dobu a pokusí se znovu nasadit všechny zámky.

459
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.
Tohle testování je k ničemu. Pokud nemáš správně zámky, tak pořád testuješ nezamknuté soubory a vůbec není podstatné kolik je tam chyb. Pokud paralelní php scripty pustíš přesně ve stejný okamžik, tak tam těch chyb bude teoreticky více než když je spustíš s malým časovým odstupem - časový odstup u takového testu sníží riziko překřížení mezi jednotlivými PHP procesy.

V testech je naopak výhodné, pokud se ty procesy co nejvíc potlučou mezi sebou - proto jsou ty časové odstupy zbytečné a kontraproduktivní.

460
Myslím, že flock není atomický - https://www.reddit.com/r/PHP/comments/9ec4tz/a_locking_file_cache_in_php/e6cqg19/
Začíná se mi pomalu vybavovat, proč jsem se tenkrát rozhodl využít pro zamykání mkdir ;)

V podstatě tam píší jen to, že mezi voláním fopen() a flock() si ten soubor může zamknout někdo jiný. Tedy nic, co by se nedalo ošetřit testem návratové hodnoty flock().

Zamykání přes mkdir() má nevýhodu v tom, že když ten proces spadne, kdo to po něm uklidí?

461
Zkus tuto jednoduchou úpravu, jak bude reagovat na souběhy:
Kód: [Vybrat]
$fp = fopen($tname, "r+");
flock($fp, LOCK_EX);
$s = fread($fp, $fsize);
ftruncate($fp, 0);
rewind($fp);
fwrite($fp, $s);
fclose($fp);

462
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);

Zamknuté to není, protože to v polovině odemykáš a zase zamykáš. V tu chvíli si ten soubor zamkne jiný proces a máš kolizi.

463
Nezkoumal jsem to tak podrobně, jen vidím, že proměnná $start je zcela zbytečná a může ty problémy způsobovat.

464
Stačí jediná chyba a můžeš tu metodu zahodit.

465
LOCK_EX se dává v případě, že chceš do souboru zapisovat.

Stran: 1 ... 29 30 [31] 32 33 ... 47