Browse Source

增加过载时通道选举器

stanley-king 3 years ago
parent
commit
ded7396516

+ 1 - 1
helper/refill/LZRefillFactory.php

@@ -23,7 +23,7 @@ require_once(BASE_HELPER_PATH . '/refill/policy/PolicyUtil.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/lingzh/quality_ploy.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/lingzh/quality_ploy.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/channel_filter.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/channel_filter.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mratio_control.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mratio_control.php');
-
+require_once(BASE_HELPER_PATH . '/refill/policy/overload_assigner.php');
 
 
 
 
 use Log;
 use Log;

+ 1 - 3
helper/refill/XYZRefillFactory.php

@@ -27,9 +27,7 @@ require_once(BASE_HELPER_PATH . '/refill/policy/xyz/quality_ploy.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mgroup.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mgroup.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/channel_filter.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/channel_filter.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mratio_control.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mratio_control.php');
-require_once(BASE_HELPER_PATH . '/refill/policy/mavg_price.php');
-
-
+require_once(BASE_HELPER_PATH . '/refill/policy/overload_assigner.php');
 
 
 use Log;
 use Log;
 use StatesHelper;
 use StatesHelper;

+ 31 - 10
helper/refill/policy/chctl.php

@@ -102,13 +102,8 @@ class chctl
 
 
     public function match($names,int $spec, int $card_type,int $quality)
     public function match($names,int $spec, int $card_type,int $quality)
     {
     {
-        if($card_type == mtopcard\ThirdRefillCard)
-        {
-            $result = [];
-            foreach ($names as $name) {
-                $result[$name] = false;
-            }
-            return $result;
+        if ($card_type == mtopcard\ThirdRefillCard) {
+            return $names;
         }
         }
 
 
         $ctl_items = [];
         $ctl_items = [];
@@ -161,9 +156,28 @@ class chctl
         usort($usable_items, $ascending);
         usort($usable_items, $ascending);
 
 
         $result = [];
         $result = [];
-        foreach ($usable_items as $item) {
+
+        $over_loads = [];
+        foreach ($usable_items as $item)
+        {
             $name = $item->name();
             $name = $item->name();
-            $result[$name] = $item->speed_overload();
+            $over_load = $item->speed_overload();
+            if($over_load) {
+                $over_loads[] = $item;
+            } else {
+                $result[] = $name;
+            }
+        }
+
+        if(!empty($over_loads))
+        {
+            $assigner = new overload_assigner();
+            $assigner->add($over_loads);
+            $over_loads = $assigner->assign();
+
+            foreach ($over_loads as $item) {
+                $result[] = $item->name();
+            }
         }
         }
 
 
         return $result;
         return $result;
@@ -390,7 +404,8 @@ class chctl
         $left_times = $left_times <= 0 ? 1 : $left_times;
         $left_times = $left_times <= 0 ? 1 : $left_times;
         Log::record("left_times = {$left_times}",Log::DEBUG);
         Log::record("left_times = {$left_times}",Log::DEBUG);
 
 
-        $desc_profit = function ($l, $r) use($out_price,$formater,$left_times) {
+        $desc_profit = function ($l, $r) use($out_price,$formater,$left_times)
+        {
             [$lCount,$lRatio] = $l->notify_ratio();
             [$lCount,$lRatio] = $l->notify_ratio();
             [$rCount,$rRatio] = $r->notify_ratio();
             [$rCount,$rRatio] = $r->notify_ratio();
 
 
@@ -526,6 +541,12 @@ class chctl
                 $normals[] = $item;
                 $normals[] = $item;
             }
             }
         }
         }
+
+        if(!empty($overloads)) {
+            $assigner = new overload_assigner();
+            $assigner->add($overloads);
+            $overloads = $assigner->assign();
+        }
         $profits = array_merge($normals, $overloads);
         $profits = array_merge($normals, $overloads);
 
 
         $feed_names = [];
         $feed_names = [];

+ 0 - 4
helper/refill/policy/ctl_item.php

@@ -2,8 +2,6 @@
 
 
 namespace refill;
 namespace refill;
 
 
