Completed
Pull Request — master (#264)
by Дмитрий
04:21
created

AppResolver   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 150
Duplicated Lines 5.33 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 7
Bugs 3 Features 0
Metric Value
c 7
b 3
f 0
dl 8
loc 150
rs 9
wmc 35
lcom 1
cbo 5

6 Methods

Rating   Name   Duplication   Size   Complexity  
C preload() 0 27 14
C getRequest() 0 26 7
A getRequestRoute() 0 3 1
A getInstanceByAppName() 0 4 1
D getInstance() 8 34 10
A getAppFullName() 0 4 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace PHPDaemon\Core;
3
4
use PHPDaemon\Config;
5
6
/**
7
 * Application resolver
8
 * @package PHPDaemon\Core
9
 * @author  Vasily Zorin <[email protected]>
10
 */
11
class AppResolver
12
{
13
    use \PHPDaemon\Traits\ClassWatchdog;
14
    use \PHPDaemon\Traits\StaticObjectWatchdog;
15
16
    /**
17
     * Preloads applications
18
     * @param  boolean $privileged If true, we are in the pre-fork stage
19
     * @return void
20
     */
21
    public function preload($privileged = false)
22
    {
23
        foreach (Daemon::$config as $fullname => $section) {
0 ignored issues
show
Bug introduced by
The expression \PHPDaemon\Core\Daemon::$config of type object<PHPDaemon\Config\Object> is not traversable.
Loading history...
24
            if (!$section instanceof Config\Section) {
25
                continue;
26
            }
27
            if (isset($section->limitinstances)) {
28
                continue;
29
            }
30
            if ((isset($section->enable) && $section->enable->value) ||
31
                (!isset($section->enable) && !isset($section->disable))
32
            ) {
33
                if (mb_orig_strpos($fullname, ':') === false) {
34
                    $fullname .= ':';
35
                }
36
                list($appName, $instance) = explode(':', $fullname, 2);
37
                $appNameLower = strtolower($appName);
38
                if ($appNameLower !== 'pool' && $privileged && (!isset($section->privileged) || !$section->privileged->value)) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
39
                    continue;
40
                }
41
                if (isset(Daemon::$appInstances[$appNameLower][$instance])) {
42
                    continue;
43
                }
44
                $this->getInstance($appName, $instance, true, true);
45
            }
46
        }
47
    }
48
49
    /**
50
     * Gets instance of application
51
     * @param  string $appName Application name
52
     * @param  string $instance Instance name
53
     * @param  boolean $spawn If true, we spawn an instance if absent
54
     * @param  boolean $preload If true, worker is at the preload stage
55
     * @return object $instance AppInstance
56
     */
57
    public function getInstance($appName, $instance = '', $spawn = true, $preload = false)
58
    {
59
        $class = ClassFinder::find($appName, 'Applications');
60
        if (isset(Daemon::$appInstances[$class][$instance])) {
61
            return Daemon::$appInstances[$class][$instance];
62
        }
63
        if (!$spawn) {
64
            return false;
65
        }
66
        $fullname = $this->getAppFullName($appName, $instance);
67 View Code Duplication
        if (!class_exists($class)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
68
            Daemon::$process->log(__METHOD__ . ': unable to find application class ' . json_encode($class) . '\'');
69
            return false;
70
        }
71 View Code Duplication
        if (!is_subclass_of($class, '\\PHPDaemon\\Core\\AppInstance')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
            Daemon::$process->log(__METHOD__ . ': class ' . json_encode($class) . '\' found, but skipped as long as it is not subclass of \\PHPDaemon\\Core\\AppInstance');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 171 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
73
            return false;
74
        }
75
        $fullnameClass = $this->getAppFullName($class, $instance);
76
        if ($fullname !== $fullnameClass && isset(Daemon::$config->{$fullname})) {
77
            Daemon::$config->renameSection($fullname, $fullnameClass);
78
        }
79
        if (!$preload) {
80
            /** @noinspection PhpUndefinedVariableInspection */
81
            if (!$class::$runOnDemand) {
82
                return false;
83
            }
84
            if (isset(Daemon::$config->{$fullnameClass}->limitinstances)) {
85
                return false;
86
            }
87
        }
88
89
        return new $class($instance);
90
    }
91
92
    /**
93
     * Resolve full name of application by its class and name
94
     * @param  string $appName Application name
95
     * @param  string $instance Application class
96
     * @return string
97
     */
98
    public function getAppFullName($appName, $instance = '')
99
    {
100
        return $appName . ($instance !== '' ? ':' . $instance : '');
101
    }
102
103
    /**
104
     * Routes incoming request to related application
105
     * @param  object $req Generic
106
     * @param  object $upstream AppInstance of Upstream
107
     * @param  string $responder
0 ignored issues
show
Documentation introduced by
Should the type for parameter $responder not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
108
     * @return object Request
109
     */
110
    public function getRequest($req, $upstream, $responder = null)
111
    {
112
        if (isset($req->attrs->server['APPNAME'])) {
113
            $appName = $req->attrs->server['APPNAME'];
114
        } elseif ($responder !== null) {
115
            $appName = $responder;
116
        } elseif (($appName = $this->getRequestRoute($req, $upstream)) !== null) {
117
            if ($appName === false) {
118
                return $req;
119
            }
120
        } else {
121
            return $req;
122
        }
123
        if (mb_orig_strpos($appName, ':') === false) {
124
            $appName .= ':';
125
        }
126
        list($app, $instance) = explode(':', $appName, 2);
127
128
        $appInstance = $this->getInstanceByAppName($app, $instance);
129
130
        if (!$appInstance) {
131
            return $req;
132
        }
133
134
        return $appInstance->handleRequest($req, $upstream);
135
    }
136
137
    /**
138
     * Routes incoming request to related application. Method is for overloading
139
     * @param  object $req Generic
140
     * @param  object $upstream AppInstance of Upstream
141
     * @return string Application's name
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
142
     */
143
    public function getRequestRoute($req, $upstream)
0 ignored issues
show
Unused Code introduced by
The parameter $req is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $upstream is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
144
    {
145
    }
146
147
    /**
148
     * Gets instance of application
149
     * @alias AppResolver::getInstance
150
     * @param  string $appName Application name
151
     * @param  string $instance Instance name
152
     * @param  boolean $spawn If true, we spawn an instance if absent
153
     * @param  boolean $preload If true, worker is at the preload stage
154
     * @return object AppInstance
155
     */
156
    public function getInstanceByAppName($appName, $instance = '', $spawn = true, $preload = false)
157
    {
158
        return $this->getInstance($appName, $instance, $spawn, $preload);
159
    }
160
}
161