<?php

namespace Api\PhpUtils\Hystrix;

use Odesk\Phystrix\AbstractCommand;
use Zend\Config\Config;
use Odesk\Phystrix\ApcStateStorage;
use Odesk\Phystrix\CircuitBreakerFactory;
use Odesk\Phystrix\CommandMetricsFactory;
use Odesk\Phystrix\CommandFactory;



class Hystrix
{

    private $phystrix;


    public function __construct(){
        $config = new Config($this->getConfig());

        $stateStorage = new ApcuStateStorage();
        $circuitBreakerFactory = new CircuitBreakerFactory($stateStorage);
        $commandMetricsFactory = new CommandMetricsFactory($stateStorage);
        $this->phystrix = new CommandFactory(
            $config, new \Zend\Di\ServiceLocator(), $circuitBreakerFactory, $commandMetricsFactory,
            new \Odesk\Phystrix\RequestCache(), new \Odesk\Phystrix\RequestLog()
        );
    }

    public function run($class, ...$params){
        $command = $this->phystrix->getCommand($class, ...$params);
        return $command->execute();
    }


    private function getConfig(){
        return [
            'default' => [
                'fallback' => array(
                    'enabled' => config("request","hystrix.fallback.enabled"),
                ),
                'circuitBreaker' => array(
                    'enabled' => config("request","hystrix.circuitBreaker.enabled"),
                    // 失败率达到多少百分比后熔断
                    'errorThresholdPercentage' => config("request","hystrix.circuitBreaker.errorThresholdPercentage"),
                    // 是否强制开启熔断
                    'forceOpen' => config("request","hystrix.circuitBreaker.forceOpen"),
                    // 是否强制关闭熔断
                    'forceClosed' => config("request","hystrix.circuitBreaker.forceClosed"),
                    // 一个统计窗口内熔断触发的最小个数/10s
                    'requestVolumeThreshold' => config("request","hystrix.circuitBreaker.requestVolumeThreshold"),
                    // 熔断多少秒后去尝试请求
                    'sleepWindowInMilliseconds' => config("request","hystrix.circuitBreaker.sleepWindowInMilliseconds"),
                ),
                'metrics' => array(
                    // 采样时间间隔
                    'healthSnapshotIntervalInMilliseconds' => config("request","hystrix.metrics.healthSnapshotIntervalInMilliseconds"),
                    // 设置统计滚动窗口的长度，以毫秒为单位。用于监控和熔断器。
                    'rollingStatisticalWindowInMilliseconds' => config("request","hystrix.metrics.rollingStatisticalWindowInMilliseconds"),
                    // 设置统计窗口的桶数量
                    'rollingStatisticalWindowBuckets' => config("request","hystrix.metrics.rollingStatisticalWindowBuckets"),
                ),
                'requestCache' => array(
                    // 设置是否缓存请求
                    'enabled' => config("request","hystrix.requestCache.enabled"),
                ),
                'requestLog' => array(
                    // 设置HystrixCommand执行和事件是否打印到HystrixRequestLog中
                    'enabled' => config("request","hystrix.requestLog.enabled"),
                )
            ]
        ];
    }
}