-use Log;
-
 class ctl_item
 class ctl_item
 {
 {
     const speed_secs = 60;
     const speed_secs = 60;
@@ -86,8 +84,6 @@ class ctl_item
     {
     {
         $this->load($this->mLastReadTime);
         $this->load($this->mLastReadTime);
         $speed = array_sum($this->mRecords);
         $speed = array_sum($this->mRecords);
-        //Log::record("{$this->mPrefix} speed = {$speed} max_speed={$this->mMaxSpeed}", Log::DEBUG);
-
         return $speed;
         return $speed;
     }
     }
 
 

+ 0 - 2
helper/refill/policy/lingzh/policy.php

@@ -12,7 +12,6 @@ class policy extends ProviderManager implements IPolicy
     protected $mQuality;
     protected $mQuality;
     protected $mPrices;
     protected $mPrices;
     protected $mGroupCtl;
     protected $mGroupCtl;
-    protected $mAvgPrice;
     protected $mRatioCtl;
     protected $mRatioCtl;
 
 
     public function __construct()
     public function __construct()
@@ -22,7 +21,6 @@ class policy extends ProviderManager implements IPolicy
         $this->mQuality = new quality_ploy();
         $this->mQuality = new quality_ploy();
         $this->mPrices = new merchant_price();
         $this->mPrices = new merchant_price();
         $this->mGroupCtl = new rgroup_ctl();
         $this->mGroupCtl = new rgroup_ctl();
-        $this->mAvgPrice = new mavg_price();
         $this->mRatioCtl = new mratio_control();
         $this->mRatioCtl = new mratio_control();
 
 
         $this->mQuality->setRatioCtl($this->mRatioCtl);
         $this->mQuality->setRatioCtl($this->mRatioCtl);

+ 97 - 0
helper/refill/policy/overload_assigner.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace refill;
+
+use Log;
+
+class overload_assigner
+{
+    private $mCtlItems;
+    public function __construct()
+    {
+        $this->mCtlItems = [];
+    }
+
+    public function add($ctls)
+    {
+        foreach ($ctls as $item) {
+            $name = $item->name();
+            $max_speed = $item->max_speed();
+            if($max_speed > 0) {
+                $this->mCtlItems[$name] = $item;
+            }
+        }
+    }
+
+    public function assign()
+    {
+        $pCtlItems = $this->mCtlItems;
+        if(empty($pCtlItems)) return [];
+
+        $namesor = function ($ctls)
+        {
+            $result = [];
+            foreach ($ctls as $item) {
+                $result[] = $item->name();
+            }
+            return $result;
+        };
+
+        $ctlsor = function ($names) use ($pCtlItems)
+        {
+            $result = [];
+            foreach ($names as $name) {
+                $result[] = $pCtlItems[$name];
+            }
+            return $result;
+        };
+
+
+        $elector = function ($none_names) use ($pCtlItems)
+        {
+            $sections = [];
+            $total = 0;
+            foreach ($none_names as $name)
+            {
+                $ctl_item = $pCtlItems[$name];
+                $length = $ctl_item->max_speed();
+                $total += $length;
+                $sections[] = ['name' => $name,'length' => $length];
+            }
+
+            $anchor = mt_rand(1,$total);
+            foreach ($sections as $section)
+            {
+                $name = $section['name'];
+                $length = $section['length'];
+
+                if($anchor > $length) {
+                    $anchor -= $length;
+                }
+                else {
+                    return $name;
+                }
+            }
+        };
+
+        $using_names = [];
+        $all_names = $namesor($this->mCtlItems);
+
+        do {
+            $none_assign = array_diff($all_names,$using_names);
+            if(count($none_assign) <= 1) {
+                $using_names = array_merge($using_names,$none_assign);
+                break;
+            }
+            else
+            {
+                $hit_name = $elector($none_assign);
+                $using_names[] = $hit_name;
+            }
+
+        } while(true);
+
+        Log::record("overload_assigner result= ". implode(',',$using_names),Log::DEBUG);
+        return $ctlsor($using_names);
+    }
+}

+ 17 - 33
helper/refill/policy/xyz/policy.php

@@ -301,45 +301,29 @@ class policy extends ProviderManager implements IPolicy
 
 
         $mobile_types = [mtopcard\ChinaMobileCard, mtopcard\ChinaUnicomCard, mtopcard\ChinaTelecomCard];
         $mobile_types = [mtopcard\ChinaMobileCard, mtopcard\ChinaUnicomCard, mtopcard\ChinaTelecomCard];
         $qualities = [Quality::Normal];
         $qualities = [Quality::Normal];
-        if($auto_find && in_array($card_type,$mobile_types) && in_array($cur_quality,$qualities))
-        {
+        if ($auto_find && in_array($card_type, $mobile_types) && in_array($cur_quality, $qualities)) {
             $names = $this->mChannelControl->auto_match($names, $spec, $card_type, $cur_quality, $price - $extra_price, time() - $order_time);
             $names = $this->mChannelControl->auto_match($names, $spec, $card_type, $cur_quality, $price - $extra_price, time() - $order_time);
-            Log::record("policy::find_providers ChannelControl auto_match quality={$cur_quality} spec={$spec} card_type={$card_type}  result=" . implode(',', $names), Log::DEBUG);
-
-            $name_provider = [];
-            foreach ($providers as $provider) {
-                $name = $provider->name();
-                $name_provider[$name] = $provider;
-            }
-
-            $result = [];
-            foreach ($names as $name)
-            {
-                if(array_key_exists($name,$name_provider)) {
-                    $result[] = $name_provider[$name];
-                }
-            }
+            Log::record("policy::find_providers ChannelControl auto_match quality={$cur_quality} spec={$spec} card_type={$card_type} result=" . implode(',', $names), Log::DEBUG);
+        } else {
+            $names = $this->mChannelControl->match($names, $spec, $card_type, $cur_quality);
+            Log::record("policy::find_providers ChannelControl match quality={$cur_quality} spec={$spec} card_type={$card_type} result=" . implode(',', $names), Log::DEBUG);
+        }
 
 
-            return [$result,false];
+        $name_provider = [];
+        foreach ($providers as $provider) {
+            $name = $provider->name();
+            $name_provider[$name] = $provider;
         }
         }
-        else
-        {
-            $name_overloads = $this->mChannelControl->match($names, $spec, $card_type, $cur_quality);
-            Log::record("policy::find_providers ChannelControl match result=" . implode(',',array_keys($name_overloads)),Log::DEBUG);
 
 
-            $result = [];
-            foreach ($name_overloads as $name => $overload)
-            {
-                foreach ($providers as $provider)
-                {
-                    if($name == $provider->name()) {
-                        $result[] = $provider;
-                    }
-                }
+        $result = [];
+        foreach ($names as $name)
+        {
+            if(array_key_exists($name,$name_provider)) {
+                $result[] = $name_provider[$name];
             }
             }
-
-            return [$result,false];
         }
         }
+
+        return [$result,false];
     }
     }
 
 
     public function price($mchid,$spec,$card_type,$quality,$pcode)
     public function price($mchid,$spec,$card_type,$quality,$pcode)

