public void ReleaseNode(DockerNode node, string jobDescription)
        {
            TaskCompletionSource <DockerNode> source = null;

            lock (_nodesLock)
            {
                node.RunningJobDescriptions.TryRemove(jobDescription, out var _);
                // 判断等待队列是否为空
                foreach (var childQueue in _waitReleaseQueue)
                {
                    // 不为空时需要把节点分配给正在等待的任务
                    // 正在运行的任务数量不变
                    if (childQueue.Value.Count > 0)
                    {
                        source = childQueue.Value.Dequeue();
                        break;
                    }
                }
                if (source == null)
                {
                    // 减少节点的正在运行任务数量
                    --node.RunningJobs;
                    _nodes.Sort(new DockerNodeComparer());
                }
            }
            if (source != null)
            {
                source.SetResult(node);
            }
        }
 public DockerNodeStore(
     JoyOIManagementConfiguration configuration,
     INotificationService notificationService)
 {
     _configuration       = configuration;
     _notificationService = notificationService;
     _nodes                   = new List <DockerNode>();
     _nodesMap                = new Dictionary <string, DockerNode>();
     _waitReleaseQueue        = new SortedDictionary <int, Queue <TaskCompletionSource <DockerNode> > >();
     _nodesLock               = new object();
     _keepaliveReportInterval = TimeSpan.FromHours(1);    // 最多1小时报告一次错误
     _keepaliveScanInterval   = TimeSpan.FromSeconds(5);  // 5秒扫描一次
     _keepaliveTimeout        = TimeSpan.FromSeconds(30); // 每个节点最多使用30秒
     _keepaliveMaxErrorCount  = 3;                        // 3次失败后标记节点状态异常
     foreach (var nodeInfo in _configuration.Nodes)
     {
         var node = new DockerNode(nodeInfo.Key, nodeInfo.Value);
         _nodes.Add(node);
         _nodesMap.Add(node.Name, node);
     }
 }