Test Failed
Push — trunk ( e02d87...314b8c )
by SuperNova.WS
07:20
created

TaskConditional   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 36
dl 0
loc 138
rs 10
c 1
b 0
f 0
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A updateTaskLastRunTime() 0 4 1
A condition() 0 2 1
A proceedLockExpiration() 0 2 1
A __invoke() 0 30 6
A isTaskAllowed() 0 2 1
A task() 0 2 1
1
<?php
2
/**
3
 * Created by Gorlum 08.02.2020 15:31
4
 */
5
6
namespace Core\Scheduler;
7
8
use DBAL\db_mysql;
9
use Core\GlobalContainer;
10
use classConfig;
11
use SN;
12
13
/**
14
 * Scheduled task is something that need to be done withing certain schedule
15
 * Supports task locks
16
 *
17
 * @package Core
18
 */
19
class TaskConditional {
20
  /**
21
   * @var GlobalContainer $gc
22
   */
23
  protected $gc;
24
  /**
25
   * @var db_mysql
26
   */
27
  protected $db;
28
  /**
29
   * @var classConfig
30
   */
31
  protected $config;
32
33
  /**
34
   * Name of config field to monitor
35
   *
36
   * @var string $configName
37
   */
38
  protected $configName = '';
39
  /**
40
   * Force load config value from DB each check
41
   *
42
   * @var bool $forceConfigLoad
43
   */
44
  protected $forceConfigLoad = true;
45
46
  /**
47
   * Lock for a task
48
   *
49
   * @var null|Lock $lock
50
   */
51
  protected $lock = null;
52
  /**
53
   * Force to process task if lock not lifted but expired
54
   *
55
   * @var bool
56
   */
57
  protected $actionOnExpiredLock = Lock::LOCK_EXPIRED_IGNORE;
58
59
  /**
60
   * TaskConditional constructor.
61
   *
62
   * @param GlobalContainer|null $gc
63
   */
64
  public function __construct($gc = null) {
65
    if (!is_object($gc)) {
66
      $this->gc = SN::$gc;
67
    } else {
68
      $this->gc = $gc;
69
    }
70
    $this->db     = $this->gc->db;
71
    $this->config = $this->gc->config;
72
  }
73
74
  /**
75
   * Invoking task
76
   *
77
   * Checking lock (if applicable) and task interval, getting lock, performing task, releasing lock
78
   *
79
   * @return bool|mixed Return FALSE if task not yet possible to execute or task() result
80
   */
81
  public function __invoke() {
82
    if (!$this->isTaskAllowed()) {
83
      // If no interval specified or no config field specified - nothing to do
84
      return false;
85
    }
86
87
    // Checking task lock
88
    if (is_object($this->lock) && !$this->lock->attemptLock(function () {
89
        return $this->proceedLockExpiration();
90
      }, SN_TIME_NOW)) {
91
92
      return false;
93
    }
94
95
    if ($this->condition()) {
96
      $this->updateTaskLastRunTime(SN_TIME_NOW);
97
      // Performing task
98
      $result = $this->task();
99
100
      $this->updateTaskLastRunTime(time());
101
    } else {
102
      $result = false;
103
    }
104
105
    // Unlocking task if any
106
    if (is_object($this->lock)) {
107
      $this->lock->unLock(true);
108
    }
109
110
    return $result;
111
  }
112
113
  /**
114
   * Fast pre-checks if task allowed at all in current state
115
   *
116
   * @return bool
117
   */
118
  protected function isTaskAllowed() {
119
    return !empty($this->configName);
120
  }
121
122
  /**
123
   * This function called if task have a lock and lock grace period expired
124
   * Here can be added some checks and even recovery procedures for expired lock
125
   *
126
   * @return bool TRUE if task can proceed even on lock expiration time
127
   */
128
  protected function proceedLockExpiration() {
129
    return $this->actionOnExpiredLock;
130
  }
131
132
  /**
133
   * This is primary condition to check
134
   *
135
   * @return bool
136
   */
137
  protected function condition() {
138
    return false;
139
  }
140
141
  /**
142
   * Task to execute
143
   *
144
   * @return bool
145
   */
146
  protected function task() {
147
    return true;
148
  }
149
150
  /**
151
   * @param int $time
152
   */
153
  protected function updateTaskLastRunTime($time) {
154
    $this->db->transactionWrap(
155
      function () use ($time) {
156
        $this->config->dateWrite($this->configName, $time, classConfig::DATE_TYPE_SQL_STRING);
157
      }
158
    );
159
  }
160
161
}
162