Atomicita operací se soubory
- mildhouse
- Člen | 27
Ahoj
jak je to v Nette s atomickymi operacemi?
Přečetl jsem si tento článek https://doc.nette.org/cs/safe-stream kde je příklad :
$s = str_repeat('Long String', 10000);
$counter = 1000;
while ($counter--) {
file_put_contents('soubor', $s); // write it
$readed = file_get_contents('soubor'); // read it
if ($s !== $readed) { // check it
echo 'řetězce se liší!';
}
}
Citace textu : Může se zdát, že volání echo ‚řetězce se liší!‘ nikdy nemůže nastat. Opak je pravdou. Schválně si zkuste tento skript spustit ve dvou oknech zároveň. Chyba se dostaví prakticky okamžitě.
Podle mě ne. I kdybych to spustil v 10ti oknech zároveň,
file_put_contents()
vloží vždy stejný řetězec (10000 x
'Long String'
) a vždy stejný řetězec načte.
Tak jsem si funkci trochu upravil :
// v Nette 2.0.12 - HomepagePresenter.php
class HomepagePresenter extends BasePresenter{
public function actionDefault(){
$string = $this->getParameter('string');
$s = str_repeat($string, 100000);
$counter = 3000;
while ($counter--) {
file_put_contents('soubor.txt', $s); // write it
$readed = file_get_contents('soubor.txt'); // read it
if ($s !== $readed) { // check it
echo 'řetězce se liší!';
}
}
}
}
// mimo Nette - index.php
$string = $_GET['string'];
$s = str_repeat($string, 100000);
$counter = 3000;
while ($counter--) {
file_put_contents('soubor.txt', $s); // write it
$readed = file_get_contents('soubor.txt'); // read it
if ($s !== $readed) { // check it
echo 'řetězce se liší!';
}
}
A spustil, napřed mimo Nette, v prvním okně
test-atomicita.cz?string=LongString a v druhém okně
test-atomicita.cz?string=LooooooongerString a podle očekávání došlo
k vypsání 'řetězce se liší!'
Pak jsem to spustil v Nette – v prvním okně
nette-atomicita.cz?string=LongString a v druhém okně
nette-atomicita.cz?string=LooooooongerString ale k vypsání
'řetězce se liší!'
nedošlo
Jakto, že v Nette proběhla operace atomicky, když jsem nepoužil Nette\Utils\SafeStream? Nenašel jsem Nette\Utils\SafeStream v API takže to je deprecated a Nette automaticky provádí atomické operace se soubory?
Díky
- Majkl578
- Moderator | 1364
Zkus to s delším stringem a chyba se určitě dostaví. :)
Pro:
$s = str_repeat('Long String', 10000);
mi stačily 2 scripty paralelně.
Nenašel jsem Nette\Utils\SafeStream v API takže to je deprecated a Nette automaticky provádí atomické operace se soubory?
V API není protože je (kdovíproč) @internal
.
Automaticky určitě nic neprovádí, musíš vždy použít protokol
safe://
.
- Jan Tvrdík
- Nette guru | 2595
@mildhouse: Máš v tom bordel, když budeš zapisovat ve dvou různých tabech různé řetězce, tak tě ani Nette SafeStream nezachrání a stejně to vypíše, že řetězce se liší. Pokud ti to náhodou chybu nevypisuje, tak máš štěstí nebo moc rychlý disk.