"Catrope" changed the status of MediaWiki.r108559 to "fixme" and commented it.
URL: http://www.mediawiki.org/wiki/Special:Code/MediaWiki/108559#c29325

Old Status: new
> New Status: fixme

Commit summary for MediaWiki.r108559:

MERGE branches/concurrency 108301:108557 into trunk

Catrope's comment:

<pre>
         $wgConcurrencyExpirationMin = 60 * -1; // Minimum possible checkout 
duration.  Negative is possible (but barely) for testing.
</pre>
What does "barely possible" mean? Why is this set to a negative value by 
default while that's apparently discouraged?

<pre>
$memc = wfGetMainCache();
</pre>
Why not use $wgMemc like most things do?

<pre>
$cacheKey = wfMemcKey( $this->resourceType, $record );
</pre>
Please prefix this with 'concurrencycheck'

<pre>
                                'cc_expiration' => time() + 
$this->expirationTime,
</pre>
You're using UNIX timestamps in the DB instead of MW timestamps? Everything 
else in MW uses the DB-specific timestamp format (14-character TS_MW timestamps 
for MySQL and SQLite, and God-knows-what for Postgres), you may want to do that 
too for consistency (although I see how using UNIX timestamps everywhere makes 
things easy). To format a timestamp for DB consumption, use 
<code>$db->timestamp( $ts )</code> , to convert it back to a UNIX timestamp, 
use <code>wfTimestamp( TS_UNIX, $ts )</code> .

The logic in ConcurrencyCheck::checkout() is flawed and allows for race 
conditions. One thing that can happen is that two processes try to INSERT a 
lock, but both fail because there is a previous, expired lock. They will then 
both execute the REPLACE query (which will insert identical data), and both 
will think they have the lock. Instead, you should first issue a DELETE query 
to delete any expired or same-user locks (or any locks if $override is set; 
that parameter looks dangerous and should be documented as such) that might 
exist, then do the INSERT stuff. That way everything is atomic. Generally, if 
you're doing a SELECT, followed by an if statement, followed by a write query, 
you're [probably doing something wrong. The fact that things happen in a 
transaction may or may not mitigate this, I'm not sure, but doing it without 
transactions or locking is always better.

In checkin(), you're checking whether the DELETE did anything before removing 
the memc key. I don't understand why you're doing this, and you should probably 
delete the memc key unconditionally here.

expire() is weird because you're selecting first, then deleting, only so you 
can delete from memc. But the memc entries already have expiry timestamps set, 
so this isn't necessary.

<pre>
                                        'cc_record IN (' . implode( ',', 
$toSelect ) . ')',
</pre>
Don't do this, use <code>'cc_record' => $toSelect,</code> .

In status(), you don't need to check for freshness right after calling 
expire(), do you?

<pre>
                        // the transaction seems incongruous, I know, but it's 
to keep the cache update atomic.
</pre>
That makes no sense to me whatsoever. Memc updates don't behave differently 
inside or outside of database transactions, unless you happen to be using 
CACHE_DB.

<pre>
                // check to make sure the time is digits only, so it can be 
used in queries
                if( $expirationTime && preg_match('/^[\d-]+$/', 
$expirationTime) ) {
</pre>
Just cast it to an integer.

<pre>
                if( ! preg_match('/^\d+$/', $record) ) {
</pre>
Again, it's simpler to just cast to an integer, check for >0 (the current code 
lets 0 slip through), then cast back to a string and compare with the input.

The rest of the revision is OK.

_______________________________________________
MediaWiki-CodeReview mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-codereview

Reply via email to