All Data Structures Functions Variables Pages
MonitorJob.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
40  class MonitorJob extends BaseJob
41  {
42  protected static $pageSize = 50;
43 
44  protected static $stuckNotificationThreshold = 4;
45 
49  public static function getDisplayName()
50  {
51  return Zurmo::t('JobsManagerModule', 'Monitor Job');
52  }
53 
57  public static function getType()
58  {
59  return 'Monitor';
60  }
61 
62  public static function getRecommendedRunFrequencyContent()
63  {
64  return Zurmo::t('JobsManagerModule', 'Every 5 minutes');
65  }
66 
70  public static function getStuckStringContent()
71  {
72  return Zurmo::t('JobsManagerModule', 'The monitor job is stuck.');
73  }
74 
75  public static function getRunTimeThresholdInSeconds()
76  {
77  return 60;
78  }
79 
80  public function run()
81  {
82  $jobsInProcess = static::getNonMonitorJobsInProcessModels();
83  $jobsAreStuck = false;
84  $jobTitleLabels = array();
85  $jobsInProcessToReset = array();
86  foreach ($jobsInProcess as $jobInProcess)
87  {
88  if (JobsManagerUtil::isJobInProcessOverThreshold($jobInProcess, $jobInProcess->type))
89  {
90  $stuckJob = StuckJob::getByType($jobInProcess->type);
91  $stuckJob->quantity = $stuckJob->quantity + 1;
92  if (!$stuckJob->save())
93  {
94  throw new FailedToSaveModelException();
95  }
96  $jobsInProcessToReset[] = $jobInProcess;
97  //Only processes once the threshold is reach, not each time after that
98  if ($stuckJob->quantity == static::$stuckNotificationThreshold)
99  {
100  $jobTitleLabels[] = strval($jobInProcess);
101  $jobsAreStuck = true;
102  }
103  }
104  }
105  if ($jobsAreStuck)
106  {
107  self::makeJobStuckNotification($jobTitleLabels);
108  }
109  foreach ($jobsInProcessToReset as $jobInProcessToReset)
110  {
111  $jobInProcessToReset->delete();
112  }
113  $jobLogs = static::getNonMonitorJobLogsUnprocessedWithErrors();
114  foreach ($jobLogs as $jobLog)
115  {
116  $message = new NotificationMessage();
117  $commonMessage = Zurmo::t('JobsManagerModule', 'Job completed with errors.');
118  $message->htmlContent = $commonMessage;
119  $url = Yii::app()->createAbsoluteUrl('jobsManager/default/jobLogDetails/',
120  array('id' => $jobLog->id));
121  $message->htmlContent .= "<br/>" . ZurmoHtml::link(Zurmo::t('Core', 'Click Here'), $url,
122  array('target' => '_blank'));
123  $message->textContent = $commonMessage;
124  $message->textContent .= "\n". Zurmo::t('JobsManagerModule', 'See the job log details in this link: {url}',
125  array('{url}' => ShortUrlUtil::createShortUrl($url)));
127  NotificationsUtil::submit($message, $rules);
128  $jobLog->isProcessed = true;
129  $jobLog->save();
130  }
132  return true;
133  }
134 
135  protected static function getNonMonitorJobsInProcessModels()
136  {
137  $searchAttributeData = array();
138  $searchAttributeData['clauses'] = array(
139  1 => array(
140  'attributeName' => 'type',
141  'operatorType' => 'doesNotEqual',
142  'value' => 'Monitor',
143  ),
144  );
145  $searchAttributeData['structure'] = '1';
146  $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('JobInProcess');
147  $where = RedBeanModelDataProvider::makeWhere('JobInProcess', $searchAttributeData, $joinTablesAdapter);
148  return JobInProcess::getSubset($joinTablesAdapter, null, null, $where, null);
149  }
150 
151  protected static function getNonMonitorJobLogsUnprocessedWithErrors()
152  {
153  $searchAttributeData = array();
154  $searchAttributeData['clauses'] = array(
155  1 => array(
156  'attributeName' => 'type',
157  'operatorType' => 'doesNotEqual',
158  'value' => 'Monitor',
159  ),
160  2 => array(
161  'attributeName' => 'isProcessed',
162  'operatorType' => 'doesNotEqual',
163  'value' => (bool)1,
164  ),
165  3 => array(
166  'attributeName' => 'status',
167  'operatorType' => 'equals',
168  'value' => JobLog::STATUS_COMPLETE_WITH_ERROR,
169  ),
170  );
171  $searchAttributeData['structure'] = '1 and 2 and 3';
172  $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('JobLog');
173  $where = RedBeanModelDataProvider::makeWhere('JobLog', $searchAttributeData, $joinTablesAdapter);
174  return JobLog::getSubset($joinTablesAdapter, null, self::$pageSize, $where, null);
175  }
176 
180  protected static function updateUnprocessedJobLogsWithoutErrors()
181  {
182  $sql = 'update joblog set isprocessed = 1 where joblog.isprocessed = 0';
183  ZurmoRedBean::exec($sql);
184  }
185 
189  public static function makeJobStuckNotification(array $jobTitleLabels)
190  {
191  $message = new NotificationMessage();
192  $prefixContent = Zurmo::t('JobsManagerModule', 'Stuck Job| Stuck Jobs', array(count($jobTitleLabels)));
193  $url = Yii::app()->createAbsoluteUrl('jobsManager/default/list/');
194  $message->textContent = $prefixContent;
195  $message->htmlContent = $prefixContent;
196  $textContent = null;
197  $htmlContent = null;
198  foreach ($jobTitleLabels as $label)
199  {
200  if ($textContent != null)
201  {
202  $textContent .= ', ';
203  }
204  if ($htmlContent != null)
205  {
206  $htmlContent .= ', ';
207  }
208  $textContent .= $label;
209  $htmlContent .= $label;
210  }
211  $message->textContent .= ': ' . $textContent;
212  $message->htmlContent .= ': ' . $htmlContent;
213  $message->textContent .= "\n" . Zurmo::t('Core', 'View Job Manager') . ': ' . ShortUrlUtil::createShortUrl($url);
214  $message->htmlContent .= "<br/>" . ZurmoHtml::link(Zurmo::t('Core', 'View Job Manager'), $url,
215  array('target' => '_blank'));
216  $rules = new StuckJobsNotificationRules();
217  NotificationsUtil::submit($message, $rules);
218  }
219  }
220 ?>
static getDisplayName()
Definition: MonitorJob.php:49
static updateUnprocessedJobLogsWithoutErrors()
Definition: MonitorJob.php:180
static makeJobStuckNotification(array $jobTitleLabels)
Definition: MonitorJob.php:189
static getByType($type)
Definition: StuckJob.php:49
static getStuckStringContent()
Definition: MonitorJob.php:70
static makeWhere($modelClassName, array $metadata, &$joinTablesAdapter)
static getSubset(RedBeanModelJoinTablesQueryAdapter $joinTablesAdapter=null, $offset=null, $count=null, $where=null, $orderBy=null, $modelClassName=null, $selectDistinct=false)
static isJobInProcessOverThreshold(JobInProcess $jobInProcess, $type)
static submit(NotificationMessage $message, NotificationRules $rules)
static getType()
Definition: MonitorJob.php:57
Generated on Sat Mar 28 2020 07:10:42