Skip to content

zlib streams should support locking #17668

Closed
Closed

Description

@githubyiti

Description

The following code:

<?php
			$gz = gzopen($cachefileb,'w9');
			gzwrite($gz, $towrite);
			gzclose($gz);

Resulted in this output:
Current function caused disk error while multiple sessions is writing to the same file.

But I expected this output instead:
can the file be locked while the file is being written?

### PHP Version

PHP 7.4

### Operating System

Almalinux

Activity

  1. cmb69 commented on Feb 2, 2025

    @cmb69
    Member
  2. githubyiti commented on Feb 2, 2025

    @githubyiti
    Author

    Thanks for the response!
    Yes, someone is reporting the same problem on exactly the page you gave, has the issue been solved?
    https://www.php.net/flock#111443

  3. cmb69 commented on Feb 2, 2025

    @cmb69
    Member

    No, that issue still persists. From a quick look at the implementation, the actual file stream is an "inner stream".

    Workaround: use fopen() instead of gzopen() (and use ini_set("zlib.output_compression", 9")).

    PS: probably better anyway: use a separate lock file (.lck).

  4. githubyiti commented on Feb 2, 2025

    @githubyiti
    Author

    Thanks.

    The old code in use has already created a lot of data, fear rewriting the old code may unexpectly corrupt the old data.
    new scripts are using the way you suggested.

    Hope if can have something like gz_lock to patch to the old code.

    Regards,

  5. cmb69 commented on Feb 2, 2025

    @cmb69
    Member

    This cannot be implemented for PHP < 8.5, and I would assume that upgrading to PHP 8 already requires quite some changes to your code base, so possibly tough luck.

    Anyway, let's turn this into a proper feature request, since it generally makes sense to be able to lock zlib streams.

  6. changed the title [-]How to lock file when gzwrite file?[/-] [+]zlib streams should support locking[/+] on Feb 2, 2025
  7. cmb69 commented on Feb 2, 2025

    @cmb69
    Member

    Implementation would need to start at

    NULL /* set_option */

  8. githubyiti commented on Feb 2, 2025

    @githubyiti
    Author

    Thanks for moderating the title.
    Hope will have gz_lock in the future.

  9. cmb69 commented on Feb 2, 2025

    @cmb69
    Member

    Hope will have gz_lock in the future.

    Well, you would rather be able to use flock().

  10. githubyiti commented on Feb 5, 2025

    @githubyiti
    Author

    Added an external file lock as below
    not sure will the problem be fixed.

    if(file_exists($cachefileb."-lock") and time()-filemtime($cachefileb."-lock")<3){@set_time_limit(10);sleep(rand(0,8));}
    clearstatcache();
    if(!file_exists($cachefileb."-lock") or time()-filemtime($cachefileb."-lock")>3){
    touch($cachefileb."-lock");
    $gz = gzopen($cachefileb,'w9');
    gzwrite($gz, $towrite);
    gzclose($gz);
    unlink($cachefileb."-lock");
    }

  11. cmb69 commented on Feb 5, 2025

    @cmb69
    Member

    No, I've meant just flock() another file. Something like:

    $lock = fopen($gz . ".lck", "w+");
    flock($lock, LOCK_EX);
    $gz = gzopen($cachefileb,'w9');
    gzwrite($gz, $towrite);
    gzclose($gz);
    flock($lock, LOCK_UN);
  12. githubyiti commented on Feb 5, 2025

    @githubyiti
    Author

    Thanks!
    Seems your flock is better.
    I just code for hobby and not familiar with the behavior of how flock works.
    Will the below work?

    $lock = fopen($gz . ".lck", "w+");
    if(!$lock ){@set_time_limit(10);
    sleep(rand(0,8));
    $lock = fopen($gz . ".lck", "w+");}
    if($lock ){flock($lock, LOCK_EX);
    $gz = gzopen($cachefileb,'w9');
    gzwrite($gz, $towrite);
    gzclose($gz);
    flock($lock, LOCK_UN);
    fclose($gz . ".lck");
    }

  13. self-assigned this
    on Feb 9, 2025
  14. added a commit that references this issue on Feb 9, 2025
  15. added a commit that references this issue on Feb 11, 2025
  16. ndossche commented on Feb 11, 2025

    @ndossche
    Member

    Implemented in PHP 8.5 via 5acff0e

  17. githubyiti commented on Feb 11, 2025

    @githubyiti
    Author

    I found the problem perhaps can be solved by gz witing the file to tmp file then rename it back to the disk.
    Even if the tmp file is corrupted when the lock failed, disk error can be prevented.
    testing the code now, so far no disk error occurred.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions