Skip to content

Instantly share code, notes, and snippets.

@mkorkmaz
Last active December 12, 2015 06:28
Show Gist options
  • Save mkorkmaz/4728951 to your computer and use it in GitHub Desktop.
Save mkorkmaz/4728951 to your computer and use it in GitHub Desktop.
Determine dsn string for PDO to connect multiple nodes. If one node is down, removes it ASAP ( in this script it takes max 15 secs )
<?php
class DetermineDSNForPDO{
public $dsn = '';
public $system_failover = FALSE;
public $node_failover = array();
public function __construct( $type, $nodes, $port ){
$system_failover= strtoupper( $type ) . "_FAILOVER";
$dsn_key = strtoupper( $type ) . "_DSN";
$dsn_expire_key = strtoupper( $type ) . "_DSN_EXPIRE";
$dsn = apc_fetch( $dsn_key );
$dsn_expire = apc_fetch( $dsn_expire_key );
$failover = apc_fetch( $system_failover );
if( $failover === 1 ){
$this->system_failover = TRUE;
}
else{
if( $dsn === FALSE ){
$dsn = $this->determine_dsn( $type, $nodes, $port );
apc_store( $dsn_key, $dsn );
apc_store( $dsn_expire_key, 1, 15 );
$dsn_expire = 1;
}
if( $dsn_expire === FALSE ){
apc_store( $dsn_expire_key, 1, 15 );
$dsn = $this->determine_dsn( $type, $nodes, $port );
apc_store( $dsn_key, $dsn );
if( $this->system_failover === TRUE ){
apc_store( $system_failover, 1, 15 );
}
}
$this->dsn = $dsn;
}
}
private function determine_dsn( $type, $nodes, $port ){
$node_failover = 0;
$nof_nodes = count( $nodes );
$first = 1;
$dsn = $type . ":";
foreach ( $nodes as $node ){
$fp = @fsockopen( "tcp://" . $node, $port, $errno, $errstr, 0.05 );
if ( $fp ) {
fclose( $fp );
if( $first == 0 ){
$dsn .= ",";
}
$dsn .= "host=" . $node . ";port=" . $port;
$first = 0 ;
}
else{
$node_failover++;
$this->node_failover[] = $node . ":" . $port;
}
}
if( $node_failover == $nof_nodes ){
$this->system_failover = TRUE;
}
return $dsn;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment