is fwrite atomic? - PHP

This is a discussion on is fwrite atomic? - PHP ; Hi, As the subject mentions, is fwrite method atomic in PHP? What I mean by that is, does fwrite function acquire an implicit lock while writing or do I need to explicitly acquire an EXCLUSIVE lock on the file before ...

+ Reply to Thread
Results 1 to 3 of 3

is fwrite atomic?

  1. Default is fwrite atomic?

    Hi,

    As the subject mentions, is fwrite method atomic in PHP? What I mean
    by that is, does fwrite function acquire an implicit lock while
    writing or do I need to explicitly acquire an EXCLUSIVE lock on the
    file before I call fwrite?

    The problem I am having is that, I want to track user requests by
    logging simple request parameters such as user IP, request URI, etc.
    instead of inserting into the db for avoiding overheads. And I will
    have a cronjob read this data around midnight and write it into the
    database (when there is little load on the server).

    So, the questions I have is:

    1. While writing this information, do I need to get an exclusive lock
    before writing? Say I have a 200 bytes string, and 2 people call
    fwrite at the same time with 2 strings, will they be written
    sequentually or will it mix these strings depending on the O/S IO
    buffer size.

    2. While I am inserting this data into the database, I will have to
    lock the file, dump them into the database and empty it. So, this
    might make some users wait, which is something I am trying to avoid.
    But, in anycase I will need to have a secondary lock object which
    controls access to this log I guess, i.e. acquire secondary lock,
    rename the file to .tmp or something, release the lock, and in the
    meantime read from .tmp, parse it and put it in the db.

    Any ideas?

    Thanks...

  2. Default Re: [PHP] is fwrite atomic?

    > As the subject mentions, is fwrite method atomic in PHP? What I mean
    > by that is, does fwrite function acquire an implicit lock while
    > writing or do I need to explicitly acquire an EXCLUSIVE lock on the
    > file before I call fwrite?


    While I haven't checked, I would imagine the answer is NO.

    > The problem I am having is that, I want to track user requests by
    > logging simple request parameters such as user IP, request URI, etc.
    > instead of inserting into the db for avoiding overheads. And I will
    > have a cronjob read this data around midnight and write it into the
    > database (when there is little load on the server).
    >
    > So, the questions I have is:
    >
    > 1. While writing this information, do I need to get an exclusive lock
    > before writing? Say I have a 200 bytes string, and 2 people call
    > fwrite at the same time with 2 strings, will they be written
    > sequentually or will it mix these strings depending on the O/S IO
    > buffer size.


    I certainly would. I don't know how the data will get written out in
    simultaneous writes. I would guess it involves filesystem options, what
    OS, kernel buffers, etc...

    Just create a "data.lock" file, open that, flock it, do your write, and
    close everything.

    > 2. While I am inserting this data into the database, I will have to
    > lock the file, dump them into the database and empty it. So, this
    > might make some users wait, which is something I am trying to avoid.
    > But, in anycase I will need to have a secondary lock object which
    > controls access to this log I guess, i.e. acquire secondary lock,
    > rename the file to .tmp or something, release the lock, and in the
    > meantime read from .tmp, parse it and put it in the db.


    I'd lock your data.lock file, move your actual data file, create an empty
    new data file, remove the lock, then process your local copy.

    You might also consider using syslog to send things there, but that might
    be more messy then it's worth...

    -philip

  3. Default Re: [PHP] is fwrite atomic?

    Cabbar Duzayak wrote:
    > As the subject mentions, is fwrite method atomic in PHP? What I mean
    > by that is, does fwrite function acquire an implicit lock while
    > writing or do I need to explicitly acquire an EXCLUSIVE lock on the
    > file before I call fwrite?


    That depends on your mode. If you opened the file in append mode, then
    yes, it is atomic. On some operating systems that may or may not be
    true over network filesystems like NFS if you are writing more than a
    block size, but if it is a local fs and you are in append mode, you can
    count on it being atomic. If you are not in append mode, then it is not
    atomic at all.

    > The problem I am having is that, I want to track user requests by
    > logging simple request parameters such as user IP, request URI, etc.
    > instead of inserting into the db for avoiding overheads. And I will
    > have a cronjob read this data around midnight and write it into the
    > database (when there is little load on the server).


    For straight logging like this you should be able to simply append to
    the log file and thus your fwrite will be atomic.

    > 2. While I am inserting this data into the database, I will have to
    > lock the file, dump them into the database and empty it. So, this
    > might make some users wait, which is something I am trying to avoid.
    > But, in anycase I will need to have a secondary lock object which
    > controls access to this log I guess, i.e. acquire secondary lock,
    > rename the file to .tmp or something, release the lock, and in the
    > meantime read from .tmp, parse it and put it in the db.


    Have your cronjob rename the file to a temporary filename which is also
    an atomic operation. Then read that temp file into your database. The
    only slight wrinkle here is that a process could be writing to the file
    as you rename it. This in itself is fine. The write will survive the
    rename and still complete writing to your renamed file since at that
    level it is simply an open file descriptor and it doesn't care what its
    name is. To make sure any outstanding writes complete, simply add a
    little delay between your rename and your read in your cron job.

    The next log write that comes in after the rename will automatically
    recreate the file since you are opening it in create+append mode.

    This way you avoid all locking and your application will actually work.
    Locks are evil!

    -Rasmus

+ Reply to Thread