#Region "Microsoft.VisualBasic::590ee32efdb20bd12cd3fb5f317173d5, ComputingServices\Cluster\Master.vb" ' Author: ' ' asuka (amethyst.asuka@gcmodeller.org) ' xie (genetics@smrucc.org) ' xieguigang (xie.guigang@live.com) ' ' Copyright (c) 2018 GPL3 Licensed ' ' ' GNU GENERAL PUBLIC LICENSE (GPL3) ' ' ' This program is free software: you can redistribute it and/or modify ' it under the terms of the GNU General Public License as published by ' the Free Software Foundation, either version 3 of the License, or ' (at your option) any later version. ' ' This program is distributed in the hope that it will be useful, ' but WITHOUT ANY WARRANTY; without even the implied warranty of ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ' GNU General Public License for more details. ' ' You should have received a copy of the GNU General Public License ' along with this program. If not, see . ' /********************************************************************************/ ' Summaries: ' Class Master ' ' Properties: Nodes ' ' Constructor: (+1 Overloads) Sub New ' ' Function: [Select], GetPreferNode, Invoke ' ' Sub: Scan, ScanTask ' ' ' /********************************************************************************/ #End Region Imports Microsoft.VisualBasic.ComponentModel.Collection Imports Microsoft.VisualBasic.Language Imports Microsoft.VisualBasic.Net Imports Microsoft.VisualBasic.Net.Http Imports Microsoft.VisualBasic.Net.Protocols Imports Microsoft.VisualBasic.Parallel Imports sciBASIC.ComputingServices.TaskHost Namespace Cluster ''' ''' Client ''' Public Class Master ''' ''' Online avaliable nodes in this server cluster. ''' Dim _nodes As New Dictionary(Of TaskRemote) Dim node_port% Dim net$ ''' ''' 返回节点的数量 ''' ''' Public ReadOnly Property Nodes As Integer Get Return _nodes.Count End Get End Property ''' ''' ''' ''' ''' Sub New(net$, node_port%) Me.node_port = node_port Me.net = net End Sub Public Sub Scan() Dim request As New RequestStream(Protocols.ProtocolEntry, TaskProtocols.Handshake) For Each IP$ In EnumerateAddress(Me.net) Dim response = New AsynInvoke(IP, node_port) _ .SendMessage(request, 200) SyncLock _nodes If response.Protocol = HTTP_RFC.RFC_OK Then If Not _nodes.ContainsKey(IP) Then Call _nodes.Add(New TaskRemote(IP, node_port)) Call $"Add new node: {IP}".__DEBUG_ECHO End If Else If _nodes.ContainsKey(IP) Then Call _nodes.Remove(IP) Call $"Removes offline node: {IP}".__DEBUG_ECHO End If End If End SyncLock Next End Sub ''' ''' 返回负载量最低的节点 ''' ''' Public Function GetPreferNode() As TaskRemote SyncLock _nodes Return LinqAPI.DefaultFirst(Of TaskRemote) <= _ From node As TaskRemote In _nodes.Values.AsParallel Select node, node.Load Order By Load Ascending End SyncLock End Function ''' ''' 自动分配空闲的计算节点 ''' ''' ''' Public Function Invoke(target As [Delegate], ParamArray args As Object()) As Object Dim node As TaskRemote = GetPreferNode() Dim out As Object = node.Invoke(target, args) Return out End Function Public Iterator Function [Select](Of T, Tout)(source As IEnumerable(Of T), task As [Delegate], args As Object()) As IEnumerable(Of Tout) Dim node As TaskRemote = GetPreferNode() Dim out As ILinq(Of Tout) = node.Select(Of T, Tout)(task, source.ToArray, args) For Each x As Tout In out Yield x Next End Function Public Sub ScanTask() Call RunTask(AddressOf Scan) End Sub End Class End Namespace