]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/queuemanager.php
Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 0.9.x
[quix0rs-gnu-social.git] / lib / queuemanager.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * Abstract class for i/o managers
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  QueueManager
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @author    Sarven Capadisli <csarven@status.net>
26  * @author    Brion Vibber <brion@status.net>
27  * @copyright 2009-2010 StatusNet, Inc.
28  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
29  * @link      http://status.net/
30  */
31
32 /**
33  * Completed child classes must implement the enqueue() method.
34  *
35  * For background processing, classes should implement either socket-based
36  * input (handleInput(), getSockets()) or idle-loop polling (idle()).
37  */
38 abstract class QueueManager extends IoManager
39 {
40     static $qm = null;
41
42     /**
43      * Factory function to pull the appropriate QueueManager object
44      * for this site's configuration. It can then be used to queue
45      * events for later processing or to spawn a processing loop.
46      *
47      * Plugins can add to the built-in types by hooking StartNewQueueManager.
48      *
49      * @return QueueManager
50      */
51     public static function get()
52     {
53         if (empty(self::$qm)) {
54
55             if (Event::handle('StartNewQueueManager', array(&self::$qm))) {
56
57                 $enabled = common_config('queue', 'enabled');
58                 $type = common_config('queue', 'subsystem');
59
60                 if (!$enabled) {
61                     // does everything immediately
62                     self::$qm = new UnQueueManager();
63                 } else {
64                     switch ($type) {
65                      case 'db':
66                         self::$qm = new DBQueueManager();
67                         break;
68                      case 'stomp':
69                         self::$qm = new StompQueueManager();
70                         break;
71                      default:
72                         throw new ServerException("No queue manager class for type '$type'");
73                     }
74                 }
75             }
76         }
77
78         return self::$qm;
79     }
80
81     /**
82      * @fixme wouldn't necessarily work with other class types.
83      * Better to change the interface...?
84      */
85     public static function multiSite()
86     {
87         if (common_config('queue', 'subsystem') == 'stomp') {
88             return IoManager::INSTANCE_PER_PROCESS;
89         } else {
90             return IoManager::SINGLE_ONLY;
91         }
92     }
93
94     function __construct()
95     {
96         $this->initialize();
97     }
98
99     /**
100      * Store an object (usually/always a Notice) into the given queue
101      * for later processing. No guarantee is made on when it will be
102      * processed; it could be immediately or at some unspecified point
103      * in the future.
104      *
105      * Must be implemented by any queue manager.
106      *
107      * @param Notice $object
108      * @param string $queue
109      */
110     abstract function enqueue($object, $queue);
111
112     /**
113      * Instantiate the appropriate QueueHandler class for the given queue.
114      *
115      * @param string $queue
116      * @return mixed QueueHandler or null
117      */
118     function getHandler($queue)
119     {
120         if (isset($this->handlers[$queue])) {
121             $class = $this->handlers[$queue];
122             if (class_exists($class)) {
123                 return new $class();
124             } else {
125                 common_log(LOG_ERR, "Nonexistent handler class '$class' for queue '$queue'");
126             }
127         } else {
128             common_log(LOG_ERR, "Requested handler for unkown queue '$queue'");
129         }
130         return null;
131     }
132
133     /**
134      * Get a list of all registered queue transport names.
135      *
136      * @return array of strings
137      */
138     function getQueues()
139     {
140         return array_keys($this->handlers);
141     }
142
143     /**
144      * Initialize the list of queue handlers
145      *
146      * @event StartInitializeQueueManager
147      * @event EndInitializeQueueManager
148      */
149     function initialize()
150     {
151         if (Event::handle('StartInitializeQueueManager', array($this))) {
152             $this->connect('plugin', 'PluginQueueHandler');
153             $this->connect('omb', 'OmbQueueHandler');
154             $this->connect('ping', 'PingQueueHandler');
155             if (common_config('sms', 'enabled')) {
156                 $this->connect('sms', 'SmsQueueHandler');
157             }
158
159             // XMPP output handlers...
160             if (common_config('xmpp', 'enabled')) {
161                 $this->connect('jabber', 'JabberQueueHandler');
162                 $this->connect('public', 'PublicQueueHandler');
163                 
164                 // @fixme this should move up a level or should get an actual queue
165                 $this->connect('confirm', 'XmppConfirmHandler');
166             }
167
168             // For compat with old plugins not registering their own handlers.
169             $this->connect('plugin', 'PluginQueueHandler');
170         }
171         Event::handle('EndInitializeQueueManager', array($this));
172     }
173
174     /**
175      * Register a queue transport name and handler class for your plugin.
176      * Only registered transports will be reliably picked up!
177      *
178      * @param string $transport
179      * @param string $class
180      */
181     public function connect($transport, $class)
182     {
183         $this->handlers[$transport] = $class;
184     }
185
186     /**
187      * Send a statistic ping to the queue monitoring system,
188      * optionally with a per-queue id.
189      *
190      * @param string $key
191      * @param string $queue
192      */
193     function stats($key, $queue=false)
194     {
195         $owners = array();
196         if ($queue) {
197             $owners[] = "queue:$queue";
198             $owners[] = "site:" . common_config('site', 'server');
199         }
200         if (isset($this->master)) {
201             $this->master->stats($key, $owners);
202         } else {
203             $monitor = new QueueMonitor();
204             $monitor->stats($key, $owners);
205         }
206     }
207 }