Reentrant POST hangs the session

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • a

    Reentrant POST hangs the session

    I already posted on this subject, but I have some more information that
    should make the issue clearer.

    Config: Apache 2.x, PHP 5.1.x, Windows XP Pro

    A php script processes a form. Inside this script I call exec to run a
    Windows process. If I press the submit button on the form repeatedly, exec
    starts and exit the process several times, but after 2-3 cycles, it starts
    the process, the process exits, but exec doesn't return, and it hangs the
    script and the session forever - it won't even timeout.

    I tried to block multiple POSTs by using a global var:

    if( isset( $_SESSION[ "processing " ] ) )
    {
    // 1
    exit;
    }
    else
    {
    $_SESSION[ "processing " ] = true;
    exec( ...);
    unset( _SESSION[ "processing " ] );
    }

    but the script never reaches //1.

    I am totally confused by this reentrancy issue and I don't know how to
    handle:
    1. multiple posts while the script is still running, to avoid hanging the
    session
    2. offering the ability to cancel the processing, if the process takes a
    long time.

    One of the requirements is that all processing happen on the server, so no
    JavaScript is allowed.

    A related question - can multiple php scripts run simultaneously in the same
    session -if a user presses submit multiple times, does this run new instance
    of the script for each POST?

    I would really appreciate any help.

    Thanks,

    A



  • Erwin Moller

    #2
    Re: Reentrant POST hangs the session

    a wrote:
    [color=blue]
    > I already posted on this subject, but I have some more information that
    > should make the issue clearer.
    >
    > Config: Apache 2.x, PHP 5.1.x, Windows XP Pro
    >
    > A php script processes a form. Inside this script I call exec to run a
    > Windows process. If I press the submit button on the form repeatedly, exec
    > starts and exit the process several times, but after 2-3 cycles, it starts
    > the process, the process exits, but exec doesn't return, and it hangs the
    > script and the session forever - it won't even timeout.[/color]

    Hi,

    No timeout?
    That sucks.
    Maybe it has to do with multiple requests having the same sessionid
    (PHPSESSID).

    If you have a default install, you'll have filebased sessionstorage, and
    just the default sessionhandling functions (No databasesession storage or own
    functions).

    I am not sure if this will help you solve the problem, but here is some
    backgroundinfor mation:

    I am unsure how things are implemented under Win XP, but under *nix the
    following happens:
    1) Request 1 (carrying some PHPSESSID) arives at the server.
    2) Server tries to open AND LOCK (flock()) the sessionfile to load the
    sessiondata into the scriptenvironme nt.
    3) Script terminates, and the (possibly changed) sessiondata is written to
    the file.

    This process repeats itself.
    If however a request arives at the server that carries a sessionid of a file
    that is already open (LOCKED), this requests WAITS untill the file gets
    unlocked.
    In this way you prevent multiple request to corrupt the sessionfile by
    simultanious writes to the same file, possibly all with other data.

    I suspect that you somehow leave the sessionfile locked with your systemcall
    that is not returning.
    You can check this by:
    1) determining the sessionid (Just ask your browser for the value of
    PHPSESID)
    2) Look up the corresponding file (in some temp-directory as mentioned in
    php.ini)
    3) Try to open and write to this file, by hand.

    If it is locked, you will not be able to.

    This is a *nix story.
    BUT, I am unsure how things work on XP. :-(

    Hope this helps you getting started with debugging.
    Sessionrelated problems tend to be hard to debug because most of the action
    go on before the script start, and after the script finishes.

    Regards,
    Erwin Moller
    [color=blue]
    >
    > I tried to block multiple POSTs by using a global var:
    >
    > if( isset( $_SESSION[ "processing " ] ) )
    > {
    > // 1
    > exit;
    > }
    > else
    > {
    > $_SESSION[ "processing " ] = true;
    > exec( ...);
    > unset( _SESSION[ "processing " ] );
    > }
    >
    > but the script never reaches //1.
    >
    > I am totally confused by this reentrancy issue and I don't know how to
    > handle:
    > 1. multiple posts while the script is still running, to avoid hanging the
    > session
    > 2. offering the ability to cancel the processing, if the process takes a
    > long time.
    >
    > One of the requirements is that all processing happen on the server, so no
    > JavaScript is allowed.
    >
    > A related question - can multiple php scripts run simultaneously in the
    > same session -if a user presses submit multiple times, does this run new
    > instance of the script for each POST?
    >
    > I would really appreciate any help.
    >
    > Thanks,
    >
    > A[/color]

    Comment

    • a

      #3
      Re: Reentrant POST hangs the session

      Thanks for your reply.

      Assuming that that's the problem (the locked session temp file) do you see
      any fixes, either in the code or by changing the configuration?

      I run another test, this time replacing the exec with a Sleep( 4 ), and sent
      multiple POST requests, and that didn't hang the session, so it seems to
      have something to do with exec.

      A


      Comment

      • Erwin Moller

        #4
        Re: Reentrant POST hangs the session

        a wrote:
        [color=blue]
        > Thanks for your reply.
        >
        > Assuming that that's the problem (the locked session temp file) do you see
        > any fixes, either in the code or by changing the configuration?[/color]

        Honestly no. I am not saying there are no fixes, but I just do not know
        engough of the internals of PHP and calling systemfunctions .
        I expect it is hard for PHP to monitor what is happening when it calls some
        systemfunction, and I can imagine PHP will 'hang' waiting for a response.
        But I do not know how this functionality is implemented.

        If I was in your situation I would first try to figure out if the systemcall
        sometimes hangs. Maybe by making a script that calls in 100 times in a row
        (increase the scriptimeout first).
        Also try to figure out if the systemcall you make is maybe getting in
        trouble if it is called many times in the same second. (Maybe it is not
        threadsafe.)
        You can check this simply by making a html-page that consist of 30 frames
        that all call the same php-script that performs the systemcall. Be sure to
        disable session for that PHP-script, otherwise you don't know if you are
        having a sessionproblem or something with the systemcall.

        If you are confident that the systemcall is ok, dive into a possibly blocked
        session.

        [color=blue]
        >
        > I run another test, this time replacing the exec with a Sleep( 4 ), and
        > sent multiple POST requests, and that didn't hang the session, so it seems
        > to have something to do with exec.[/color]

        Yes. Agree.
        [color=blue]
        >
        > A[/color]

        Good luck.
        Keep us informed with your findings.

        Regards,
        Erwin Moller

        Comment

        • a

          #5
          Re: Reentrant POST hangs the session

          [color=blue]
          > If I was in your situation I would first try to figure out if the
          > systemcall
          > sometimes hangs. Maybe by making a script that calls in 100 times in a row
          > (increase the scriptimeout first).
          > Also try to figure out if the systemcall you make is maybe getting in
          > trouble if it is called many times in the same second. (Maybe it is not
          > threadsafe.)[/color]

          My tests indicate that the script is run synchronously anyway, i.e. any new
          post will wait for current php script processing to end before starting the
          same script over. Also, the process called by exec starts and ends fine, it
          doesn't hang. I even changed it to exit immediately, just to make sure there
          were no other interferences. So the script hangs between the exit of my
          process and its return to the script.

          Also, 2 fast POSTs will not hang the script, only if there are more than 2,
          sometimes 3, sometimes 4. So maybe there is a race condition between the
          waiting posts, rather than between the one being processed and the one (or
          more) waiting.

          I will run some more tests where instead of doing exec, I will use some
          other interprocess communication mechanism (tcp/ip for example) see if this
          changes anything.

          Thanks for your interest in this.

          A


          Comment

          • Erwin Moller

            #6
            Re: Reentrant POST hangs the session

            a wrote:
            [color=blue]
            >[color=green]
            >> If I was in your situation I would first try to figure out if the
            >> systemcall
            >> sometimes hangs. Maybe by making a script that calls in 100 times in a
            >> row (increase the scriptimeout first).
            >> Also try to figure out if the systemcall you make is maybe getting in
            >> trouble if it is called many times in the same second. (Maybe it is not
            >> threadsafe.)[/color]
            >
            > My tests indicate that the script is run synchronously anyway, i.e. any
            > new post will wait for current php script processing to end before
            > starting the same script over.[/color]

            Is that test done WITH sessions enabled?
            Then every request to ANY script will wait that uses that session.

            That is why is advised you to disable session if you test this.
            If you both have session ebabled AND doing systemscalls, you do not know
            what you are testing.

            Also, the process called by exec starts and[color=blue]
            > ends fine, it doesn't hang. I even changed it to exit immediately, just to
            > make sure there were no other interferences. So the script hangs between
            > the exit of my process and its return to the script.[/color]

            Are you sure?
            I mean: Did you leave some trace that the beginning of the php-script DID
            run untill it reached the systemcall?
            [color=blue]
            >
            > Also, 2 fast POSTs will not hang the script, only if there are more than
            > 2, sometimes 3, sometimes 4. So maybe there is a race condition between
            > the waiting posts, rather than between the one being processed and the one
            > (or more) waiting.[/color]

            PHP is completely able to run the same script simultaniously 100 times, as
            long as there is no session (and thus possibly locking) involved.
            Your problem must be more subtile.
            [color=blue]
            >
            > I will run some more tests where instead of doing exec, I will use some
            > other interprocess communication mechanism (tcp/ip for example) see if
            > this changes anything.
            >
            > Thanks for your interest in this.[/color]

            Good luck.
            [color=blue]
            >
            > A[/color]

            Keep us informed. :-)

            Regards,
            Erwin Moller

            Comment

            • a

              #7
              Re: Reentrant POST hangs the session

              > Is that test done WITH sessions enabled?[color=blue]
              > Then every request to ANY script will wait that uses that session.
              >[/color]

              Yes, the session is enabled (see below why)- sorry for not mentioning this.
              [color=blue]
              > That is why is advised you to disable session if you test this.
              > If you both have session ebabled AND doing systemscalls, you do not know
              > what you are testing.
              >[/color]

              Since this script will be used in a production environment with the session
              enabled due to the nature of the application, and the error also occurs when
              the session is enabled, I thought that I didn't need to disable it. The
              session should actually prevent such an issue from happening alogether,
              since it serializes access to a script.
              [color=blue]
              > Also, the process called by exec starts and[color=green]
              >> ends fine, it doesn't hang. I even changed it to exit immediately, just
              >> to
              >> make sure there were no other interferences. So the script hangs between
              >> the exit of my process and its return to the script.[/color]
              >
              > Are you sure?
              > I mean: Did you leave some trace that the beginning of the php-script DID
              > run untill it reached the systemcall?
              >[/color]

              Yes, I created a diagnostic file where the script writes trace statements in
              various points, and also monitored the process exec-ed by the script, which
              is no longer in the list of active processes by the time the script hangs.

              Thanks,

              A


              Comment

              • R. Rajesh Jeba Anbiah

                #8
                Re: Reentrant POST hangs the session

                a wrote:[color=blue]
                > Thanks for your reply.
                >
                > Assuming that that's the problem (the locked session temp file) do you see
                > any fixes, either in the code or by changing the configuration?
                >
                > I run another test, this time replacing the exec with a Sleep( 4 ), and sent
                > multiple POST requests, and that didn't hang the session, so it seems to
                > have something to do with exec.[/color]



                --
                <?php echo 'Just another PHP saint'; ?>
                Email: rrjanbiah-at-Y!com Blog: http://rajeshanbiah.blogspot.com/

                Comment

                • Jim Michaels

                  #9
                  Re: Reentrant POST hangs the session


                  "Erwin Moller"
                  <since_humans_r ead_this_I_am_s pammed_too_much @spamyourself.c om> wrote in
                  message news:43eafbbf$0 $11061$e4fe514c @news.xs4all.nl ...[color=blue]
                  >a wrote:
                  >[color=green]
                  >> I already posted on this subject, but I have some more information that
                  >> should make the issue clearer.
                  >>
                  >> Config: Apache 2.x, PHP 5.1.x, Windows XP Pro
                  >>
                  >> A php script processes a form. Inside this script I call exec to run a
                  >> Windows process. If I press the submit button on the form repeatedly,
                  >> exec
                  >> starts and exit the process several times, but after 2-3 cycles, it
                  >> starts
                  >> the process, the process exits, but exec doesn't return, and it hangs the
                  >> script and the session forever - it won't even timeout.[/color]
                  >
                  > Hi,
                  >
                  > No timeout?
                  > That sucks.
                  > Maybe it has to do with multiple requests having the same sessionid
                  > (PHPSESSID).
                  >
                  > If you have a default install, you'll have filebased sessionstorage, and
                  > just the default sessionhandling functions (No databasesession storage or
                  > own
                  > functions).
                  >
                  > I am not sure if this will help you solve the problem, but here is some
                  > backgroundinfor mation:
                  >
                  > I am unsure how things are implemented under Win XP, but under *nix the
                  > following happens:
                  > 1) Request 1 (carrying some PHPSESSID) arives at the server.
                  > 2) Server tries to open AND LOCK (flock()) the sessionfile to load the
                  > sessiondata into the scriptenvironme nt.
                  > 3) Script terminates, and the (possibly changed) sessiondata is written to
                  > the file.[/color]

                  XP is nothing like UNIX except for its POSIX subsystem. But I suppose the
                  process here is somewhat similar.
                  [color=blue]
                  >
                  > This process repeats itself.
                  > If however a request arives at the server that carries a sessionid of a
                  > file
                  > that is already open (LOCKED), this requests WAITS untill the file gets
                  > unlocked.
                  > In this way you prevent multiple request to corrupt the sessionfile by
                  > simultanious writes to the same file, possibly all with other data.
                  >
                  > I suspect that you somehow leave the sessionfile locked with your
                  > systemcall
                  > that is not returning.
                  > You can check this by:
                  > 1) determining the sessionid (Just ask your browser for the value of
                  > PHPSESID)
                  > 2) Look up the corresponding file (in some temp-directory as mentioned in
                  > php.ini)
                  > 3) Try to open and write to this file, by hand.
                  >
                  > If it is locked, you will not be able to.
                  >
                  > This is a *nix story.
                  > BUT, I am unsure how things work on XP. :-(
                  >
                  > Hope this helps you getting started with debugging.
                  > Sessionrelated problems tend to be hard to debug because most of the
                  > action
                  > go on before the script start, and after the script finishes.
                  >
                  > Regards,
                  > Erwin Moller
                  >[color=green]
                  >>
                  >> I tried to block multiple POSTs by using a global var:
                  >>
                  >> if( isset( $_SESSION[ "processing " ] ) )
                  >> {
                  >> // 1
                  >> exit;
                  >> }
                  >> else
                  >> {
                  >> $_SESSION[ "processing " ] = true;
                  >> exec( ...);
                  >> unset( _SESSION[ "processing " ] );
                  >> }
                  >>
                  >> but the script never reaches //1.
                  >>
                  >> I am totally confused by this reentrancy issue and I don't know how to
                  >> handle:
                  >> 1. multiple posts while the script is still running, to avoid hanging the
                  >> session
                  >> 2. offering the ability to cancel the processing, if the process takes a
                  >> long time.
                  >>
                  >> One of the requirements is that all processing happen on the server, so
                  >> no
                  >> JavaScript is allowed.
                  >>
                  >> A related question - can multiple php scripts run simultaneously in the
                  >> same session -if a user presses submit multiple times, does this run new
                  >> instance of the script for each POST?
                  >>
                  >> I would really appreciate any help.
                  >>
                  >> Thanks,
                  >>
                  >> A[/color]
                  >[/color]


                  Comment

                  • Erwin Moller

                    #10
                    Re: Reentrant POST hangs the session

                    a wrote:
                    [color=blue][color=green]
                    >> Is that test done WITH sessions enabled?
                    >> Then every request to ANY script will wait that uses that session.
                    >>[/color]
                    >
                    > Yes, the session is enabled (see below why)- sorry for not mentioning
                    > this.[/color]

                    Hi a,
                    [color=blue]
                    >[color=green]
                    >> That is why is advised you to disable session if you test this.
                    >> If you both have session ebabled AND doing systemscalls, you do not know
                    >> what you are testing.
                    >>[/color]
                    >
                    > Since this script will be used in a production environment with the
                    > session enabled due to the nature of the application, and the error also
                    > occurs when the session is enabled, I thought that I didn't need to
                    > disable it. The session should actually prevent such an issue from
                    > happening alogether, since it serializes access to a script.[/color]

                    No, that is NOT the case.
                    But this is excactly what I was trying to tell you/warn you about:
                    PHP runs requests to all kind of pages simultaniously.
                    Also requests to the same script(!).
                    And even requests to the same script by the same user. (Unless a session is
                    involved)

                    The only reason PHP waits before executing a script is because THE SAME
                    SESSION IS IN USE. This can be in the same script, or in another script.
                    The execution will ONLY be postphoned if the session is locked (in use).

                    That is why you should try to disable it if you want to test the systemcall.

                    If you cannot test this for some reason, you'll have a harder time debug
                    your problem.

                    But you found a way (futher down this text).
                    [color=blue]
                    >[color=green]
                    >> Also, the process called by exec starts and[color=darkred]
                    >>> ends fine, it doesn't hang. I even changed it to exit immediately, just
                    >>> to
                    >>> make sure there were no other interferences. So the script hangs between
                    >>> the exit of my process and its return to the script.[/color]
                    >>
                    >> Are you sure?
                    >> I mean: Did you leave some trace that the beginning of the php-script DID
                    >> run untill it reached the systemcall?
                    >>[/color]
                    >
                    > Yes, I created a diagnostic file where the script writes trace statements
                    > in various points, and also monitored the process exec-ed by the script,
                    > which is no longer in the list of active processes by the time the script
                    > hangs.[/color]

                    Ok, so that proves that the script started, right?
                    In that case you know you didn't have a sessionproblem indeed, otherwise it
                    just didn't start.

                    Conclusion: Your systemcall makes the script hang, but the PHPprocess is
                    terminated, and didn't return anything, not even the beginning of the
                    response (headers and such).

                    Some thing you could look at:
                    Are you using output buffering? obstart();
                    If so, flush the output before calling the systemcall.

                    You could also try to see if the script returns anything by calling it with
                    something else than a webbrowser (like wget).

                    Well, good luck, I am out of ideas.

                    Regards,
                    Erwin Moller
                    [color=blue]
                    >
                    > Thanks,
                    >
                    > A[/color]

                    Comment

                    Working...