Passed
Push — master ( 30bcbc...eba4fe )
by Siad
06:53
created

WaitForTask   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Test Coverage

Coverage 77.19%

Importance

Changes 0
Metric Value
eloc 53
dl 0
loc 161
ccs 44
cts 57
cp 0.7719
rs 10
c 0
b 0
f 0
wmc 21

10 Methods

Rating   Name   Duplication   Size   Complexity  
A setMaxWaitUnit() 0 3 1
A setTimeoutProperty() 0 3 1
A setCheckEveryUnit() 0 3 1
A main() 0 29 5
A setMaxWait() 0 3 1
A setCheckEvery() 0 3 1
A __construct() 0 3 1
A processTimeout() 0 6 2
A processSuccess() 0 3 1
B _convertUnit() 0 27 7
1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 */
19
20
/**
21
 *  Based on Apache Ant Wait For:
22
 *
23
 *  Licensed to the Apache Software Foundation (ASF) under one or more
24
 *  contributor license agreements.  See the NOTICE file distributed with
25
 *  this work for additional information regarding copyright ownership.
26
 *  The ASF licenses this file to You under the Apache License, Version 2.0
27
 *  (the "License"); you may not use this file except in compliance with
28
 *  the License.  You may obtain a copy of the License at
29
 *
30
 *      http://www.apache.org/licenses/LICENSE-2.0
31
 *
32
 *  Unless required by applicable law or agreed to in writing, software
33
 *  distributed under the License is distributed on an "AS IS" BASIS,
34
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35
 *  See the License for the specific language governing permissions and
36
 *  limitations under the License.
37
 *
38
 * @author  Michiel Rook <[email protected]>
39
 * @package phing.tasks.system
40
 */
41
class WaitForTask extends ConditionBase
42
{
43
    const ONE_MILLISECOND = 1;
44
    const ONE_SECOND = 1000;
45
    const ONE_MINUTE = 60000;
46
    const ONE_HOUR = 3600000;
47
    const ONE_DAY = 86400000;
48
    const ONE_WEEK = 604800000;
49
50
    const DEFAULT_MAX_WAIT_MILLIS = 180000;
51
    const DEFAULT_CHECK_MILLIS = 500;
52
53
    protected $maxWait = self::DEFAULT_MAX_WAIT_MILLIS;
54
    protected $maxWaitMultiplier = self::ONE_MILLISECOND;
55
56
    protected $checkEvery = self::DEFAULT_CHECK_MILLIS;
57
    protected $checkEveryMultiplier = self::ONE_MILLISECOND;
58
59
    protected $timeoutProperty = null;
60
61 5
    public function __construct($taskName = 'waitfor')
62
    {
63 5
        parent::__construct($taskName);
64 5
    }
65
66
    /**
67
     * Set the maximum length of time to wait.
68
     *
69
     * @param int $maxWait
70
     */
71 5
    public function setMaxWait($maxWait)
72
    {
73 5
        $this->maxWait = (int) $maxWait;
74 5
    }
75
76
    /**
77
     * Set the max wait time unit
78
     *
79
     * @param string $maxWaitUnit
80
     */
81 5
    public function setMaxWaitUnit($maxWaitUnit)
82
    {
83 5
        $this->maxWaitMultiplier = $this->_convertUnit($maxWaitUnit);
84 5
    }
85
86
    /**
87
     * Convert the unit to a multipler.
88
     *
89
     * @param  string $unit
90
     * @throws BuildException
91
     * @return int
92
     */
93 5
    protected function _convertUnit($unit)
94
    {
95 5
        if ($unit === 'week') {
96
            return self::ONE_WEEK;
97
        }
98
99 5
        if ($unit === 'day') {
100
            return self::ONE_DAY;
101
        }
102
103 5
        if ($unit === 'hour') {
104
            return self::ONE_HOUR;
105
        }
106
107 5
        if ($unit === 'minute') {
108
            return self::ONE_MINUTE;
109
        }
110
111 5
        if ($unit === 'second') {
112 4
            return self::ONE_SECOND;
113
        }
114
115 1
        if ($unit === 'millisecond') {
116 1
            return self::ONE_MILLISECOND;
117
        }
118
119
        throw new BuildException("Illegal unit '$unit'");
120
    }
121
122
    /**
123
     * Set the time between each check
124
     *
125
     * @param int $checkEvery
126
     */
127
    public function setCheckEvery($checkEvery)
128
    {
129
        $this->checkEvery = (int) $checkEvery;
130
    }
131
132
    /**
133
     * Set the check every time unit
134
     *
135
     * @param  string $checkEveryUnit
136
     * @return void
137
     */
138
    public function setCheckEveryUnit($checkEveryUnit)
139
    {
140
        $this->checkEveryMultiplier = $this->_convertUnit($checkEveryUnit);
141
    }
142
143
    /**
144
     * Name of the property to set after a timeout.
145
     *
146
     * @param  string $timeoutProperty
147
     * @return void
148
     */
149 3
    public function setTimeoutProperty($timeoutProperty)
150
    {
151 3
        $this->timeoutProperty = $timeoutProperty;
152 3
    }
153
154
    /**
155
     * Check repeatedly for the specified conditions until they become
156
     * true or the timeout expires.
157
     *
158
     * @throws BuildException
159
     */
160 5
    public function main()
161
    {
162 5
        if ($this->countConditions() > 1) {
163
            throw new BuildException("You must not nest more than one condition into <waitfor>");
164
        }
165
166 5
        if ($this->countConditions() < 1) {
167
            throw new BuildException("You must nest a condition into <waitfor>");
168
        }
169
170 5
        $cs = $this->getIterator();
171 5
        $condition = $cs->current();
172
173 5
        $maxWaitMillis = $this->maxWait * $this->maxWaitMultiplier;
174 5
        $checkEveryMillis = $this->checkEvery * $this->checkEveryMultiplier;
175
176 5
        $start = microtime(true) * 1000;
177 5
        $end = $start + $maxWaitMillis;
178
179 5
        while (microtime(true) * 1000 < $end) {
180 5
            if ($condition->evaluate()) {
181 2
                $this->processSuccess();
182 2
                return;
183
            }
184
185 3
            usleep($checkEveryMillis * 1000);
186
        }
187
188 3
        $this->processTimeout();
189 2
    }
190
191 2
    protected function processSuccess()
192
    {
193 2
        $this->log($this->getTaskName() . ": condition was met", Project::MSG_VERBOSE);
194 2
    }
195
196 3
    protected function processTimeout()
197
    {
198 3
        $this->log($this->getTaskName() . ": timeout", Project::MSG_VERBOSE);
199
200 3
        if ($this->timeoutProperty != null) {
201 3
            $this->project->setNewProperty($this->timeoutProperty, "true");
202
        }
203 3
    }
204
}
205