Completed
Push — master ( 151512...fa81e5 )
by De Cramer
08:19 queued 03:57
created

AbstractApplication::run()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 68
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 7.9936

Importance

Changes 0
Metric Value
dl 0
loc 68
ccs 24
cts 33
cp 0.7272
rs 6.9654
c 0
b 0
f 0
cc 7
eloc 34
nc 7
nop 0
crap 7.9936

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 eXpansion\Framework\Core\Services\DedicatedConnection\Factory;
8
use Maniaplanet\DedicatedServer\Connection;
9
use Propel\Runtime\Connection\Exception\ConnectionException;
10
use Propel\Runtime\Propel;
11
use Psr\Log\LoggerInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
abstract class AbstractApplication implements RunInterface
15
{
16
    /** Base eXpansion callbacks. */
17
    const EVENT_BEFORE_INIT = "expansion.before_init";
18
    const EVENT_AFTER_INIT = "expansion.after_init";
19
    const EVENT_READY = "expansion.ready";
20
    const EVENT_STOP = "expansion.stop";
21
22
    const EXPANSION_VERSION = "dev";
23
24
    /** @var Factory */
25
    protected $factory;
26
27
    /** @var DispatcherInterface */
28
    protected $dispatcher;
29
30
    /** @var Console */
31
    protected $console;
32
33
    /** @var bool */
34
    protected $isRunning = true;
35
    /**
36
     * @var LoggerInterface
37
     */
38
    private $logger;
39
40
    /**
41
     * AbstractApplication constructor.
42
     *
43
     * @param DispatcherInterface $dispatcher
44
     * @param Factory $factory
45
     * @param Console $output
46
     * @param LoggerInterface $logger
47
     */
48 150
    public function __construct(
49
        DispatcherInterface $dispatcher,
50
        Factory $factory,
51
        Console $output,
52
        LoggerInterface $logger
53
    ) {
54 150
        $this->factory = $factory;
55 150
        $this->dispatcher = $dispatcher;
56 150
        $this->console = $output;
57 150
        $this->logger = $logger;
58 150
    }
59
60
    /**
61
     * Initialize eXpansion.
62
     *
63
     * @param OutputInterface $console
64
     *
65
     * @return $this|mixed
66
     * @throws \Maniaplanet\DedicatedServer\Xmlrpc\TransportException
67
     */
68 1
    public function init(OutputInterface $console)
69
    {
70 1
        $this->console->init($console, $this->dispatcher);
71 1
        $this->dispatcher->dispatch(self::EVENT_BEFORE_INIT, []);
72
73 1
        $this->factory->createConnection();
74 1
        $this->dispatcher->init($this->factory->getConnection());
75
76 1
        $this->dispatcher->dispatch(self::EVENT_AFTER_INIT, []);
77 1
        return $this;
78
    }
79
80
    /**
81
     * Run eXpansion
82
     *
83
     * @inheritdoc
84
     */
85 2
    public function run()
86
    {
87
        // Time each cycle needs to take in microseconds. Wrunning 60 cycles per seconds to have optimal response time.
88 2
        $cycleTime = (1 / 60) * 1000000;
89
90
        // Running GC collect every 5 minutes should be sufficient.;
91 2
        $gcCycleTime = 60 * 5;
92
93
        // Time when we will force gc cycles.
94 2
        $maxGcCycleTime = 60 * 20;
95
96
        // Last time garbage collector ran. Assume that at start it ran.
97 2
        $lastGcTime = time();
98
99 2
        $this->console->writeln("Running preflight checks...");
100 2
        $this->factory->getConnection()->enableCallbacks(true);
101
102
        // need to send this for scripts to start callback handling
103
        try {
104 2
            $this->factory->getConnection()->triggerModeScriptEvent("XmlRpc.EnableCallbacks", ["True"]);
105
        } catch (\Exception $exception) {
106
            $this->factory->getConnection()->saveMatchSettings('MatchSettings/eXpansion-mode-fail-'.date(DATE_ISO8601).'.txt');
107
            throw $exception;
108
        }
109
110 2
        $this->console->writeln("preflight checks OK.");
111
112 2
        $this->dispatcher->dispatch(self::EVENT_READY, []);
113
114 2
        $this->console->writeln("And takeoff");
115
116
        do {
117 2
            $startTime = microtime(true);
118
119
            // Run the actuall application
120 2
            $this->executeRun();
121
122 2
            $endTime = microtime(true);
123 2
            $delay = $cycleTime - (($endTime - $startTime) * 1000000);
124
125
            // If we got lot's of time and it's been a while since last GC collect let's run a garbage collector
126
            // cycle this iteration.
127 2
            if ($delay > $cycleTime / 2 && $lastGcTime < (time() - $gcCycleTime)) {
128
                // PHP does this automatically as well but in some mysterious ways it can sometimes keep in memory
129
                // hundred of mb's before running it.
130
                gc_collect_cycles();
131
                $lastGcTime = time();
132
133
                // Renew delay so that this iteration isn't much slower then the others
134
                $endTime = microtime(true);
135
                $delay = $cycleTime - (($endTime - $startTime) * 1000000);
136
            }
137
138 2
            if ($lastGcTime < (time() - $maxGcCycleTime)) {
139
                //It's been a while since last Garbage collection forcing it to go even through the application is
140
                // running slow.
141
                gc_collect_cycles();
142
                $lastGcTime = time();
143
144 2
            } elseif ($delay > 0) {
145 2
                usleep($delay);
146
            }
147 2
        } while ($this->isRunning);
148
149 2
        $this->factory->getConnection()->sendHideManialinkPage(null);
150 2
        $this->factory->getConnection()->triggerModeScriptEvent("Shootmania.UI.ResetProperties", []);
151 2
        $this->factory->getConnection()->triggerModeScriptEvent("Trackmania.UI.ResetProperties", []);
152 2
    }
153
154
    /**
155
     * Stop eXpansion.
156
     */
157 2
    public function stopApplication()
158
    {
159 2
        $this->dispatcher->dispatch(self::EVENT_STOP, []);
160 2
        $this->isRunning = false;
161 2
    }
162
163
    abstract protected function executeRun();
164
}
165