#Region "Microsoft.VisualBasic::e60e21b276f0d529eb9cae8b0a40b16b, ComputingServices\Taskhost.d\Invoke\TaskHost.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 TaskRemote ' ' Properties: FileSystem, Key, Load ' ' Constructor: (+2 Overloads) Sub New ' Function: [Select], AsLinq, (+3 Overloads) Invoke, Shell ' ' ' /********************************************************************************/ #End Region Imports Microsoft.VisualBasic.ComponentModel.Collection.Generic Imports Microsoft.VisualBasic.Net Imports Microsoft.VisualBasic.Net.Http Imports Microsoft.VisualBasic.Net.Protocols Imports Microsoft.VisualBasic.Serialization.JSON Imports sciBASIC.ComputingServices.ComponentModel Imports sciBASIC.ComputingServices.FileSystem Namespace TaskHost ''' ''' Using this object to running the method on the remote machine. ''' (由于是远程调用,所以运行的环境可能会很不一样,所以在设计程序的时候请尽量 ''' 避免或者不要使用模块变量,以免出现难以调查的BUG) ''' Public Class TaskRemote : Implements IRemoteSupport Implements INamedValue Dim _remote As IPEndPoint Public ReadOnly Property FileSystem As FileSystemHost Implements IRemoteSupport.FileSystem Private Property Key As String Implements INamedValue.Key Get Return _remote.IPAddress End Get Set(value As String) _remote.IPAddress = value End Set End Property ''' ''' 获取得到远程主机的负载量 ''' ''' Public ReadOnly Property Load As Double Get Dim req As New RequestStream(Protocols.ProtocolEntry, TaskProtocols.NodeLoad) Dim rep = New AsynInvoke(_remote).SendMessage(req, 1000) If rep.Protocol <> HTTP_RFC.RFC_OK Then Return 1000 Else Return rep.LoadObject(Of Double) End If End Get End Property Sub New(remote As IPEndPoint) _remote = remote FileSystem = New FileSystemHost(GetFirstAvailablePort) End Sub Sub New(remote As String, port As Integer) Call Me.New(New IPEndPoint(remote, port)) End Sub ''' ''' Start the application on the remote host.(相当于Sub,调用远程的命令行程序,只会返回0或者错误代码) ''' ''' Exe file path ''' ''' Public Function Shell(exe As String, args As String) As Integer Dim func As Func(Of String, String, Integer) = AddressOf Protocols.Shell Return Invoke(Of Integer)(func, {exe, args}) End Function ''' ''' Running the function delegate pointer on the remote machine. ''' ''' ***************************************************************************************************** ''' NOTE: Performance issue, this is important! if the function pointer its returns type is a collection, ''' then you should using the method to running ''' your code on the remote. Or a large json data will be return back through network in one package, ''' this may cause a serious performance problem both on your server and your local client. ''' (本地服务器通过这个方法调用远程主机上面的函数,假若目标函数的返回值类型是一个集合, ''' 请使用方法,否则集合之中的所有数据都将会一次性返回, ''' 这个可能会导致严重的性能问题) ''' ''' ''' ''' Public Function Invoke(target As [Delegate], ParamArray args As Object()) As Object Dim params As InvokeInfo = InvokeInfo.CreateObject(target, args) Dim rtvl As Rtvl = Invoke(params) Dim obj As Object = rtvl.GetValue(target) Return obj End Function Public Function Invoke(info As InvokeInfo) As Rtvl Dim value As String = JsonContract.GetJson(info) Dim req As RequestStream = New RequestStream(ProtocolEntry, TaskProtocols.Invoke, value) Dim rep As RequestStream = New AsynInvoke(_remote).SendMessage(req) Dim rtvl As Rtvl = JsonContract.LoadObject(Of Rtvl)(rep.GetUTF8String) Return rtvl End Function Public Function Invoke(Of T)(target As [Delegate], ParamArray args As Object()) As T Dim value As Object = Invoke(target, args) If value Is Nothing Then Return Nothing Else Return DirectCast(value, T) End If End Function ''' ''' If your function pointer returns type is a collection, then using this method is recommended. ''' (执行远程机器上面的代码,然后返回数据查询接口) ''' ''' ''' 远程机器上面的函数指针 ''' ''' Public Function AsLinq(Of T)(target As [Delegate], ParamArray args As Object()) As ILinq(Of T) Dim params As InvokeInfo = InvokeInfo.CreateObject(target, args) Dim jparam As String = params.GetJson Dim req As New RequestStream(ProtocolEntry, TaskProtocols.InvokeLinq, jparam) Dim rep As RequestStream = New AsynInvoke(_remote).SendMessage(req) Dim svr As IPEndPoint = rep.GetUTF8String.LoadObject(Of IPEndPoint) Return New ILinq(Of T)(svr) End Function Public Function [Select](Of T, Tout)(target As [Delegate], source As T(), ParamArray args As Object()) As ILinq(Of Tout) Dim params As InvokeInfo = InvokeInfo.CreateObject(target, {CObj(source)}.Join(args)) Dim jparam As String = params.GetJson Dim req As New RequestStream(ProtocolEntry, TaskProtocols.Select, jparam) Dim rep As RequestStream = New AsynInvoke(_remote).SendMessage(req) Dim svr As IPEndPoint = rep.GetUTF8String.LoadObject(Of IPEndPoint) Return New ILinq(Of Tout)(svr) End Function End Class End Namespace