Index: trunk/extensions/Cassandra/Cassandra_body.php |
— | — | @@ -31,22 +31,27 @@ |
32 | 32 | |
33 | 33 | public function store( $cluster, $data ) { |
34 | 34 | global $wgCassandraKeyPrefix, $wgCassandraWriteConsistency, $wgCassandraColumnFamily; |
35 | | - $this->connect( $cluster ); |
36 | | - $key = 'ES:' . $wgCassandraKeyPrefix . sha1( $data ); |
37 | 35 | |
38 | | - $columnPath = new cassandra_ColumnPath(); |
39 | | - $columnPath->column = 'data'; |
40 | | - $columnPath->super_column = null; |
41 | | - $columnPath->column_family = $wgCassandraColumnFamily; |
| 36 | + try { |
| 37 | + $this->connect( $cluster ); |
| 38 | + $key = $wgCassandraKeyPrefix . sha1( $data ); |
42 | 39 | |
43 | | - $this->client->insert( $this->keyspace, $key, $columnPath, $data, time(), $wgCassandraWriteConsistency ); |
44 | | - return "cassandra://$cluster/$key"; |
| 40 | + $columnPath = new cassandra_ColumnPath(); |
| 41 | + $columnPath->column = 'data'; |
| 42 | + $columnPath->super_column = null; |
| 43 | + $columnPath->column_family = $wgCassandraColumnFamily; |
| 44 | + |
| 45 | + $this->client->insert( $this->keyspace, $key, $columnPath, $data, time(), $wgCassandraWriteConsistency ); |
| 46 | + return "cassandra://$cluster/$key"; |
| 47 | + } catch ( TException $e ) { |
| 48 | + throw new MWCassandraException( $e ); |
| 49 | + } |
45 | 50 | } |
46 | 51 | |
47 | 52 | function fetchFromURL( $url ) { |
48 | 53 | global $wgCassandraReadConsistency, $wgCassandraColumnFamily; |
49 | 54 | |
50 | | - try{ |
| 55 | + try { |
51 | 56 | $this->connect( $url ); |
52 | 57 | $splitted = explode( '/', $url ); |
53 | 58 | $key = end( $splitted ); |
— | — | @@ -61,7 +66,7 @@ |
62 | 67 | $predicate = new cassandra_SlicePredicate(); |
63 | 68 | $predicate->slice_range = $sliceRange; |
64 | 69 | |
65 | | - $result = $this->client->get_slice($this->keyspace, $key, $columnParent, $predicate, $wgCassandraReadConsistency); |
| 70 | + $result = $this->client->get_slice( $this->keyspace, $key, $columnParent, $predicate, $wgCassandraReadConsistency ); |
66 | 71 | |
67 | 72 | return $result[0]->column->value; |
68 | 73 | } catch ( TException $e ) { |
— | — | @@ -72,25 +77,32 @@ |
73 | 78 | } |
74 | 79 | |
75 | 80 | private function connect( $cluster ) { |
76 | | - global $wgThriftPort; |
| 81 | + global $wgCassandraPort; |
77 | 82 | |
78 | 83 | $cluster = str_replace( 'cassandra://', '', $cluster ); |
79 | 84 | list( $host, $this->keyspace ) = explode( '/', $cluster ); |
80 | 85 | |
81 | | - $this->socket = new TSocket( $host, $wgThriftPort); |
82 | | - $this->transport = new TBufferedTransport( $this->socket, 1024, 1024 ); |
83 | | - $this->protocol = new TBinaryProtocolAccelerated( $this->transport ); |
84 | | - $this->client = new CassandraClient( $this->protocol ); |
85 | | - $this->transport->open(); |
| 86 | + try { |
| 87 | + $this->socket = new TSocket( $host, $wgCassandraPort ); |
| 88 | + $this->transport = new TBufferedTransport( $this->socket, 1024, 1024 ); |
| 89 | + $this->protocol = new TBinaryProtocolAccelerated( $this->transport ); |
| 90 | + $this->client = new CassandraClient( $this->protocol ); |
| 91 | + $this->transport->open(); |
| 92 | + } catch ( TException $e ) { |
| 93 | + throw new MWCassandraException( $e ); |
| 94 | + } |
86 | 95 | } |
87 | 96 | } |
88 | 97 | |
| 98 | +/** |
| 99 | + * Wrapper exception for better handling in MW |
| 100 | + */ |
89 | 101 | class MWCassandraException extends MWException { |
90 | 102 | public $innerException; |
91 | 103 | |
92 | 104 | public function __construct( TException $e ) { |
93 | 105 | $this->innerException = $e; |
94 | | - parent::__construct( 'Cassandra error ' . get_class( $e ) . ': ' . $e->__toString() |
| 106 | + parent::__construct( 'Cassandra error ' . get_class( $e ) . ': ' . $e->why |
95 | 107 | . "\n\nStack trace: " . $e->getTraceAsString() |
96 | 108 | ); |
97 | 109 | } |
Index: trunk/extensions/Cassandra/Cassandra.php |
— | — | @@ -10,11 +10,12 @@ |
11 | 11 | 'version' => 0.1, |
12 | 12 | 'author' => 'Max Semenik', |
13 | 13 | 'url' => 'http://www.mediawiki.org/wiki/Extension:Cassandra', |
14 | | - 'description' => 'Allows to store revision text in [http://incubator.apache.org/cassandra/ Apache Cassandra] database.', |
| 14 | + 'description' => 'Allows to store revision text in [http://cassandra.apache.org/ Apache Cassandra] database.', |
15 | 15 | //'descriptionmsg' => 'cassandra-desc', |
16 | 16 | ); |
17 | 17 | |
18 | | -$wgAutoloadClasses['ExternalStoreCassandra'] = dirname( __FILE__ ) . '/Cassandra_body.php'; |
| 18 | +$wgAutoloadClasses['ExternalStoreCassandra'] = $wgAutoloadClasses['MWCassandraException'] |
| 19 | + = dirname( __FILE__ ) . '/Cassandra_body.php'; |
19 | 20 | |
20 | 21 | if ( is_array( $wgExternalStores ) ) { |
21 | 22 | $wgExternalStores[] = 'cassandra'; |
— | — | @@ -26,19 +27,26 @@ |
27 | 28 | * Extension settings |
28 | 29 | */ |
29 | 30 | |
30 | | -// Directory where Thrift for PHP resides. |
| 31 | +// Directory where Thrift bindings for PHP reside |
31 | 32 | $wgThriftRoot = '/usr/share/php/Thrift'; |
32 | | -$wgThriftPort = 9160; |
33 | | -$wgCassandraKeyPrefix = ''; |
34 | 33 | |
| 34 | +// Port used for communicating with Cassandra. Must match <ThriftPort> |
| 35 | +// in Cassandra's storage-conf.xml |
| 36 | +$wgCassandraPort = 9160; |
| 37 | + |
| 38 | +// String prepended to saved key names, can be used to distinct between |
| 39 | +// different wikis, etc. Does not affect the already saved revisions. |
| 40 | +$wgCassandraKeyPrefix = $wgDBname; |
| 41 | + |
35 | 42 | /** |
36 | 43 | * Read and write consistencies, see http://wiki.apache.org/cassandra/API#ConsistencyLevel |
37 | 44 | * for details. |
38 | 45 | * Avoid using cassandra_ConsistencyLevel here to prevent large parts |
39 | 46 | * of Cassandra and Thrift from being loaded on every request. Shouldn't |
40 | | - * matter for real-world setups with byte code cache though. |
| 47 | + * matter much for real-world setups with byte code cache though. |
41 | 48 | */ |
42 | 49 | $wgCassandraReadConsistency = 1; // cassandra_ConsistencyLevel::ONE |
43 | 50 | $wgCassandraWriteConsistency = 1; // cassandra_ConsistencyLevel::ONE |
44 | 51 | |
| 52 | +// Column family to be used for storing data |
45 | 53 | $wgCassandraColumnFamily = 'Standard1'; |
\ No newline at end of file |