r109802 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r109801‎ | r109802 | r109803 >
Date:02:55, 23 January 2012
Author:aaron
Status:deferred
Tags:filebackend 
Comment:
In LockServerDaemon:
* Factored out LockHolder class from main class
* Tweaked a few socket options (using a non-blocking accept() and keep alives for new clients)
Modified paths:
  • /trunk/phase3/maintenance/locking/LockServerDaemon.php (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/locking/LockServerDaemon.php
@@ -22,30 +22,22 @@
2323 /** @var resource */
2424 protected $sock; // socket to listen/accept on
2525 /** @var Array */
26 - protected $shLocks = array(); // (key => session => 1)
27 - /** @var Array */
28 - protected $exLocks = array(); // (key => session)
29 - /** @var Array */
3026 protected $sessions = array(); // (session => resource)
3127 /** @var Array */
3228 protected $deadSessions = array(); // (session => UNIX timestamp)
3329
34 - /** @var Array */
35 - protected $sessionIndexSh = array(); // (session => key => 1)
36 - /** @var Array */
37 - protected $sessionIndexEx = array(); // (session => key => 1)
 30+ /** @var LockHolder */
 31+ protected $lockHolder;
3832
3933 protected $address; // string (IP/hostname)
4034 protected $port; // integer
4135 protected $authKey; // string key
4236 protected $connTimeout; // array ( 'sec' => integer, 'usec' => integer )
4337 protected $lockTimeout; // integer number of seconds
44 - protected $maxLocks; // integer
 38+ protected $maxBacklog; // integer
4539 protected $maxClients; // integer
46 - protected $maxBacklog; // integer
4740
4841 protected $startTime; // integer UNIX timestamp
49 - protected $lockCount = 0; // integer
5042 protected $ticks = 0; // integer counter
5143
5244 protected static $instance = null;
@@ -88,17 +80,19 @@
8981 'usec' => floor( ( $connTimeout - floor( $connTimeout ) ) * 1e6 )
9082 );
9183 $this->lockTimeout = isset( $config['lockTimeout'] )
92 - ? $config['lockTimeout']
 84+ ? (int)$config['lockTimeout']
9385 : 60;
94 - $this->maxLocks = isset( $config['maxLocks'] )
95 - ? $config['maxLocks']
96 - : 5000;
9786 $this->maxClients = isset( $config['maxClients'] )
98 - ? $config['maxClients']
 87+ ? (int)$config['maxClients']
9988 : 1000; // less than default FD_SETSIZE
10089 $this->maxBacklog = isset( $config['maxBacklog'] )
101 - ? $config['maxBacklog']
102 - : 10;
 90+ ? (int)$config['maxBacklog']
 91+ : 100;
 92+ $maxLocks = isset( $config['maxLocks'] )
 93+ ? (int)$config['maxLocks']
 94+ : 5000;
 95+
 96+ $this->lockHolder = new LockHolder( $maxLocks );
