From 69a3761be58e81868c2bb511b88e7f9c20af719d Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Fri, 7 Jun 2013 15:07:26 +0200 Subject: [PATCH] Adding notification reset once worker is active Go through all active notifications (active means they are not notified again) and check if their state has changed. If so, mark as inactive and allow for re-notification of the same type and data. --- cronjobs/notifications.php | 34 +++++++++++------ public/include/classes/mail.class.php | 2 +- public/include/classes/notification.class.php | 38 ++++++++++++++++++- public/include/classes/worker.class.php | 21 ++++++++++ 4 files changed, 80 insertions(+), 15 deletions(-) diff --git a/cronjobs/notifications.php b/cronjobs/notifications.php index 7bca08ec..e70d2b07 100755 --- a/cronjobs/notifications.php +++ b/cronjobs/notifications.php @@ -22,21 +22,31 @@ limitations under the License. // Include all settings and classes require_once('shared.inc.php'); +// Find all IDLE workers $aWorkers = $worker->getAllIdleWorkers(); if (empty($aWorkers)) { verbose("No idle workers found\n"); - exit; -} - -foreach ($aWorkers as $aWorker) { - $aData = $aWorker; - $aData['username'] = $user->getUserName($aWorker['account_id']); - $aData['email'] = $user->getUserEmail($aData['username']); - if (!$notification->isNotified($aData)) { - if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) - verbose("Unable to send notification: " . $notification->getError() . "\n"); - } else { - verbose("Already notified for this worker\n"); +} else { + foreach ($aWorkers as $aWorker) { + $aData = $aWorker; + $aData['username'] = $user->getUserName($aWorker['account_id']); + $aData['email'] = $user->getUserEmail($aData['username']); + if (!$notification->isNotified($aData)) { + if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData)) + verbose("Unable to send notification: " . $notification->getError() . "\n"); + } else { + verbose("Already notified for this worker\n"); + } } } +// We notified, lets check which recovered +$aNotifications = $notification->getAllActive(); +foreach ($aNotifications as $aNotification) { + $aData = json_decode($aNotification['data'], true); + $aWorker = $worker->getWorker($aData['id']); + if ($aWorker['active'] == 1) + if (!$notification->setInactive($aNotification['id'])) + verbose("Failed to set notification inactive for " . $aWorker['username'] . "\n"); +} + ?> diff --git a/public/include/classes/mail.class.php b/public/include/classes/mail.class.php index 6c7cc0f1..a1cf2137 100644 --- a/public/include/classes/mail.class.php +++ b/public/include/classes/mail.class.php @@ -20,7 +20,7 @@ class Mail { $this->config = $config; } - private function checkStmt($bState) { + function checkStmt($bState) { $this->debug->append("STA " . __METHOD__, 4); if ($bState ===! true) { $this->debug->append("Failed to prepare statement: " . $this->mysqli->error); diff --git a/public/include/classes/notification.class.php b/public/include/classes/notification.class.php index a9eca1af..9a6dcf3b 100644 --- a/public/include/classes/notification.class.php +++ b/public/include/classes/notification.class.php @@ -7,13 +7,36 @@ if (!defined('SECURITY')) class Notification extends Mail { var $table = 'notifications'; + public function setInactive($id) { + $field = array( + 'name' => 'active', + 'type' => 'i', + 'value' => 0 + ); + return $this->updateSingle($id, $field); + } + + /** + * Update a single row in a table + * @param userID int Account ID + * @param field string Field to update + * @return bool + **/ + private function updateSingle($id, $field) { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare("UPDATE $this->table SET " . $field['name'] . " = ? WHERE id = ? LIMIT 1"); + if ($this->checkStmt($stmt) && $stmt->bind_param($field['type'].'i', $field['value'], $id) && $stmt->execute()) + return true; + $this->debug->append("Unable to update " . $field['name'] . " with " . $field['value'] . " for ID $id"); + return false; + } /** * We check our notification table for existing data * so we can avoid duplicate entries **/ public function isNotified($aData) { $data = json_encode($aData); - $stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? LIMIT 1"); + $stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? AND active = 1 LIMIT 1"); if ($stmt && $stmt->bind_param('s', $data) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows == 1) return true; // Catchall @@ -21,6 +44,17 @@ class Notification extends Mail { return false; } + /** + * Get all active notifications + **/ + public function getAllActive() { + $stmt =$this->mysqli->prepare("SELECT id, data FROM $this->table WHERE active = 1 LIMIT 1"); + if ($stmt && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_all(MYSQLI_ASSOC); + // Catchall + return false; + } + /** * Add a new notification to the table * @param type string Type of the notification @@ -29,7 +63,7 @@ class Notification extends Mail { public function addNotification($type, $data) { // Store notification data as json $data = json_encode($data); - $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data) VALUES (?,?)"); + $stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data, active) VALUES (?,?,1)"); if ($stmt && $stmt->bind_param('ss', $type, $data) && $stmt->execute()) return true; $this->debug->append("Failed to add notification for $type with $data: " . $this->mysqli->error); diff --git a/public/include/classes/worker.class.php b/public/include/classes/worker.class.php index a5052ba9..6a9f6524 100644 --- a/public/include/classes/worker.class.php +++ b/public/include/classes/worker.class.php @@ -78,6 +78,27 @@ class Worker { return false; } + /** + * Fetch a specific worker and its status + * @param id int Worker ID + * @return mixed array Worker details + **/ + public function getWorker($id) { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare(" + SELECT id, username, password, monitor, + ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active, + ( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate + FROM $this->table + WHERE id = ? + "); + if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result()) + return $result->fetch_assoc(); + // Catchall + echo $this->mysqli->error; + return false; + } + /** * Fetch all workers for an account * @param account_id int User ID