3 * Table Definition for core_notify_server
5 class_exists('DB_DataObject') ? '' : require_once 'DB/DataObject.php';
7 class Pman_Core_DataObjects_Core_notify_server extends DB_DataObject
10 /* the code below is auto generated do not remove the above tag */
12 public $__table = 'core_notify_server'; // table name
13 public $id; // int(11) not_null primary_key auto_increment
22 function applyFilters($q, $au, $roo)
24 if (isset($q['_with_queue_size'])) {
25 $this->addQueueSize();
30 function addQueueSize()
32 // look for database links for server_id (which should find core_notify + others..)
33 $cn = get_class(DB_DataObject::factory('core_notify'));
35 foreach($this->databaseLinks() as $tbl => $kv) {
36 foreach($kv as $k=>$v) {
37 if ($v != 'core_notify_server:id') {
41 $test = DB_DAtaObject::factory($tbl);
42 if (!is_a($test, $cn)) {
49 die("OOPS - no tables for notify_server references");
52 foreach($tables as $t) {
59 server_id = core_notify_server.id
61 sent < '1970-01-01' OR sent IS NULL
67 $this->selectAdd("(" . implode(" + ", $totals) . ") as in_queue ");
76 // most services should call this first..
78 function getCurrent($notify, $force = false)
80 static $current = false;;
82 if ($current !== false) {
86 $ns = DB_DataObject::factory('core_notify_server');
93 $ns->poolname = $notify->poolname;
95 $ns->hostname = gethostname();
97 if ($ns->find(true)) {
102 $notify->jerr("Server not found for this server " . gethostname() . " in core_notify_server" );
104 // fallback to any server - if we are using force. (this is so helo will work...)
106 $ns = DB_DataObject::factory('core_notify_server');
108 $ns->hostname = gethostname();
109 if (!$ns->find(true)) {
110 $notify->jerr("Server not found for this server " . gethostname() . " in core_notify_server" );
117 function isFirstServer()
123 $servers = $this->availableServers();
124 if (empty($servers)) {
127 // only run this on the first server...
128 return $this->id == $servers[0]->id;
132 // called on current server.
133 function assignQueues($notify)
139 $servers = $this->availableServers();
142 foreach($servers as $s) {
148 $notify->jerr("no configured servers in core_notify_server for poolname = {$notify->poolname}");
152 // only run this on the first server...
153 if ($this->id != $ids[0]) {
156 foreach($ids as $rn) {
160 $num_servers = count($ids);
162 if ($num_servers == 1) {
163 $p = DB_DataObject::factory($notify->table);
168 server_id = {$ids[0]}
174 act_start < NOW() + INTERVAL 3 HOUR
176 server_id != {$ids[0]}
183 $p = DB_DataObject::factory($notify->table);
189 act_start < NOW() + INTERVAL 3 HOUR
191 server_id NOT IN (" . implode(",", $ids) . ")
193 $p->orderBy('act_when asc'); //?
194 $total_add = $p->count();
195 if ($total_add < 1) {
199 $to_add = $p->fetchAll('id');
201 $p = DB_DataObject::factory($notify->table);
208 server_id IN (" . implode(",", $ids) . ")
211 $p->selectAdd('server_id, count(id) as n');
212 $p->groupBy('server_id');
213 $in_q = $p->fetchAll('server_id', 'n');
215 // if queue is empty it will not get allocated anything.
216 foreach($ids as $sid) {
217 if (!isset($in_q[$sid])) {
222 foreach($in_q as $sid => $n) {
228 $target_len = floor( ($totalq + $total_add) / $num_servers );
230 foreach($in_q as $sid => $cq) {
231 if ( $cq > $target_len) {
234 $up[ $sid ] = array_slice($to_add, 0, $target_len - $cq);
237 // add the reminder evently
238 foreach($to_add as $n=>$i) {
240 $up[ $ids[$n % $num_servers] ][] = $i;
243 // distribution needs to go to ones that have the shortest queues. - so to balance out the queues
247 foreach($up as $sid => $nids) {
251 $p = DB_DataObject::factory($notify->table);
258 id IN (". implode(',', $nids). ')'
262 DB_DataObject::factory("core_notify_blacklist")->prune();
265 // called on current server.
267 function availableServers()
269 $ns = DB_DataObject::factory('core_notify_server');
270 $ns->poolname = $this->poolname;
272 $ns->orderBy('id ASC');
273 return $ns->fetchAll();
277 function updateNotifyToNextServer( $cn , $when = false, $allow_same = false)
283 // fixme - this should take into account blacklisted - and return false if no more servers are available
284 $email = empty($cn->to_email) ? ($cn->person() ? $cn->person()->email : $cn->to_email) : $cn->to_email;
286 $w = DB_DataObject::factory($cn->tableName());
289 $servers = $this->availableServers();
291 foreach($servers as $i => $s) {
292 if ($s->id == $this->id) {
297 $offset = ($start + 1) % count($servers);
299 while ($offset != $start) {
300 $s = $servers[$offset];
301 if (!$s->isBlacklisted($email)) {
305 $offset = ($offset + 1) % count($servers);
308 if ($good == false && $allow_same) {
312 if ($good == false) {
319 $w->server_id = $good->id;
320 $w->act_when = $when === false ? $w->sqlValue('NOW() + INTERVAL 1 MINUTE') : $when;
326 function isBlacklisted($email)
332 // return current server id..
333 static $cache = array();
335 $ea = explode('@',$email);
336 $dom = strtolower(array_pop($ea));
337 if (isset( $cache[$this->id . '-'. $dom])) {
338 return $cache[$this->id . '-'. $dom];
341 $cd = DB_DataObject::factory('core_domain')->loadOrCreate($dom);
343 $bl = DB_DataObject::factory('core_notify_blacklist');
344 $bl->server_id = $this->id;
345 $bl->domain_id = $cd->id;
347 $cache[$this->id . '-'. $dom] = true;
358 $ff = HTML_FlexyFramework::get();
359 $ff->Mail['helo'] = $this->helo;
362 function checkSmtpResponse($errmsg, $core_domain)
367 $bl = DB_DataObject::factory('core_notify_blacklist');
368 $bl->server_id = $this->id;
369 $bl->domain_id = $core_domain->id;
373 // is it a blacklist message
374 if (!$bl->messageIsBlacklisted($errmsg)) {
377 $bl->error_str = $errmsg;
378 $bl->added_dt = $bl->sqlValue("NOW()");