+ 58 - 0
test/TestOverloadAssign.php

@@ -0,0 +1,58 @@
+<?php
+
+
+use PHPUnit\Framework\TestCase;
+
+define('APP_ID', 'test');
+define('BASE_ROOT_PATH', str_replace('/test', '', dirname(__FILE__)));
+
+require_once(BASE_ROOT_PATH . '/global.php');
+require_once(BASE_CORE_PATH . '/lrlz.php');
+require_once(BASE_ROOT_PATH . '/fooder.php');
+
+require_once(BASE_CORE_PATH . '/framework/function/http.php');
+require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
+require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
+
+class ctl_item
+{
+    private $mName;
+    private $mMaxSpeed;
+    public function __construct($name,$max_speed)
+    {
+        $this->mName = $name;
+        $this->mMaxSpeed = $max_speed;
+    }
+    public function name() {
+        return $this->mName;
+    }
+    public function max_speed() {
+        return $this->mMaxSpeed;
+    }
+}
+
+
+
+class TestOverloadAssign extends TestCase
+{
+    public static function setUpBeforeClass() : void
+    {
+        Base::run_util();
+    }
+
+    public function testRandomOverload()
+    {
+        $assigner = new refill\overload_assigner();
+
+        $ctls = [];
+
+        $items = ['a' => 1,'b' => 30,'c' => 50,'d' => 100,'e' => 500];
+        foreach ($items as $name => $max_speed) {
+            $ctls[] = new ctl_item($name,$max_speed);
+        }
+        $assigner->add($ctls);
+        for ($i = 0; $i < 10000; $i++) {
+            $result = $assigner->assign();
+        }
+    }
+}

+ 2 - 0
test/TestThirdRefill.php

@@ -43,4 +43,6 @@ class TestThirdRefill extends TestCase
         $params = json_decode($data, true);
         $params = json_decode($data, true);
         refill\RefillFactory::instance()->notify('sctongqian', $params);
         refill\RefillFactory::instance()->notify('sctongqian', $params);
     }
     }
+
+
 }
 }