236c1f5be1
- cambiato formato tempo di esecuzione in statistiche - gestita risposta SubMode 4 in Rest
372 lines
18 KiB
VB.net
372 lines
18 KiB
VB.net
Imports System.IO
|
|
Imports System.Net.Http
|
|
Imports System.Text.Json.Nodes
|
|
Imports System.Windows.Threading
|
|
Imports EgtDotNETBasis
|
|
Imports EgwMultiEngineManager.Core
|
|
Imports EgwMultiEngineManager.Data
|
|
Imports EgwMultiEngineManager.Data.Constants
|
|
Imports Newtonsoft.Json
|
|
Imports RestSharp
|
|
Imports StackExchange.Redis
|
|
|
|
Public Class ExecEnvironmentManager
|
|
Implements IDisposable
|
|
|
|
Public Enum EnvironmentCommunicationTypes As Integer
|
|
NULL = 0
|
|
REDIS = 1
|
|
REST = 2
|
|
End Enum
|
|
|
|
Public Event StatisticUpdate(sGroupName As String, Statistics As Statistics)
|
|
|
|
Private ConstChnName_EgwEngineInput As String = "EgwEngineInput"
|
|
Private ConstChnName_EgwEngineOutput As String = "EgwEngineOutput"
|
|
Private ConstChnName_EgwStatistics As String = "EgwStatistics"
|
|
|
|
Private m_bDevMode As Boolean = False
|
|
Private ConstChnName_EgwDevEngineInput As String = "EgwDevEngineInput"
|
|
Private ConstChnName_EgwDevEngineOutput As String = "EgwDevEngineOutput"
|
|
Private ConstChnName_EgwDevStatistics As String = "EgwDevStatistics"
|
|
|
|
Private disposedValue As Boolean
|
|
|
|
Private m_nRequestCounter As Integer = 0
|
|
Private ReadOnly Property nRequestCounter As Integer
|
|
Get
|
|
m_nRequestCounter += 1
|
|
Return m_nRequestCounter
|
|
End Get
|
|
End Property
|
|
|
|
Private m_RestTimer As New DispatcherTimer
|
|
Friend ReadOnly Property RestTimer As DispatcherTimer
|
|
Get
|
|
Return m_RestTimer
|
|
End Get
|
|
End Property
|
|
|
|
Private m_EnvironmentCommunicationType As EnvironmentCommunicationTypes
|
|
|
|
Private m_ExecEnvironment As EXECENVIRONMENTS = EXECENVIRONMENTS.NULL
|
|
Friend ReadOnly Property ExecEnvironment As EXECENVIRONMENTS
|
|
Get
|
|
Return m_ExecEnvironment
|
|
End Get
|
|
End Property
|
|
|
|
Private m_sGroupName As String = String.Empty
|
|
Friend ReadOnly Property GroupName As String
|
|
Get
|
|
Return m_sGroupName
|
|
End Get
|
|
End Property
|
|
|
|
Private Shared m_RedisManager As RedisManager
|
|
Friend Shared Sub SetRedisManager(RedisManager As RedisManager)
|
|
m_RedisManager = RedisManager
|
|
End Sub
|
|
|
|
Friend ReadOnly Property ChnName_EgwEngineInput As String
|
|
Get
|
|
Return If(m_bDevMode, ConstChnName_EgwDevEngineInput, ConstChnName_EgwEngineInput)
|
|
End Get
|
|
End Property
|
|
|
|
Friend ReadOnly Property ChnName_EgwEngineOutput As String
|
|
Get
|
|
Return If(m_bDevMode, ConstChnName_EgwDevEngineOutput, ConstChnName_EgwEngineOutput)
|
|
End Get
|
|
End Property
|
|
|
|
Friend ReadOnly Property ChnName_EgwStatistics As String
|
|
Get
|
|
Return If(m_bDevMode, ConstChnName_EgwDevStatistics, ConstChnName_EgwStatistics)
|
|
End Get
|
|
End Property
|
|
|
|
Private m_bChannelFromAnswer As Boolean = False
|
|
|
|
Private m_ExecProcessManager As ExecProcessManager
|
|
Public ReadOnly Property ExecProcessManager As ExecProcessManager
|
|
Get
|
|
Return m_ExecProcessManager
|
|
End Get
|
|
End Property
|
|
|
|
Private m_Client As RestClient
|
|
Friend ReadOnly Property Client As RestClient
|
|
Get
|
|
Return m_Client
|
|
End Get
|
|
End Property
|
|
|
|
Private m_chnEgwEngineOutput As RedisChannel
|
|
Private m_chnEgwEngineInput As RedisChannel
|
|
Private m_chnEgwStatistics As RedisChannel
|
|
|
|
' statistics
|
|
Private m_stopWatch As New Stopwatch()
|
|
Private m_dMinProcessingTime As Double = 0
|
|
Private m_dMidProcessingTime As Double = 0
|
|
Private m_dMaxProcessingTime As Double = 0
|
|
Private m_nProcessingQty As Integer = 0
|
|
|
|
Friend Shared Function CreateExecEnvironmentManager(nType As EnvironmentCommunicationTypes, nGroupIndex As Integer, ByRef NewExecEnvironmentManager As ExecEnvironmentManager) As Boolean
|
|
Dim sConnection As String = "localhost"
|
|
GetMainPrivateProfileString(S_GENERAL, K_REDISCONNECTION, "", sConnection)
|
|
Dim sCamExePath As String = ""
|
|
GetMainPrivateProfileString(S_GENERAL, K_CAMEXEPATH, "", sCamExePath)
|
|
Dim sPipeLuaDirName As String = ""
|
|
GetMainPrivateProfileString(S_GENERAL, K_PIPELUADIRNAME, "", sPipeLuaDirName)
|
|
Dim sEnvironment As String = ""
|
|
Dim sPipeLuaFile As String = ""
|
|
Dim nMaxCamInstances As Integer = 0
|
|
Dim bDebug As Boolean = False
|
|
Dim sGroupName As String = If(nType = EnvironmentCommunicationTypes.REST, S_RESTEXECGROUP, S_EXECGROUP) & nGroupIndex.ToString()
|
|
If GetMainPrivateProfileString(sGroupName, K_ENVIRONMENT, "", sEnvironment) > 0 AndAlso
|
|
GetMainPrivateProfileString(sGroupName, K_PIPELUAFILE, "", sPipeLuaFile) AndAlso
|
|
GetMainPrivateProfileString(sGroupName, K_MAXCAMINSTANCES, "", nMaxCamInstances) Then
|
|
EgtOutLog(If(nType = EnvironmentCommunicationTypes.REST, "REST", "") & "Group" & nGroupIndex.ToString())
|
|
EgtOutLog("Environment = " & sEnvironment)
|
|
EgtOutLog("PipeLuaFile = " & sPipeLuaFile)
|
|
EgtOutLog("MaxCAMInstances = " & nMaxCamInstances)
|
|
If nMaxCamInstances <= 0 Then
|
|
EgtOutLog("No Cam instances assigned!")
|
|
EgtOutLog(String.Format(sGroupName & " will not be created!"))
|
|
nGroupIndex += 1
|
|
Return True
|
|
End If
|
|
Dim ExecEnvironment As EXECENVIRONMENTS = GetExecEnvironmentFromString(sEnvironment)
|
|
If ExecEnvironment = EXECENVIRONMENTS.NULL Then
|
|
EgtOutLog("No ExecEnvironment assigned!")
|
|
EgtOutLog(String.Format(sGroupName & " will not be created!"))
|
|
nGroupIndex += 1
|
|
Return True
|
|
End If
|
|
Dim sPipeLuaPath As String = Map.refMainWindowVM.sDataRoot & "\" & sPipeLuaDirName & "\" & sPipeLuaFile
|
|
If Not File.Exists(sPipeLuaPath) Then
|
|
EgtOutLog("Lua file not assigned or not found!")
|
|
EgtOutLog(String.Format(sGroupName & " will not be created!"))
|
|
nGroupIndex += 1
|
|
Return True
|
|
End If
|
|
Dim sProcessArguments As String = """" & sPipeLuaPath & """ " & """" & sConnection & """"
|
|
' leggo se modalita' debug
|
|
Dim nDebug As Integer = GetMainPrivateProfileInt(sGroupName, K_DEBUG, 0)
|
|
bDebug = (nDebug = 1)
|
|
NewExecEnvironmentManager = New ExecEnvironmentManager(nType, sGroupName, ExecEnvironment, nGroupIndex, sCamExePath, sProcessArguments, nMaxCamInstances, ExecProcessManager.ReturnModes.EVENT_, bDebug)
|
|
EgtOutLog(String.Format(sGroupName & " created"))
|
|
Return True
|
|
Else
|
|
Return False
|
|
End If
|
|
End Function
|
|
|
|
Sub New(nType As EnvironmentCommunicationTypes, sGroupName As String, nEnvironment As EXECENVIRONMENTS, nGroupId As Integer, sProcessFileName As String, sProcessArguments As String, nMaxCamInstances As Integer, bReturnMode As ExecProcessManager.ReturnModes, bDebug As Boolean)
|
|
m_EnvironmentCommunicationType = nType
|
|
m_sGroupName = sGroupName
|
|
Select Case m_EnvironmentCommunicationType
|
|
Case EnvironmentCommunicationTypes.REDIS
|
|
m_ExecEnvironment = nEnvironment
|
|
m_ExecProcessManager = New ExecProcessManager(nGroupId, nEnvironment, sProcessFileName, sProcessArguments, nMaxCamInstances, ExecProcessManager.ReturnModes.EVENT_, bDebug)
|
|
AddHandler m_ExecProcessManager.m_AnswerReceived, AddressOf ExecProcessManager_AnswerReceived
|
|
AddHandler m_ExecProcessManager.m_Statistics, AddressOf ExecProcessManager_Statistics
|
|
m_ExecProcessManager.StartExecutionThread()
|
|
' leggo canali input/output
|
|
Dim sIniGroup As String = S_EXECGROUP & nGroupId.ToString()
|
|
m_bChannelFromAnswer = (GetMainPrivateProfileInt(sIniGroup, K_CHANNELFROMANSWER, 0) = 1)
|
|
Dim sInputChannelName As String = ""
|
|
GetMainPrivateProfileString(sIniGroup, K_INPUTCHANNEL, "Egw%%EngineInput", sInputChannelName)
|
|
ConstChnName_EgwEngineInput = sInputChannelName.Replace("%%", "").Replace("@@", "")
|
|
ConstChnName_EgwDevEngineInput = sInputChannelName.Replace("%%", "Dev").Replace("@@", "")
|
|
Dim sOutputChannelName As String = ""
|
|
GetMainPrivateProfileString(sIniGroup, K_OUTPUTCHANNEL, "Egw%%EngineOutput", sOutputChannelName)
|
|
ConstChnName_EgwEngineOutput = sOutputChannelName.Replace("%%", "").Replace("@@", "")
|
|
ConstChnName_EgwDevEngineOutput = sOutputChannelName.Replace("%%", "Dev").Replace("@@", "")
|
|
Dim sStatisticsChannelName As String = ""
|
|
GetMainPrivateProfileString(sIniGroup, K_STATISTICSCHANNEL, "Egw%%Statistics@@", sStatisticsChannelName)
|
|
Dim sIpAddress As String = ":" & GetPcData.GetIPAddress().ToString
|
|
ConstChnName_EgwStatistics = sStatisticsChannelName.Replace("%%", "").Replace("@@", sIpAddress)
|
|
ConstChnName_EgwDevStatistics = sStatisticsChannelName.Replace("%%", "Dev").Replace("@@", sIpAddress)
|
|
m_chnEgwEngineOutput = New RedisChannel(ChnName_EgwEngineOutput, RedisChannel.PatternMode.Auto)
|
|
m_chnEgwEngineInput = New RedisChannel(ChnName_EgwEngineInput, RedisChannel.PatternMode.Auto)
|
|
m_chnEgwStatistics = New RedisChannel(ChnName_EgwStatistics, RedisChannel.PatternMode.Auto)
|
|
m_RedisManager.SubscribeChannel(m_chnEgwEngineInput, AddressOf EgwEngineInputHandler)
|
|
Case EnvironmentCommunicationTypes.REST
|
|
m_ExecEnvironment = nEnvironment
|
|
m_ExecProcessManager = New ExecProcessManager(nGroupId + 1000, nEnvironment, sProcessFileName, sProcessArguments, nMaxCamInstances, ExecProcessManager.ReturnModes.EVENT_, bDebug)
|
|
m_chnEgwStatistics = New RedisChannel(ChnName_EgwStatistics, RedisChannel.PatternMode.Auto)
|
|
AddHandler m_ExecProcessManager.m_AnswerReceived, AddressOf ExecProcessManager_AnswerReceived
|
|
AddHandler m_ExecProcessManager.m_Statistics, AddressOf ExecProcessManager_Statistics
|
|
m_ExecProcessManager.StartExecutionThread()
|
|
'm_Client = New RestClient("https://office.egalware.com/lux/srv/api")
|
|
m_Client = New RestClient("https://iis01.egalware.com/lux/srv/api")
|
|
m_RestTimer.Interval = TimeSpan.FromMilliseconds(1000)
|
|
AddHandler m_RestTimer.Tick, AddressOf RestTimer_Tick
|
|
m_RestTimer.Start()
|
|
'RestTimer_Tick(Nothing, Nothing)
|
|
End Select
|
|
End Sub
|
|
|
|
Friend Shared Function GetExecEnvironmentFromString(sEnvironment As String) As EXECENVIRONMENTS
|
|
Select Case sEnvironment
|
|
Case "WINDOW"
|
|
Return EXECENVIRONMENTS.WINDOW
|
|
Case "BEAM"
|
|
Return EXECENVIRONMENTS.BEAM
|
|
Case "WALL"
|
|
Return EXECENVIRONMENTS.WALL
|
|
Case "CABINET"
|
|
Return EXECENVIRONMENTS.CABINET
|
|
Case Else
|
|
Return EXECENVIRONMENTS.NULL
|
|
End Select
|
|
End Function
|
|
|
|
Private Async Sub RestTimer_Tick(sender As Object, e As EventArgs)
|
|
Dim nProcessedQuestion As Integer = 0
|
|
While m_ExecProcessManager.nFreeProcesses > 0 And m_ExecProcessManager.ArgumentsQueueCount < m_ExecProcessManager.nFreeProcesses And nProcessedQuestion < m_ExecProcessManager.nRunningProcesses
|
|
Dim request As New RestRequest("Prod/getnext", Method.Get)
|
|
Dim response = Await m_Client.ExecuteAsync(request)
|
|
If response.StatusCode = Net.HttpStatusCode.OK Then
|
|
m_stopWatch.Restart()
|
|
Dim Question As QuestionDTO = JsonConvert.DeserializeObject(Of QuestionDTO)(response.Content)
|
|
If Not IsNothing(Question) AndAlso Question.ExecEnvironment = m_ExecEnvironment Then
|
|
Question.SetId(nRequestCounter)
|
|
EgtOutLog(DateTime.Now.ToString("HH:mm:ss.fff") & " Environment=" & m_ExecEnvironment & " Channel=REST Question Id=" & Question.nId)
|
|
m_ExecProcessManager.ArgumentsEnqueue(Question)
|
|
nProcessedQuestion += 1
|
|
Else
|
|
EgtOutLog(DateTime.Now.ToString("HH:mm:ss.fff") & "Errore! Environment=" & m_ExecEnvironment & " Channel=REST Content=" & response.Content)
|
|
End If
|
|
Else
|
|
' se non ci sono domande, esco
|
|
Return
|
|
End If
|
|
End While
|
|
End Sub
|
|
|
|
Private Sub EgwEngineInputHandler(RedisChannel As RedisChannel, RedisValue As RedisValue)
|
|
m_stopWatch.Restart()
|
|
Dim Question As QuestionDTO = JsonConvert.DeserializeObject(Of QuestionDTO)(RedisValue)
|
|
If Question.ExecEnvironment = m_ExecEnvironment Then
|
|
Question.SetId(nRequestCounter)
|
|
EgtOutLog(DateTime.Now.ToString("HH:mm:ss.fff") & " Environment=" & m_ExecEnvironment & " Channel=" & RedisChannel.ToString() & " Question Id=" & Question.nId)
|
|
m_ExecProcessManager.ArgumentsEnqueue(Question)
|
|
End If
|
|
End Sub
|
|
|
|
Private Sub ExecProcessManager_AnswerReceived(Answer As AnswerDTO)
|
|
Select Case m_EnvironmentCommunicationType
|
|
Case EnvironmentCommunicationTypes.REDIS
|
|
Dim chnEgwEngineOutput As RedisChannel = m_chnEgwEngineOutput
|
|
If m_bChannelFromAnswer AndAlso Answer.Args.ContainsKey("OutputChannel") Then
|
|
Dim ChnName_Output As String = Answer.Args("OutputChannel")
|
|
If Not String.IsNullOrWhiteSpace(ChnName_Output) Then
|
|
chnEgwEngineOutput = New RedisChannel(ChnName_Output, RedisChannel.PatternMode.Auto)
|
|
End If
|
|
End If
|
|
EgtOutLog(DateTime.Now.ToString("HH:mm:ss.fff") & " Environment=" & m_ExecEnvironment & " Channel=" & chnEgwEngineOutput.ToString() & " Answer Id=" & Answer.nId)
|
|
m_RedisManager.Publish(chnEgwEngineOutput, JsonConvert.SerializeObject(Answer))
|
|
m_stopWatch.Stop()
|
|
' Format and display the TimeSpan value.
|
|
Dim elapsedTime As String = String.Format("{0:N3}", m_stopWatch.Elapsed.TotalMilliseconds)
|
|
m_nProcessingQty += 1
|
|
If m_dMinProcessingTime = 0 OrElse m_stopWatch.Elapsed.TotalMilliseconds < m_dMinProcessingTime Then m_dMinProcessingTime = m_stopWatch.Elapsed.TotalMilliseconds
|
|
If m_nProcessingQty > 1 Then
|
|
m_dMidProcessingTime = ((m_dMidProcessingTime * (m_nProcessingQty - 1)) / m_nProcessingQty) + (m_stopWatch.Elapsed.TotalMilliseconds / m_nProcessingQty)
|
|
Else
|
|
m_dMidProcessingTime = m_stopWatch.Elapsed.TotalMilliseconds
|
|
End If
|
|
If m_stopWatch.Elapsed.TotalMilliseconds > m_dMaxProcessingTime Then m_dMaxProcessingTime = m_stopWatch.Elapsed.TotalMilliseconds
|
|
EgtOutLog("Answer " & Answer.nId & " calculated in " & elapsedTime & "ms")
|
|
Case EnvironmentCommunicationTypes.REST
|
|
If Answer.Args.ContainsKey("Mode") AndAlso Answer.Args.ContainsKey("SubMode") Then
|
|
Dim request As RestRequest = Nothing
|
|
Dim nMode As Integer = Answer.Args("Mode")
|
|
Dim nSubMode As Integer = Answer.Args("SubMode")
|
|
Select Case nMode
|
|
Case 5
|
|
Select Case nSubMode
|
|
Case 1
|
|
request = New RestRequest("Prod/jobreturn", Method.Post)
|
|
Case 2
|
|
request = New RestRequest("Prod/jobreturn", Method.Post)
|
|
Case 3
|
|
request = New RestRequest("Prod/jobreturn", Method.Post)
|
|
Case 4
|
|
request = New RestRequest("Prod/jobreturn", Method.Post)
|
|
End Select
|
|
End Select
|
|
'request.AddBody(JsonConvert.SerializeObject(Answer))
|
|
request.AddStringBody(JsonConvert.SerializeObject(Answer), DataFormat.Json)
|
|
EgtOutLog(DateTime.Now.ToString("HH:mm:ss.fff") & " Environment=" & m_ExecEnvironment & " Channel=REST Answer Id=" & Answer.nId)
|
|
' Eseguo la chiamata
|
|
Dim response As RestResponse = Client.Execute(request)
|
|
' Controllo l'esito
|
|
If response.IsSuccessful Then
|
|
EgtOutLog("Answer Id=" & Answer.nId & "inviata con successo!")
|
|
Else
|
|
EgtOutLog("Errore! Answer Id=" & Answer.nId & " Description=" & response.StatusDescription)
|
|
End If
|
|
Else
|
|
EgtOutLog("Errore! Risposta senza Mode o SubMode!")
|
|
End If
|
|
m_stopWatch.Stop()
|
|
' Format and display the TimeSpan value.
|
|
Dim elapsedTime As String = String.Format("{0:N3}", m_stopWatch.Elapsed.TotalMilliseconds)
|
|
m_nProcessingQty += 1
|
|
If m_dMinProcessingTime = 0 OrElse m_stopWatch.Elapsed.TotalMilliseconds < m_dMinProcessingTime Then m_dMinProcessingTime = m_stopWatch.Elapsed.TotalMilliseconds
|
|
If m_nProcessingQty > 1 Then
|
|
m_dMidProcessingTime = ((m_dMidProcessingTime * (m_nProcessingQty - 1)) / m_nProcessingQty) + (m_stopWatch.Elapsed.TotalMilliseconds / m_nProcessingQty)
|
|
Else
|
|
m_dMidProcessingTime = m_stopWatch.Elapsed.TotalMilliseconds
|
|
End If
|
|
If m_stopWatch.Elapsed.TotalMilliseconds > m_dMaxProcessingTime Then m_dMaxProcessingTime = m_stopWatch.Elapsed.TotalMilliseconds
|
|
EgtOutLog("Answer " & Answer.nId & " calculated in " & elapsedTime & "ms")
|
|
End Select
|
|
End Sub
|
|
|
|
Private Sub ExecProcessManager_Statistics(e As Statistics)
|
|
Dim CurrManagerStatistics As Statistics = e
|
|
CurrManagerStatistics.SetProcessingTimes(m_dMinProcessingTime, m_dMidProcessingTime, m_dMaxProcessingTime)
|
|
RaiseEvent StatisticUpdate(m_sGroupName, CurrManagerStatistics)
|
|
If Not IsNothing(m_chnEgwStatistics) Then
|
|
m_RedisManager.Publish(m_chnEgwStatistics, JsonConvert.SerializeObject(CurrManagerStatistics))
|
|
End If
|
|
m_nProcessingQty = 0
|
|
m_dMinProcessingTime = 100000
|
|
m_dMidProcessingTime = 0
|
|
m_dMaxProcessingTime = 0
|
|
End Sub
|
|
|
|
Protected Overridable Sub Dispose(disposing As Boolean)
|
|
If Not disposedValue Then
|
|
If disposing Then
|
|
' TODO: dispose managed state (managed objects)
|
|
End If
|
|
|
|
' TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
|
' TODO: set large fields to null
|
|
m_ExecProcessManager.Dispose()
|
|
disposedValue = True
|
|
End If
|
|
End Sub
|
|
|
|
' ' TODO: override finalizer only if 'Dispose(disposing As Boolean)' has code to free unmanaged resources
|
|
' Protected Overrides Sub Finalize()
|
|
' ' Do not change this code. Put cleanup code in 'Dispose(disposing As Boolean)' method
|
|
' Dispose(disposing:=False)
|
|
' MyBase.Finalize()
|
|
' End Sub
|
|
|
|
Public Sub Dispose() Implements IDisposable.Dispose
|
|
' Do not change this code. Put cleanup code in 'Dispose(disposing As Boolean)' method
|
|
Dispose(disposing:=True)
|
|
GC.SuppressFinalize(Me)
|
|
End Sub
|
|
|
|
End Class
|