Completed
Pull Request — master (#252)
by
unknown
05:45
created

AbstractApplication::run()   C

Complexity

Conditions 8
Paths 10

Size

Total Lines 72
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
dl 0
loc 72
ccs 0
cts 36
cp 0
rs 6.3883
c 0
b 0
f 0
cc 8
eloc 37
nc 10
nop 0
crap 72

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
4
namespace eXpansion\Framework\Core\Services\Application;
5
6
use eXpansion\Framework\Core\Services\Console;
7
use Maniaplanet\DedicatedServer\Connection;
8
use Propel\Runtime\Connection\Exception\ConnectionException;
9
use Propel\Runtime\Propel;
10
use Psr\Log\LoggerInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
13
abstract class AbstractApplication implements RunInterface
14
{
15
    /** Base eXpansion callbacks. */
16
    const EVENT_BEFORE_INIT = "expansion.before_init";
17
    const EVENT_AFTER_INIT = "expansion.after_init";
18
    const EVENT_READY = "expansion.ready";
19
    const EVENT_STOP = "expansion.stop";
20
21
    const EXPANSION_VERSION = "dev";
22
23
    /** @var Connection */
24
    protected $connection;
25
26
    /** @var DispatcherInterface */
27
    protected $dispatcher;
28
29
    /** @var Console */
30
    protected $console;
31
32
    /** @var bool */
33
    protected $isRunning = true;
34
    /**
35
     * @var LoggerInterface
36
     */
37
    private $logger;
38
39
    /**
40
     * Application constructor.
41
     *
42
     * @param DispatcherInterface $dispatcher
43
     * @param Connection $connection
44
     * @param Console $output
45
     * @param LoggerInterface $logger
46
     */
47 138
    public function __construct(
48
        DispatcherInterface $dispatcher,
49
        Connection $connection,
50
        Console $output,
51
        LoggerInterface $logger
52
    ) {
53 138
        $this->connection = $connection;
54 138
        $this->dispatcher = $dispatcher;
55 138
        $this->console = $output;
56 138
        $this->logger = $logger;
57 138
    }
58
59
    /**
60
     * Initialize eXpansion.
61
     *
62
     * @param OutputInterface $console
63
     *
64
     * @return $this
65
     */
66
    public function init(OutputInterface $console)
67
    {
68
        $this->console->init($console, $this->dispatcher);
69
        $this->dispatcher->dispatch(self::EVENT_BEFORE_INIT, []);
70
        $this->dispatcher->init($this->connection);
71
        $this->dispatcher->dispatch(self::EVENT_AFTER_INIT, []);
72
73
        return $this;
74
    }
75
76
    /**
77
     * Run eXpansion
78
     *
79
     * @inheritdoc
80
     */
81
    public function run()
82
    {
83
        // Time each cycle needs to take in microseconds. Wrunning 60 cycles per seconds to have optimal response time.
84
        $cycleTime = (1 / 60) * 1000000;
85
86
        // Running GC collect every 5 minutes should be sufficient.;
87
        $gcCycleTime = 60 * 5;
88
89
        // Time when we will force gc cycles.
90
        $maxGcCycleTime = 60 * 20;
91
92
        // Last time garbage collector ran. Assume that at start it ran.
93
        $lastGcTime = time();
94
95
        $this->console->writeln("Running preflight checks...");
96
        $this->connection->enableCallbacks(true);
97
98
        // need to send this for scripts to start callback handling
99
        try {
100
            $this->connection->triggerModeScriptEvent("XmlRpc.EnableCallbacks", ["True"]);
101
            Propel::getConnection()->inTransaction();
102
        } catch (ConnectionException $propelException) {
103
104
            $this->console->writeln("\nLooks like your database connection is down, see logs for more details.");
105
            $this->console->writeln("Please check-in later, when you database is up and running.");
106
            $this->logger->error("Unable to open connection for database server", ["exception" => $propelException]);
107
            exit(1);
0 ignored issues
show
Coding Style Compatibility introduced by
The method run() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
108
109
        } catch (\Exception $exception) {
110
            $this->connection->saveMatchSettings('MatchSettings/eXpansion-mode-fail-' . date(DATE_ISO8601) . '.txt');
111
            throw $exception;
112
        }
113
114
        $this->console->writeln("preflight checks OK.");
115
116
        $this->dispatcher->dispatch(self::EVENT_READY, []);
117
118
        $this->console->writeln("And takeoff");
119
120
        do {
121
            $startTime = microtime(true);
122
123
            // Run the actuall application
124
            $this->executeRun();
125
126
            $endTime = microtime(true);
127
            $delay = $cycleTime - (($endTime - $startTime) * 1000000);
128
129
            // If we got lot's of time and it's been a while since last GC collect let's run a garbage collector
130
            // cycle this iteration.
131
            if ($delay > $cycleTime / 2 && $lastGcTime < (time() - $gcCycleTime)) {
132
                // PHP does this automatically as well but in some mysterious ways it can sometimes keep in memory
133
                // hundred of mb's before running it.
134
                gc_collect_cycles();
135
                $lastGcTime = time();
136
137
                // Renew delay so that this iteration isn't much slower then the others
138
                $endTime = microtime(true);
139
                $delay = $cycleTime - (($endTime - $startTime) * 1000000);
140
            }
141
142
            if ($lastGcTime < (time() - $maxGcCycleTime)) {
143
                //It's been a while since last Garbage collection forcing it to go even through the application is
144
                // running slow.
145
                gc_collect_cycles();
146
                $lastGcTime = time();
147
148
            } elseif ($delay > 0) {
149
                usleep($delay);
150
            }
151
        } while ($this->isRunning);
152
    }
153
154
    /**
155
     * Stop eXpansion.
156
     */
157
    public function stopApplication()
158
    {
159
        $this->dispatcher->dispatch(self::EVENT_STOP, []);
160
        $this->isRunning = false;
161
    }
162
163
    abstract protected function executeRun();
164
}
165