10397 }
10498
10599 /**
@@ -113,6 +107,7 @@
114108 throw new Exception( "socket_create(): " . socket_strerror( socket_last_error() ) );
115109 }
116110 socket_set_option( $sock, SOL_SOCKET, SO_REUSEADDR, 1 ); // bypass 2MLS
 111+ socket_set_nonblock( $sock ); // don't block on accept()
117112 if ( socket_bind( $sock, $this->address, $this->port ) === false ) {
118113 throw new Exception( "socket_bind(): " .
119114 socket_strerror( socket_last_error( $sock ) ) );
@@ -135,7 +130,7 @@
136131 $clients = array( $this->sock ); // start off with listening socket
137132 do {
138133 // Create a copy, so $clients doesn't get modified by socket_select()
139 - $read = $clients; // clients-with-data
 134+ $read = $clients; // clients-with-data (plus listening socket)
140135 // Get a list of all the clients that have data to be read from
141136 $changed = socket_select( $read, $write = NULL, $except = NULL, NULL );
142137 if ( $changed === false ) {
@@ -148,12 +143,15 @@
149144 if ( in_array( $this->sock, $read ) && count( $clients ) < $this->maxClients ) {
150145 // Accept the new client...
151146 $newsock = socket_accept( $this->sock );
152 - socket_set_option( $newsock, SOL_SOCKET, SO_RCVTIMEO, $this->connTimeout );
153 - socket_set_option( $newsock, SOL_SOCKET, SO_SNDTIMEO, $this->connTimeout );
154 - $clients[] = $newsock;
155 - // Remove the listening socket from the clients-with-data array...
156 - $key = array_search( $this->sock, $read );
157 - unset( $read[$key] );
 147+ if ( $newsock ) {
 148+ socket_set_option( $newsock, SOL_SOCKET, SO_KEEPALIVE, 1 );
 149+ socket_set_option( $newsock, SOL_SOCKET, SO_RCVTIMEO, $this->connTimeout );
 150+ socket_set_option( $newsock, SOL_SOCKET, SO_SNDTIMEO, $this->connTimeout );
 151+ $clients[] = $newsock;
 152+ // Remove the listening socket from the clients-with-data array...
 153+ $key = array_search( $this->sock, $read );
 154+ unset( $read[$key] );
 155+ }
158156 }
159157 // Loop through all the clients that have data to read...
160158 foreach ( $read as $read_sock ) {
@@ -210,11 +208,11 @@
211209 $this->sessions[$session] = $sourceSock;
212210 }
213211 if ( $function === 'ACQUIRE' ) {
214 - return $this->lock( $session, $type, $resources );
 212+ return $this->lockHolder->lock( $session, $type, $resources );
215213 } elseif ( $function === 'RELEASE' ) {
216 - return $this->unlock( $session, $type, $resources );
 214+ return $this->lockHolder->unlock( $session, $type, $resources );
217215 } elseif ( $function === 'RELEASE_ALL' ) {
218 - return $this->release( $session );
 216+ return $this->lockHolder->release( $session );
219217 } elseif ( $function === 'STAT' ) {
220218 return $this->stat();
221219 }
@@ -262,12 +260,63 @@
263261 }
264262
265263 /**
 264+ * Clear locks for sessions that have been dead for a while
 265+ *
 266+ * @return integer Number of sessions purged
 267+ */
 268+ protected function purgeExpiredLocks() {
 269+ $now = time();
 270+ $count = 0;
 271+ foreach ( $this->deadSessions as $session => $timestamp ) {
 272+ if ( ( $now - $timestamp ) > $this->lockTimeout ) {
 273+ $this->lockHolder->release( $session );
 274+ unset( $this->deadSessions[$session] );
 275+ ++$count;
 276+ }
 277+ }
 278+ return $count;
 279+ }
 280+
 281+ /**
 282+ * @return string
 283+ */
 284+ protected function stat() {
 285+ return ( time() - $this->startTime ) . ':' . memory_get_usage();
 286+ }
 287+}
 288+
 289+/**
 290+ * LockServerDaemon helper class that keeps track of the locks.
 291+ * This should not require MediaWiki setup or PHP files.
 292+ */
 293+class LockHolder {
 294+ /** @var Array */
 295+ protected $shLocks = array(); // (key => session => 1)
 296+ /** @var Array */
 297+ protected $exLocks = array(); // (key => session)
 298+
 299+ /** @var Array */
 300+ protected $sessionIndexSh = array(); // (session => key => 1)
 301+ /** @var Array */
 302+ protected $sessionIndexEx = array(); // (session => key => 1)
 303+ protected $lockCount = 0; // integer
 304+
 305+ protected $maxLocks; // integer
 306+
 307+ /**
 308+ * @params $maxLocks integer Maximum number of locks to allow
 309+ */
 310+ public function __construct( $maxLocks ) {
 311+ $this->maxLocks = $maxLocks;
 312+ }
 313+
 314+ /**
266315 * @param $session string
267316 * @param $type string
268317 * @param $keys Array
269318 * @return string
270319 */
271 - protected function lock( $session, $type, $keys ) {
 320+ public function lock( $session, $type, array $keys ) {
272321 if ( $this->lockCount >= $this->maxLocks ) {
273322 return 'TOO_MANY_LOCKS';
274323 }
@@ -312,7 +361,7 @@
313362 * @param $keys Array
314363 * @return string
315364 */
316 - protected function unlock( $session, $type, $keys ) {
 365+ public function unlock( $session, $type, array $keys ) {
317366 if ( $type === 'SH' ) {
318367 foreach ( $keys as $key ) {
319368 $this->unset_sh_lock( $key, $session );
@@ -331,7 +380,7 @@
332381 * @param $session string
333382 * @return string
334383 */
335 - protected function release( $session ) {
 384+ public function release( $session ) {
336385 if ( isset( $this->sessionIndexSh[$session] ) ) {
337386 foreach ( $this->sessionIndexSh[$session] as $key => $x ) {
338387 $this->unset_sh_lock( $key, $session );
@@ -346,28 +395,6 @@
347396 }
348397
349398 /**
350 - * @return string
351 - */
352 - protected function stat() {
353 - return ( time() - $this->startTime ) . ':' . memory_get_usage();
354 - }
355 -
356 - /**
357 - * Clear locks for sessions that have been dead for a while
358 - *
359 - * @return void
360 - */
361 - protected function purgeExpiredLocks() {
362 - $now = time();
363 - foreach ( $this->deadSessions as $session => $timestamp ) {
364 - if ( ( $now - $timestamp ) > $this->lockTimeout ) {
365 - $this->release( $session );
366 - unset( $this->deadSessions[$session] );
367 - }
368 - }
369 - }
370 -
371 - /**
372399 * @param $key string
373400 * @param $session string
374401 * @return void

Follow-up revisions

RevisionCommit summaryAuthorDate
r110222In LockServerDaemon:...aaron20:54, 28 January 2012

Status & tagging log