Last modified: 2014-08-24 16:30:36 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T71657, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 69657 - [PhpTags] exception in updateBytecodeCache() related to database serialization when using ExtSQI
[PhpTags] exception in updateBytecodeCache() related to database serializatio...
Status: RESOLVED FIXED
Product: MediaWiki extensions
Classification: Unclassified
Other (Other open bugs)
master
All All
: Unprioritized normal (vote)
: ---
Assigned To: Pavel (pastakhov)
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2014-08-17 10:52 UTC by Joel K. Pettersson
Modified: 2014-08-24 16:30 UTC (History)
2 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Joel K. Pettersson 2014-08-17 10:52:55 UTC
After saving, and after purging, a page containing PhpTags SMW ExtSQI queries on it, an exception is triggered within PhpTags. The printout included below appears on the page instead of its contents. (I'm using MW 1.24-git and PhpTags 3.4.2.)

serialize() calls the __sleep() member function on objects, and DatabaseBase defines this to throw the exception you see below. So this happens when an object which has DatabaseBase as a parent class is somewhere within the bytecode output data - which is serialized in PhpTags.body.php on line 192.

To test, I added a line to do var_dump() on each element of $dataArray above line 192 in PhpTags.body.php. Indeed, there were SMW-related objects from the querying done by SQI present.

I guess similar issues could appear with other kinds of querying, whenever some object using a DatabaseBase-related class is contained in something constructed by a PhpTags expression.

Solving this in a good way may be tricky, I guess. Here are some ideas I can think of, but I don't know how good they are:

1. The simplest, but not ideal: Extensions to PhpTags could have a way to turn off bytecode caching, using an addition to the PhpTags API. Then an extension should call that method if an object is created that would cause trouble with serialization. Maybe good as a short-term fix?

2. Similar but more complex idea which preserves more caching: Each object defined by a PhpTags extension could specify if it should be cached. Then a "source" instruction could be added to the bytecode, and uses of non-cached objects are initially "compiled" to a "source" instruction and a copy of the command(s). Then the runtime would run the bytecode, and whenever it encounters "source", that piece is compiled (for real this time) and then ran.

3. Other, more complex ideas could also be possible, based on changing the bytecode format. Would it be possible, in an efficient way, to make it so that the bytecode no longer contains objects allocated by the extensions? For example, bytecode instructions for performing the calls to create the data?

4. Another idea - not part of solving this, but it could perhaps later be used as an optimization to improve performance. (But it adds even more complication.) Each object defined by a PhpTags extension could specify whether the output is "static" or "dynamic" relative to the input. ("Static" would include anything which depends only on the current page revision and is not random - e.g. also the title, IDs, last editor. But "$frameID" for caching would have to be changed to revision ID rather than page ID, since data outside each PhpTags block on a page can then change "static" output.) Then the compilation could keep track of inputs and outputs, and for any "static" output, the use of the object is replaced by an "echo" and the result. But to keep this from becoming a mess, an extensive redesign would probably be needed beforehand.

The last idea may be over-the-top. Anyway, I'm just playing with concepts, after looking through the source code (but not all of its details) and getting a rough sense of the design. Don't know if or how useful it may be.

Here is the printout:

[089c1ea3] /wiki/TestPTSQI Exception from line 812 of /vagrant/mediawiki/includes/db/Database.php: Database serialization may cause problems, since the connection is not restored on wakeup.

Backtrace:

#0 /vagrant/mediawiki/extensions/PhpTags/PhpTags.body.php(192): DatabaseBase->__sleep()
#1 /vagrant/mediawiki/extensions/PhpTags/PhpTags.body.php(178): PhpTags::updateBytecodeCache()
#2 /vagrant/mediawiki/includes/Hooks.php(206): PhpTags::onOutputPageParserOutput()
#3 /vagrant/mediawiki/includes/GlobalFunctions.php(3975): Hooks::run(string, array, NULL)
#4 /vagrant/mediawiki/includes/OutputPage.php(1672): wfRunHooks(string, array)
#5 /vagrant/mediawiki/includes/OutputPage.php(1711): OutputPage->addParserOutputMetadata(ParserOutput)
#6 /vagrant/mediawiki/includes/page/Article.php(704): OutputPage->addParserOutput(ParserOutput)
#7 /vagrant/mediawiki/includes/actions/ViewAction.php(44): Article->view()
#8 /vagrant/mediawiki/includes/MediaWiki.php(439): ViewAction->show()
#9 /vagrant/mediawiki/includes/MediaWiki.php(307): MediaWiki->performAction(Article, Title)
#10 /vagrant/mediawiki/includes/MediaWiki.php(609): MediaWiki->performRequest()
#11 /vagrant/mediawiki/includes/MediaWiki.php(460): MediaWiki->main()
#12 /vagrant/mediawiki/index.php(46): MediaWiki->run()
#13 /var/www/w/index.php(5): include(string)
#14 {main}
Comment 1 Pavel (pastakhov) 2014-08-17 12:40:38 UTC
Any objects should never be cached, it is third point. It is the bug and I'll fix it. Bytecode never contains the objects right after compilation (it contains only instructions) and it should cached in this form.

The problem is that bytecode is cached after use and contains data that should not be in the cache, this is easily remedied.

Regarding the first point: if you set variable $wgPhpTagsBytecodeExptime = 0; PhpTags will not use caching. When I fix the error, you can return it to its original state.  I will increase the value of constant PHPTAGS_RUNTIME_RELEASE and existing old wrong cache will be not used.

Thank you for the bug report
Comment 2 Gerrit Notification Bot 2014-08-19 14:03:27 UTC
Change 155029 had a related patch set uploaded by 01tonythomas:
fix bytecode cache (v 3.5.0, Runtime release is 2)

https://gerrit.wikimedia.org/r/155029
Comment 3 Gerrit Notification Bot 2014-08-19 14:35:55 UTC
Change 155029 merged by jenkins-bot:
fix bytecode cache (v 3.5.0, Runtime release is 2)

https://gerrit.wikimedia.org/r/155029
Comment 4 Joel K. Pettersson 2014-08-24 16:30:36 UTC
Sorry for the delay. The fix works, so I'm closing this as resolved.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links