Last modified: 2010-05-15 16:03:49 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 T15587, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 13587 - Editing a page with the api is half broken
Editing a page with the api is half broken
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
API (Other open bugs)
1.13.x
All All
: Normal major (vote)
: ---
Assigned To: Roan Kattouw
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-04-02 08:11 UTC by Tony
Modified: 2010-05-15 16:03 UTC (History)
3 users (show)

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


Attachments

Description Tony 2008-04-02 08:11:34 UTC
When using the api to edit a page, most data is saved, such as, the page content, recentchanges, etc. Although, there is a lot that does not get updated in some cases. Notably, everything that happens in the LinksUpdate object.

If I send an edit to the api that contains wikitext like categories, external links, images, etc, they will not be updated in the various db tables. The reason is, a new transaction begins just before the database insert and update statements for these things happens, and there is never a commit sent to the db. Essentially, the transaction is never committed, so these insert and update queries get rolled back in mysql.

Having fully debugged the issue I've found the cause to be a small difference between regular mediawiki vs the api. If you'll notice in the main index.php for mediawiki one of the last lines of code is:

$mediaWiki->finalCleanup ( $wgDeferredUpdateList, $wgOut );

That method runs a commit against the database, ensuring these types of issues don't pop up. That's fine I guess, but there is no equivalent in the api, hence this bug report. Although mostly a hack, I've resolved this issue by adding:

$dbw = wfGetDB( DB_MASTER );
$dbw->commit();

to /includes/api/ApiEditPage.php just below line 193 from svn revision 32595 of the vodaphone branch.

That is obviously not a long term solution, but it proves the problem is identified (not to mention I got to the point where I was outputting all queries run inside mediawiki, and a final commit was missing).
Comment 1 Bryan Tong Minh 2008-04-02 10:45:26 UTC
The proper way is doing $dbw->immediateCommit(); instead of $dbw->commit(); Don't ask me why.

The long term solution is probably to have a finalCleanup(); method available for all write APIs.
Comment 2 Roan Kattouw 2008-04-02 12:15:12 UTC
I simply forgot to do $dbw->commit(); after performing the edit. Other write modules also do that. commit() was added in r32701, please test whether that fixes it.
Comment 3 Tony 2008-04-02 16:32:59 UTC
Using r32701 it works :) Maybe you should talk to Bryan though, cause he is suggesting immediateCommit()
Comment 4 Bryan Tong Minh 2008-04-02 17:07:37 UTC
(In reply to comment #3)
> Using r32701 it works :) Maybe you should talk to Bryan though, cause he is
> suggesting immediateCommit()
> 

Well that's what <http://www.mediawiki.org/wiki/Manual:Database_access#Lock_contention> tells me: "There are functions called begin() and commit() but they don't do what you would expect. Don't use them."

In any case, the main code in Wiki.php is:

    function finalCleanup ( &$deferredUpdates, &$output ) {
        wfProfileIn( __METHOD__ );
        $this->doUpdates( $deferredUpdates );
        $this->doJobs();
        # Now commit any transactions, so that unreported errors after output() don't roll back the whole thing
        $factory = wfGetLBFactory();
        $factory->shutdown();
        $output->output();
        wfProfileOut( __METHOD__ );
    }

I think that wfGetLBFactory()->shutdown(); is the more appropriate way to do this?
Comment 5 Roan Kattouw 2008-04-02 17:32:56 UTC
(In reply to comment #4)
> In any case, the main code in Wiki.php is:
> 
>     function finalCleanup ( &$deferredUpdates, &$output ) {
>         wfProfileIn( __METHOD__ );
>         $this->doUpdates( $deferredUpdates );
>         $this->doJobs();
>         # Now commit any transactions, so that unreported errors after output()
> don't roll back the whole thing
>         $factory = wfGetLBFactory();
>         $factory->shutdown();
>         $output->output();
>         wfProfileOut( __METHOD__ );
>     }
> 
> I think that wfGetLBFactory()->shutdown(); is the more appropriate way to do
> this?

I'll just make sure API requests call MediaWiki::finalCleanup() when they finish and call $wgOut->disable() first so $output->output() becomes a no-op. That's probably cleaner than all those $dbw->begin() and $dbw->commit() calls.
Comment 6 Roan Kattouw 2008-04-02 18:06:12 UTC
(In reply to comment #5)
> I'll just make sure API requests call MediaWiki::finalCleanup() when they
> finish and call $wgOut->disable() first so $output->output() becomes a no-op.
> That's probably cleaner than all those $dbw->begin() and $dbw->commit() calls.
> 
I've done it slightly differently: I just had api.php call MediaWiki::doUpdates() when it finishes in r32717. I've also removed the commit() call in action=edit, haven't tested for other modules yet (haven't designed test interfaces for them yet).

Comment 7 Roan Kattouw 2008-05-09 10:49:51 UTC
Forgot to close this one

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


Navigation
Links