Ejemplo n.º 1
0
        /// <summary>
        /// 获取一个可以工作的机器人
        /// </summary>
        /// <param name="clientKey">客户的唯一标识</param>
        /// <param name="type">申请机器人的类型</param>
        /// <returns>一台可工作的机器人</returns>
        public IRobot ApplyOneAvailableRobot(RobotType type, string clientKey = null)
        {
            IRobot robot = null;

            if (String.IsNullOrEmpty(clientKey))
            {
                throw new ArgumentException("Client Key 不能为空");
            }

            // 1. 如果之前有注册机器人,则继续使用
            if (_roster.ContainsKey(clientKey))
            {
                string      apiKey      = _roster[clientKey];
                RobotStruct robotStruct = _robots[apiKey];

                if (robotStruct.RobotType != type)
                {
                    throw new UnmatchedTypeException(robotStruct.RobotType, "已经注册了不同类型的机器人");
                }

                robot = robotStruct.Robot;
                return(robot);
            }

            // 2. 如果是共享类型的机器人,则搜索
            if (RobotType.Public == type)
            {
                foreach (string apiKey in _robots.Keys)
                {
                    RobotStruct robotStruct = _robots[apiKey];
                    if (RobotType.Public == robotStruct.RobotType &&
                        robotStruct.CanRegister())
                    {
                        if (robotStruct.Register(clientKey))
                        {
                            robot = robotStruct.Robot;
                            return(robot);
                        }
                    }
                }
            }

            // 3. 找不到合适的机器人,则创建新的机器人,并加入池中
            robot = CreateRobot(clientKey, type);

            return(robot);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 机器人每个1秒自动回收闲置时长超过规定分钟数的机器人
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            lock (_locker)
            {
                List <string> idledApiKey = new List <string>();

                foreach (string apiKey in _robots.Keys)
                {
                    RobotStruct robotStruct = _robots[apiKey];
                    IRobot      robot       = robotStruct.Robot;
                    if (robot.IdledMinutes >= _maxIdleMinutes)
                    {
                        idledApiKey.Add(apiKey);

                        foreach (string clientKey in robotStruct.RegisteredClientKeys)
                        {
                            if (_roster.ContainsKey(clientKey))
                            {
                                if (apiKey == _roster[clientKey])
                                {
                                    // 先从花名册中删除 Client Key
                                    _roster.Remove(clientKey);
                                }
                            }
                        }
                    }
                }

                // 后从机器人池删除机器人
                foreach (string apiKey in idledApiKey)
                {
                    _robots.Remove(apiKey);
                }

                // 创建最少数量的共享类型机器人
                lock (this)
                {
                    int newRobotCount = (_minRobot) - (_robots.Count);
                    foreach (string apiKey in APIKeys)
                    {
                        if (newRobotCount <= 0)
                        {
                            break;
                        }

                        // 确保此轮回收暂不使用失效的机器人
                        //if (idledApiKey.Contains(apiKey))
                        //{
                        //    continue;
                        //}

                        if (!_robots.ContainsKey(apiKey))
                        {
                            newRobotCount--;

                            IRobot      robot       = new Robot(APIBaseURL, apiKey);
                            RobotStruct robotStruct = new RobotStruct(robot, RobotType.Public, _maxClientPerRobot);
                            _robots.Add(apiKey, robotStruct);
                        }
                    }
                }

                // 后从机器人池删除机器人
                //foreach (string apiKey in idledApiKey)
                //{
                //    _robots.Remove(apiKey);
                //}
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 创建机器人实例
        /// </summary>
        private IRobot CreateRobot(string clientKey, RobotType type)
        {
            IRobot registeredRobot = null;

            // 加锁,主要防止同时并发创建机器人实例对象
            lock (this)
            {
                if (_robots.Count >= _maxRobot)
                {
                    throw new MaxRobotException(_maxRobot);
                }

                int newRobotCount = 0;
                if (RobotType.Private == type)
                {
                    newRobotCount = 1;
                }
                else if (RobotType.Public == type)
                {
                    newRobotCount = _newRobot;
                    if (_robots.Count + _newRobot >= _maxRobot)
                    {
                        newRobotCount = _maxRobot - _robots.Count;
                    }
                }

                // 创建机器人
                int maxClientPerRobot = _maxClientPerRobot;
                if (RobotType.Private == type)
                {
                    maxClientPerRobot = 1;
                }

                foreach (string key in APIKeys)
                {
                    if (newRobotCount <= 0)
                    {
                        break;
                    }

                    if (!_robots.ContainsKey(key))
                    {
                        newRobotCount--;

                        IRobot      robot       = new Robot(APIBaseURL, key);
                        RobotStruct robotStruct = new RobotStruct(robot, type, maxClientPerRobot);

                        if (null == registeredRobot)
                        {
                            robotStruct.Register(clientKey);
                            registeredRobot = robotStruct.Robot;
                            _roster.Add(clientKey, key);
                        }

                        _robots.Add(key, robotStruct);
                    }
                }
            }

            return(registeredRobot);
        }