ProxyManager   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 79
rs 10
c 0
b 0
f 0
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A release() 0 13 3
A generateUid() 0 3 1
A reserve() 0 43 4
1
<?php
2
/**
3
 * Created for IG Monitoring.
4
 * User: jakim <[email protected]>
5
 * Date: 09.05.2018
6
 */
7
8
namespace app\components\http;
9
10
11
use app\models\Proxy;
12
use Carbon\Carbon;
13
use Yii;
14
use yii\base\Component;
15
use yii\base\InvalidConfigException;
16
use yii\db\Expression;
17
18
class ProxyManager extends Component
19
{
20
    /**
21
     * Between requests, in seconds.
22
     *
23
     * @var int
24
     */
25
    public $restTime = 1;
26
27
    /**
28
     * After IG block, in hours.
29
     *
30
     * @var int
31
     */
32
    public $blockRestTime = 1;
33
34
    public function reserve(bool $ignoreRest = false): Proxy
35
    {
36
        $uid = $this->generateUid();
37
        $condition = [
38
            'and',
39
            ['active' => 1],
40
            ['reservation_uid' => null],
41
            ['<=', 'updated_at', new Expression(sprintf('DATE_ADD(NOW(), INTERVAL %s SECOND)', (int)$this->restTime))],
42
        ];
43
44
        $columns = [
45
            'reservation_uid' => $uid,
46
            'updated_at' => Carbon::now()->toDateTimeString(),
47
        ];
48
49
        if (!$ignoreRest) {
50
            $condition[] = ['or',
51
                ['rest_until' => null],
52
                new Expression('rest_until<=now()'),
53
            ];
54
            // btw, if rest is done, can be reset
55
            $columns['rests'] = 0;
56
            $columns['rest_until'] = null;
57
        }
58
59
        $sql = Yii::$app->db->createCommand()
60
            ->update('proxy', $columns, $condition)
61
            ->rawSql;
62
63
        $n = Yii::$app->db->createCommand("{$sql} ORDER BY [[updated_at]] ASC LIMIT 1")
64
            ->execute();
65
66
        if (empty($n)) {
67
            throw new NoProxyAvailableException();
68
        }
69
70
        $proxy = Proxy::findOne(['reservation_uid' => $uid]);
71
72
        if (empty($proxy)) {
73
            throw new InvalidConfigException('Something is wrong with \'ProxyManager\'.');
74
        }
75
76
        return $proxy;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $proxy returns the type yii\db\ActiveRecord which includes types incompatible with the type-hinted return app\models\Proxy.
Loading history...
77
    }
78
79
    public function release(Proxy $proxy, ?bool $rest = null)
80
    {
81
        $attributes = ['reservation_uid' => null];
82
        if ($rest === true) {
83
            Yii::debug(sprintf("REST: %s\n", "{$proxy->ip}:{$proxy->port}"), __METHOD__);
84
            $attributes['rests'] = new Expression('rests+1');
85
            $attributes['rest_until'] = new Expression(sprintf('DATE_ADD(NOW(), INTERVAL rests+%s HOUR)', (int)$this->blockRestTime));
86
        } elseif ($rest === false) {
87
            $attributes['rests'] = 0;
88
            $attributes['rest_until'] = null;
89
        }
90
91
        Proxy::updateAll($attributes, ['id' => $proxy->id]);
92
    }
93
94
    protected function generateUid()
95
    {
96
        return sprintf('%s_%s', Yii::$app->security->generateRandomString(64), time());
97
    }
98
}