Did we forget to use session_write_close()?

Did we forget to use session_write_close()?

by Petr Skoda -
Number of replies: 12
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
Hi!

I noticed that my Moodle can not do two things at the same time, eg: download from file area and navigate course.

IMO it may be because we do not use session_write_close() - see php man here. In short: pages block on access to session file, session_write_close flushes session to disk and releases file lock. You can not change $SESSION and $USER after closing session, but you can still read it.

There are several places that could use it:
  • file.php
  • long pages that display pictures from file area
  • any other pages that take long time to display
  • before redirection (not sure??)

We do not need to call it when $nomoodlecookie = true;, because the session is not started and hence the session file is not opened.

Did I get it right??
Are there any hidden side effects??

Anyway I need this concurrent downloads for byte-serving and improved pdf support wink

skodak


Average of ratings: -
In reply to Petr Skoda

Re: Did we forget to use session_write_close()?

by Martín Langhoff -
Are you sure that's the source of your problem? I usually have half a dozen tabs in mozilla to the same Moodle installation, doing things in them. I sometimes keep the 'live log' page in the background, which would effectively lock things.

On the other hand, I'm on Linux, and the sessions are on NFS. What's your install like?
In reply to Martín Langhoff

Re: Did we forget to use session_write_close()?

by Petr Skoda -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
Mine is Win32 NTFS. I did try to erase/view the session file while downloading and got error, the file was write-locked. If I add session_write_close() to file.php I can view/erase session file while downloading smile

AFAIK file locking on NFS in *nix can be a bit problematic, but I am not an expert...
In reply to Petr Skoda

Re: Did we forget to use session_write_close()?

by Martín Langhoff -
Hmmm.

I can confirm file locking on NFS is working fine at this end (using Debian Linux with a newish kernel), I'm using it for mutexes and it's great.

We also have dev installs writing to the local disk, and they aren't seeing any locking issues either.

Session files should be write-locked but not read-locked, you say you can't read them -- even if you are the webserver?

In any case, this should be fixed -- but I suspect it's limited to win32.
In reply to Petr Skoda

Re: Did we forget to use session_write_close()?

by Eloy Lafuente (stronk7) -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Peer reviewers Picture of Plugin developers Picture of Testers
Hi Petr,

I had noticed such effect specially when I was downloading some long documents using file.php. I wasn't able to load another page (php, in the same server) until the download finished. I thought that it was due to my bandwidth (being 100% used by the download) but, after reading PHP documentation it can be the cause.

To make a quick test try the following:

Uhmm, interesting!! Difference is notable, isn't it?

My +1 vote for this. Being sure that we apply it to scripts where session data isn't going to be modified at all, of course.

Ciao smile
In reply to Eloy Lafuente (stronk7)

Re: Did we forget to use session_write_close()?

by Mark Stevens -
Uhmm, interesting!! Difference is notable, isn't it?

Eloy, the difference is Martin's moodle.org server is so slow wink
In reply to Mark Stevens

Re: Did we forget to use session_write_close()?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

Is it?!  Not for me except very occasionally when some other processes are running (moodle.com backups) ... I've actually just bought another server this weekend so I can move these processes away from this server and give it more room to grow.

In reply to Martin Dougiamas

Re: Did we forget to use session_write_close()?

by Mark Stevens -
I'm sorry, I thought you would see my wink blush  I've never had any problems with moodle.org big grin

What kind of server did you get?  IDG just named Apple's Xserve G5 the best server hardware wink   Shameless wink and plug for my favourite platform smile http://home.businesswire.com/portal/site/google/index.jsp?ndmViewId=news_view&newsId=20050103005060&newsLang=en
In reply to Mark Stevens

Re: Did we forget to use session_write_close()?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
Ah, sorry, I wasn't sure about the smiley. smile

An Xserve would be swanky, but on my budget I stick with boring old Intel hardware... the new one is only for non-urgent repetitive tasks like packaging up releases, storing backups and processing mail, so it's just a 2.4Ghz Celeron running Debian.  But this is offtopic ... smile
In reply to Eloy Lafuente (stronk7)

Re: Did we forget to use session_write_close()?

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

Ah, good demo Eloy and nice catch Petr!

The demo doesn't work anymore now because I've now added that call to file.php on moodle.org ... If we don't see any side effects for a while I'll put it in CVS.

What will happen if there are two concurrent scripts in a session that start at exactly the same time (eg in a frame) and one of them turns off the write but the other one still needs to do some writing to it?

In reply to Martin Dougiamas

Re: Did we forget to use session_write_close()?

by Eloy Lafuente (stronk7) -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Peer reviewers Picture of Plugin developers Picture of Testers
exactly the same time? I think that always one script (or should we call it request), gets the "semaphore" and put it "in red" for the rest. When the semaphore is "green" (by an implicit or explicit session_write_close()) the next request gets the semaphore... and so on.

The only potential problem with this is that we have to be absolutely sure that the request isn't going to write data to session after session_write_close().

Framed environments (resource display) will benefit of this too, sure... and I think that scripts calling to other scripts (in the same request) will be able to use sessions to store data and ensure that such data is committed and available for called (secondary) scripts. I had some problems with this when working in the glossary_only_first filter.

Ciao smile
In reply to Eloy Lafuente (stronk7)

Re: Did we forget to use session_write_close()?

by Petr Skoda -
Picture of Core developers Picture of Documentation writers Picture of Peer reviewers Picture of Plugin developers
I am not sure, but this could also enable "preloading" as discussed here.

IMO it should not be a problem to close sessions in most scripts explicitly. Later if we use Smarty it should be safe to close it always before rendering page. Even now most script prepare data and only then start outputting HTML.

We could define custum functions in setup.php:
mdl_open_session();
mdl_close_session();

We could then safely reopen session if needed...
In reply to Petr Skoda

Re: Did we forget to use session_write_close()?

by Martín Langhoff -
I'm trying to think of other candidate pages to add this to, but I don't see any. Ideas?

Also, a couple of extra notes:

- apparently session_write_close() is actually called session_flush() in PHP 4.3.8; see comments in http://nz.php.net/manual/en/function.session-write-close.php

- It's a bit risky in that $SESSION and $USER will still be around, but changes will be discarded.