MediaWiki master
mcc.php
Go to the documentation of this file.
1<?php
7// @codeCoverageIgnoreStart
8require_once __DIR__ . '/Maintenance.php';
9// @codeCoverageIgnoreEnd
10
13
19class Mcc extends Maintenance {
20 public function __construct() {
21 parent::__construct();
22 $this->addDescription(
23 'MemCached Command (mcc) is an interactive CLI that lets you interact ' .
24 'with the MediaWiki memcached backends.'
25 );
26 $this->addOption( 'cache', 'Cache type to use (a key in $wgObjectCaches)', false, true );
27 $this->addOption( 'debug', 'Set debug mode on the memcached connection' );
28 }
29
30 protected function showHelp() {
31 parent::showHelp();
32 $this->output( "Interactive commands:\n " );
33 $this->output( str_replace( "\n", "\n ", $this->mccGetHelp( false ) ) );
34 $this->output( "\n" );
35 }
36
37 public function execute() {
38 $mcc = new MemcachedClient( [
39 'persistent' => true,
40 'debug' => $this->hasOption( 'debug' ),
41 ] );
42
43 $config = $this->getConfig();
44 $objectCaches = $config->get( MainConfigNames::ObjectCaches );
45 $mainCacheType = $config->get( MainConfigNames::MainCacheType );
46 if ( $this->hasOption( 'cache' ) ) {
47 $cache = $this->getOption( 'cache' );
48 if ( !isset( $objectCaches[$cache] ) ) {
49 $this->fatalError( "MediaWiki isn't configured with a cache named '$cache'" );
50 }
51 $servers = $objectCaches[$cache]['servers'];
52 } elseif ( $mainCacheType === CACHE_MEMCACHED ) {
53 $mcc->set_servers( $config->get( MainConfigNames::MemCachedServers ) );
54 } elseif ( isset( $objectCaches[$mainCacheType]['servers'] ) ) {
55 $mcc->set_servers( $objectCaches[$mainCacheType]['servers'] );
56 } else {
57 $this->fatalError( "MediaWiki isn't configured for Memcached usage" );
58 }
59
60 do {
61 $bad = false;
62 $quit = false;
63
64 $line = self::readconsole();
65 if ( $line === false ) {
66 break;
67 }
68
69 $args = explode( ' ', $line );
70 $command = array_shift( $args );
71
72 // process command
73 switch ( $command ) {
74 case 'help':
75 // show a help message
76 print $this->mccGetHelp( array_shift( $args ) );
77 break;
78
79 case 'get':
80 $sub = '';
81 if ( array_key_exists( 1, $args ) ) {
82 $sub = $args[1];
83 }
84 print "Getting {$args[0]}[$sub]\n";
85 $res = $mcc->get( $args[0] );
86 if ( array_key_exists( 1, $args ) ) {
87 $res = $res[$args[1]];
88 }
89 if ( $res === false ) {
90 # print 'Error: ' . $mcc->error_string() . "\n";
91 print "MemCached error\n";
92 } elseif ( is_string( $res ) ) {
93 print "$res\n";
94 } else {
95 var_dump( $res );
96 }
97 break;
98
99 case 'getsock':
100 $res = $mcc->get( $args[0] );
101 $sock = $mcc->get_sock( $args[0] );
102 var_dump( $sock );
103 break;
104
105 case 'server':
106 if ( $mcc->_single_sock !== null ) {
107 print $mcc->_single_sock . "\n";
108 break;
109 }
110 $res = $mcc->get( $args[0] );
111 $hv = $mcc->_hashfunc( $args[0] );
112 for ( $i = 0; $i < 3; $i++ ) {
113 print $mcc->_buckets[$hv % $mcc->_bucketcount] . "\n";
114 $hv += $mcc->_hashfunc( $i . $args[0] );
115 }
116 break;
117
118 case 'set':
119 $key = array_shift( $args );
120 if ( $args[0] == "#" && is_numeric( $args[1] ) ) {
121 $value = str_repeat( '*', (int)$args[1] );
122 } else {
123 $value = implode( ' ', $args );
124 }
125 if ( !$mcc->set( $key, $value, 0 ) ) {
126 # print 'Error: ' . $mcc->error_string() . "\n";
127 print "MemCached error\n";
128 }
129 break;
130
131 case 'delete':
132 $key = implode( ' ', $args );
133 if ( !$mcc->delete( $key ) ) {
134 # print 'Error: ' . $mcc->error_string() . "\n";
135 print "MemCached error\n";
136 }
137 break;
138
139 case 'history':
140 if ( function_exists( 'readline_list_history' ) ) {
141 foreach ( readline_list_history() as $num => $line ) {
142 print "$num: $line\n";
143 }
144 } else {
145 print "readline_list_history() not available\n";
146 }
147 break;
148
149 case 'dumpmcc':
150 var_dump( $mcc );
151 break;
152
153 case 'quit':
154 case 'exit':
155 $quit = true;
156 break;
157
158 default:
159 $bad = true;
160 }
161
162 if ( $bad ) {
163 if ( $command ) {
164 print "Bad command\n";
165 }
166 } else {
167 if ( function_exists( 'readline_add_history' ) ) {
168 readline_add_history( $line );
169 }
170 }
171 } while ( !$quit );
172 }
173
177 private function mccGetHelp( $command ): string {
178 $output = '';
179 $commandList = [
180 'get' => 'grabs something',
181 'getsock' => 'lists sockets',
182 'set' => 'changes something',
183 'delete' => 'deletes something',
184 'history' => 'show command line history',
185 'server' => 'show current memcached server',
186 'dumpmcc' => 'shows the whole thing',
187 'exit' => 'exit mcc',
188 'quit' => 'exit mcc',
189 'help' => 'help about a command',
190 ];
191 if ( !$command ) {
192 $command = 'fullhelp';
193 }
194 if ( $command === 'fullhelp' ) {
195 $max_cmd_len = max( array_map( 'strlen', array_keys( $commandList ) ) );
196 foreach ( $commandList as $cmd => $desc ) {
197 $output .= sprintf( "%-{$max_cmd_len}s: %s\n", $cmd, $desc );
198 }
199 } elseif ( isset( $commandList[$command] ) ) {
200 $output .= "$command: $commandList[$command]\n";
201 } else {
202 $output .= "$command: command does not exist or no help for it\n";
203 }
204
205 return $output;
206 }
207}
208
209// @codeCoverageIgnoreStart
210$maintClass = Mcc::class;
211require_once RUN_MAINTENANCE_IF_MAIN;
212// @codeCoverageIgnoreEnd
const CACHE_MEMCACHED
Definition Defines.php:75
Diagnostic tool for interacting with memcached.
Definition mcc.php:19
execute()
Do the actual work.
Definition mcc.php:37
__construct()
Default constructor.
Definition mcc.php:20
showHelp()
Definitely show the help.
Definition mcc.php:30
A class containing constants representing the names of configuration variables.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
output( $out, $channel=null)
Throw some output to the user.
static readconsole( $prompt='> ')
Prompt the console for input.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
hasOption( $name)
Checks to see if a particular option was set.
getOption( $name, $default=null)
Get an option, or return the default.
addDescription( $text)
Set the description text.
memcached client class implemented using (p)fsockopen()
$maintClass
Definition mcc.php:210