]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/queuehandler.php
cd43b1e09a77916a80452adf101349c65fbabeec
[quix0rs-gnu-social.git] / lib / queuehandler.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2008, 2009, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
21
22 require_once(INSTALLDIR.'/lib/daemon.php');
23 require_once(INSTALLDIR.'/classes/Queue_item.php');
24 require_once(INSTALLDIR.'/classes/Notice.php');
25
26 define('CLAIM_TIMEOUT', 1200);
27 define('QUEUE_HANDLER_MISS_IDLE', 10);
28 define('QUEUE_HANDLER_HIT_IDLE', 0);
29
30 /**
31  * Base class for queue handlers.
32  *
33  * As extensions of the Daemon class, each queue handler has the ability
34  * to launch itself in the background, at which point it'll pass control
35  * to the configured QueueManager class to poll for updates.
36  *
37  * Subclasses must override at least the following methods:
38  * - transport
39  * - start
40  * - finish
41  * - handle_notice
42  *
43  * Some subclasses will also want to override the idle handler:
44  * - idle
45  */
46 class QueueHandler extends Daemon
47 {
48
49     function __construct($id=null, $daemonize=true)
50     {
51         parent::__construct($daemonize);
52
53         if ($id) {
54             $this->set_id($id);
55         }
56     }
57
58     /**
59      * How many seconds a polling-based queue manager should wait between
60      * checks for new items to handle.
61      *
62      * Defaults to 60 seconds; override to speed up or slow down.
63      *
64      * @return int timeout in seconds
65      */
66     function timeout()
67     {
68         return 60;
69     }
70
71     function class_name()
72     {
73         return ucfirst($this->transport()) . 'Handler';
74     }
75
76     function name()
77     {
78         return strtolower($this->class_name().'.'.$this->get_id());
79     }
80
81     /**
82      * Return transport keyword which identifies items this queue handler
83      * services; must be defined for all subclasses.
84      *
85      * Must be 8 characters or less to fit in the queue_item database.
86      * ex "email", "jabber", "sms", "irc", ...
87      *
88      * @return string
89      */
90     function transport()
91     {
92         return null;
93     }
94
95     /**
96      * Initialization, run when the queue handler starts.
97      * If this function indicates failure, the handler run will be aborted.
98      *
99      * @fixme run() will abort if this doesn't return true,
100      *        but some subclasses don't bother.
101      * @return boolean true on success, false on failure
102      */
103     function start()
104     {
105     }
106
107     /**
108      * Cleanup, run when the queue handler ends.
109      * If this function indicates failure, a warning will be logged.
110      *
111      * @fixme run() will throw warnings if this doesn't return true,
112      *        but many subclasses don't bother.
113      * @return boolean true on success, false on failure
114      */
115     function finish()
116     {
117     }
118
119     /**
120      * Here's the meat of your queue handler -- you're handed a Notice
121      * object, which you may do as you will with.
122      *
123      * If this function indicates failure, a warning will be logged
124      * and the item is placed back in the queue to be re-run.
125      *
126      * @param Notice $notice
127      * @return boolean true on success, false on failure
128      */
129     function handle_notice($notice)
130     {
131         return true;
132     }
133
134     /**
135      * Setup and start of run loop for this queue handler as a daemon.
136      * Most of the heavy lifting is passed on to the QueueManager's service()
137      * method, which passes control back to our handle_notice() method for
138      * each notice that comes in on the queue.
139      *
140      * Most of the time this won't need to be overridden in a subclass.
141      *
142      * @return boolean true on success, false on failure
143      */
144     function run()
145     {
146         if (!$this->start()) {
147             $this->log(LOG_WARNING, 'failed to start');
148             return false;
149         }
150
151         $this->log(LOG_INFO, 'checking for queued notices');
152
153         $queue   = $this->transport();
154         $timeout = $this->timeout();
155
156         $qm = QueueManager::get();
157
158         $qm->service($queue, $this);
159
160         $this->log(LOG_INFO, 'finished servicing the queue');
161
162         if (!$this->finish()) {
163             $this->log(LOG_WARNING, 'failed to clean up');
164             return false;
165         }
166
167         $this->log(LOG_INFO, 'terminating normally');
168
169         return true;
170     }
171
172     /**
173      * Called by QueueHandler after each handled item or empty polling cycle.
174      * This is a good time to e.g. service your XMPP connection.
175      *
176      * Doesn't need to be overridden if there's no maintenance to do.
177      *
178      * @param int $timeout seconds to sleep if there's nothing to do
179      */
180     function idle($timeout=0)
181     {
182         if ($timeout > 0) {
183             sleep($timeout);
184         }
185     }
186
187     function log($level, $msg)
188     {
189         common_log($level, $this->class_name() . ' ('. $this->get_id() .'): '.$msg);
190     }
191
192     function getSockets()
193     {
194         return array();
195     }
196 }
197