By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,099 Members | 2,156 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,099 IT Pros & Developers. It's quick & easy.

Reentrant POST hangs the session

P: n/a
a
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

Feb 9 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
a wrote:
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.
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 sessionhandlingfunctions (No databasesessionstorage or own
functions).

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

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 scriptenvironment.
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

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


Feb 9 '06 #2

P: n/a
a
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
Feb 9 '06 #3

P: n/a
a wrote:
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?
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.


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.
Yes. Agree.

A


Good luck.
Keep us informed with your findings.

Regards,
Erwin Moller
Feb 9 '06 #4

P: n/a
a
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.)


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
Feb 10 '06 #5

P: n/a
a wrote:
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.)
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.


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 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.
Are you sure?
I mean: Did you leave some trace that the beginning of the php-script DID
run untill it reached the systemcall?

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

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.
Good luck.

A


Keep us informed. :-)

Regards,
Erwin Moller
Feb 10 '06 #6

P: n/a
a
> Is that test done WITH sessions enabled?
Then every request to ANY script will wait that uses that session.

Yes, the session is enabled (see below why)- sorry for not mentioning this.
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.

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


Are you sure?
I mean: Did you leave some trace that the beginning of the php-script DID
run untill it reached the systemcall?


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
Feb 10 '06 #7

P: n/a
a wrote:
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.


http://in2.php.net/session_write_close

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

Feb 11 '06 #8

P: n/a

"Erwin Moller"
<si******************************************@spam yourself.com> wrote in
message news:43***********************@news.xs4all.nl...
a wrote:
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.
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 sessionhandlingfunctions (No databasesessionstorage or
own
functions).

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

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 scriptenvironment.
3) Script terminates, and the (possibly changed) sessiondata is written to
the file.


XP is nothing like UNIX except for its POSIX subsystem. But I suppose the
process here is somewhat similar.

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

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

Feb 12 '06 #9

P: n/a
a wrote:
Is that test done WITH sessions enabled?
Then every request to ANY script will wait that uses that session.

Yes, the session is enabled (see below why)- sorry for not mentioning
this.


Hi a,
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.

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.


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).
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.
Are you sure?
I mean: Did you leave some trace that the beginning of the php-script DID
run untill it reached the systemcall?


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.


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

Thanks,

A


Feb 17 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.