Poller.php 5.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
<?php /** @file */

namespace Zotlabs\Daemon;

class Poller {

	static public function run($argc,$argv) {

		$maxsysload = intval(get_config('system','maxloadavg'));
		if($maxsysload < 1)
			$maxsysload = 50;
		if(function_exists('sys_getloadavg')) {
			$load = sys_getloadavg();
			if(intval($load[0]) > $maxsysload) {
				logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
				return;
			}
		}

		$interval = intval(get_config('system','poll_interval'));
		if(! $interval) 
			$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));

		// Check for a lockfile.  If it exists, but is over an hour old, it's stale.  Ignore it.
		$lockfile = 'store/[data]/poller';
		if((file_exists($lockfile)) && (filemtime($lockfile) > (time() - 3600)) 
			&& (! get_config('system','override_poll_lockfile'))) {
			logger("poller: Already running");
			return;
		}
	
		// Create a lockfile.  Needs two vars, but $x doesn't need to contain anything.
		file_put_contents($lockfile, $x);

		logger('poller: start');
	
		$manual_id  = 0;
		$generation = 0;

		$force      = false;
		$restart    = false;

		if(($argc > 1) && ($argv[1] == 'force'))
			$force = true;

		if(($argc > 1) && ($argv[1] == 'restart')) {
			$restart = true;
			$generation = intval($argv[2]);
			if(! $generation)
				killme();		
		}

		if(($argc > 1) && intval($argv[1])) {
			$manual_id = intval($argv[1]);
			$force     = true;
		}


		$sql_extra = (($manual_id) ? " AND abook_id = " . intval($manual_id) . " " : "");

		reload_plugins();

		$d = datetime_convert();

		// Only poll from those with suitable relationships

		$abandon_sql = (($abandon_days) 
			? sprintf(" AND account_lastlog > %s - INTERVAL %s ", db_utcnow(), db_quoteinterval(intval($abandon_days).' DAY')) 
			: '' 
		);

		$randfunc = db_getfunc('RAND');
	
74 75 76 77 78 79
		$contacts = q("SELECT abook.abook_updated, abook.abook_connected, abook.abook_feed,
			abook.abook_channel, abook.abook_id, abook.abook_archived, abook.abook_pending,
			abook.abook_ignored, abook.abook_blocked,
			xchan.xchan_network,
			account.account_lastlog, account.account_flags 
			FROM abook LEFT JOIN xchan on abook_xchan = xchan_hash 
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
			LEFT JOIN account on abook_account = account_id
			where abook_self = 0
			$sql_extra 
			AND (( account_flags = %d ) OR ( account_flags = %d )) $abandon_sql ORDER BY $randfunc",
			intval(ACCOUNT_OK),
			intval(ACCOUNT_UNVERIFIED)     // FIXME
		);

		if($contacts) {

			foreach($contacts as $contact) {

				$update  = false;

				$t = $contact['abook_updated'];
				$c = $contact['abook_connected'];

				if(intval($contact['abook_feed'])) {
					$min = service_class_fetch($contact['abook_channel'],'minimum_feedcheck_minutes');
					if(! $min)
						$min = intval(get_config('system','minimum_feedcheck_minutes'));
					if(! $min)
						$min = 60;
					$x = datetime_convert('UTC','UTC',"now - $min minutes");
					if($c < $x) {
105
						Master::Summon(array('Onepoll',$contact['abook_id']));
106 107 108 109 110 111 112
						if($interval)
							@time_sleep_until(microtime(true) + (float) $interval);
					}
					continue;
				}


Zot's avatar
Zot committed
113
				if(! in_array($contact['xchan_network'],['zot','zot6']))
114 115 116 117 118 119 120 121 122 123
					continue;

				if($c == $t) {
					if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
						$update = true;
				}
				else {
	
					// if we've never connected with them, start the mark for death countdown from now
	
Zot's avatar
Zot committed
124
					if($c <= NULL_DATE) {
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
						$r = q("update abook set abook_connected = '%s'  where abook_id = %d",
							dbesc(datetime_convert()),
							intval($contact['abook_id'])
						);
						$c = datetime_convert();
						$update = true;
					}

					// He's dead, Jim

					if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 30 day")) > 0) {	
						$r = q("update abook set abook_archived = 1 where abook_id = %d",
							intval($contact['abook_id'])
						);
						$update = false;
						continue;
					}

					if(intval($contact['abook_archived'])) {
						$update = false;
						continue;
					}

					// might be dead, so maybe don't poll quite so often
	
					// recently deceased, so keep up the regular schedule for 3 days
 
					if((strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $c . " + 3 day")) > 0)
					 && (strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 1 day")) > 0))
						$update = true;

					// After that back off and put them on a morphine drip

					if(strcmp(datetime_convert('UTC','UTC', 'now'),datetime_convert('UTC','UTC', $t . " + 2 day")) > 0) {	
						$update = true;
					}

				}

				if(intval($contact['abook_pending']) || intval($contact['abook_archived']) || intval($contact['abook_ignored']) || intval($contact['abook_blocked']))
					continue;

				if((! $update) && (! $force))
						continue;

170
				Master::Summon(array('Onepoll',$contact['abook_id']));
171 172 173 174 175 176 177
				if($interval)
					@time_sleep_until(microtime(true) + (float) $interval);

			}
		}

		if($dirmode == DIRECTORY_MODE_SECONDARY || $dirmode == DIRECTORY_MODE_PRIMARY) {
Zot's avatar
Zot committed
178
			$r = q("SELECT u.ud_addr, u.ud_id, u.ud_last FROM updates AS u INNER JOIN (SELECT ud_addr, max(ud_id) AS ud_id FROM updates WHERE ( ud_flags & %d ) = 0 AND ud_addr != '' AND ( ud_last <= '%s' OR ud_last > %s - INTERVAL %s ) GROUP BY ud_addr) AS s ON s.ud_id = u.ud_id ",
179 180 181 182 183 184 185 186 187 188
				intval(UPDATE_FLAGS_UPDATED),
				dbesc(NULL_DATE),
				db_utcnow(), db_quoteinterval('7 DAY')
			);
			if($r) {
				foreach($r as $rr) {

					// If they didn't respond when we attempted before, back off to once a day
					// After 7 days we won't bother anymore

Zot's avatar
Zot committed
189
					if($rr['ud_last'] > NULL_DATE)
190 191
						if($rr['ud_last'] > datetime_convert('UTC','UTC', 'now - 1 day'))
							continue;
192
					Master::Summon(array('Onedirsync',$rr['ud_id']));
193 194 195 196 197 198 199 200 201
					if($interval)
						@time_sleep_until(microtime(true) + (float) $interval);
				}
			}
		}	

		set_config('system','lastpoll',datetime_convert());

		//All done - clear the lockfile	
202

203 204 205 206 207
		@unlink($lockfile);

		return;
	}
}