Test Failed
Push — master ( 502b5c...f799ac )
by Alexey
04:27
created

Daemon::start()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 19
nc 8
nop 0
dl 0
loc 26
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
class Daemon extends Module {
4
    private $tasksDirResource;
5
    private $serializer;
6
    private $workDir;
7
    public $needCheck = false;
8
9
    function check() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
10
        $workDir = $this->workDir();
11
        $lock = fopen($workDir . '/daemon.lock', 'w+');
12
        if (flock($lock, LOCK_EX | LOCK_NB)) {
13
            echo 'started';
14
            flock($lock, LOCK_UN);
15
            fclose($lock);
16
            $fp = fsockopen($_SERVER['SERVER_NAME'],
17
                80,
18
                $errno, $errstr, 30);
19
20
            $out = "GET /daemon/start HTTP/1.1\r\n";
21
            $out .= "Host: " . $_SERVER['SERVER_NAME'] . "\r\n";
22
            $out .= "Connection: Close\r\n\r\n";
23
            fwrite($fp, $out);
24
            fclose($fp);
25
        }
26
    }
27
28
    function start() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
29
        $workDir = $this->workDir();
30
        $lock = fopen($workDir . '/daemon.lock', 'w+');
31
        if (flock($lock, LOCK_EX | LOCK_NB)) {
32
            ignore_user_abort(true);
33
            set_time_limit(0);
34
            while (true) {
35
                $taskFile = $this->getNextTask();
36
                if (!$taskFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $taskFile of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
37
                    for ($i = 0; $i < 60; $i++) {
38
                        sleep(1);
39
                        $taskFile = $this->getNextTask();
40
                        if ($taskFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $taskFile of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
41
                            break;
42
                        }
43
                    }
44
                    if (!$taskFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $taskFile of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
45
                        break;
46
                    }
47
                }
48
                $task = $this->unserialize(file_get_contents($taskFile));
49
                unlink($taskFile);
50
                $task();
51
            }
52
        }
53
    }
54
55
    function getNextTask() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
56
        $workDir = $this->workDir();
57
        if (!is_resource($this->tasksDirResource)) {
58
            $this->tasksDirResource = opendir($workDir . '/tasks/');
59
        }
60
        if ($this->tasksDirResource) {
61
            while (false !== ($entry = readdir($this->tasksDirResource))) {
62
                if ($entry != "." && $entry != "..") {
63
                    return $workDir . '/tasks/' . $entry;
64
                }
65
            }
66
        }
67
        return false;
68
    }
69
70
    function task($callback) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
71
        $keyLog = \App::$cur->log->start('add task');
72
        $workDir = $this->workDir();
73
        $taskFile = $workDir . '/tasks/' . microtime(true) . '.task';
74
        $keyLog2 = \App::$cur->log->start('serialize task');
75
        $serialize = $this->serialize($callback);
76
        \App::$cur->log->end($keyLog2);
77
        $keyLog3 = \App::$cur->log->start('put task to file');
78
        file_put_contents($taskFile, $serialize);
79
        \App::$cur->log->end($keyLog3);
80
        $this->needCheck = true;
81
        \App::$cur->log->end($keyLog);
82
        return $taskFile;
83
    }
84
85
    function workDir() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
86
        if ($this->workDir) {
87
            return $this->workDir;
88
        }
89
        $path = App::$primary->path . '/daemon';
90
        Tools::createDir(App::$primary->path . '/daemon/tasks');
91
        return $path;
92
    }
93
94
    function unserialize($item) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
95
        return $this->serializer()->unserialize($item);
96
    }
97
98
    function serialize($item) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
99
        return $this->serializer()->serialize($item);
100
    }
101
102
    function serializer() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
103
        if ($this->serializer) {
104
            return $this->serializer;
105
        }
106
        \ComposerCmd::requirePackage('jeremeamia/superclosure');
107
        return $this->serializer = new \SuperClosure\Serializer(new SuperClosure\Analyzer\TokenAnalyzer());
108
    }
109
110
    function __destruct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
111
        if ($this->needCheck) {
112
            $this->check();
113
        }
114
    }
115
116
}