erl.posh | NEW-PROCESS

#"PROCESS" -> EVENT REGISTRATION + PSSESSION + MESSAGE BOX (QUEUE)
#"MESSAGE" -> RAISED EVENT
#"CORE SYSTEM" -> STORE ALL PROCESS ID ?


FUNCTION NEW-PROCESS{
    PARAM(
        $PSS_JOB_DEF = {
            PARAM(
                $EVENT
            )
            Write-Host "===============================" -ForegroundColor Yellow;  
            Write-Host ($Event | FT -AutoSize | Out-String);
            Write-Host "===============================" -ForegroundColor Yellow;
        }
        , $NODE = "LOCALHOST"
        , $INIT_ACTION = {
            $this = $Event.Sender.value
            Write-Host "PROCESSING INIT_ACTION... ($($this.PID))" -ForegroundColor Yellow
            IF(($this.PSS.STATE -EQ "Opened") -AND ($this.PSS.Availability -eq "Available")){
                Write-Host "INIT_ACTION INVOKING NOW... ($($this.PID))" -ForegroundColor Yellow
                $this.CURRENT_JOB = Invoke-Command -Session $this.PSS -AsJob -ScriptBlock $this.PSS_JOB_DEF -ArgumentList $Event
                $ROEID = [GUID]::NewGuid().ToString()
                $ROE = Register-ObjectEvent -InputObject $this.CURRENT_JOB -EventName StateChanged -Action $(
                    [scriptblock]::Create("
                        `$this = `$EVENT.MessageData
                        `$this.CURRENT_JOB_RECEIVED = `$false
                        `$this.RECEIVE_JOB()
                        `$this.CURRENT_JOB_RECEIVED = `$true
                        Get-EventSubscriber -SourceIdentifier $ROEID | Unregister-Event")
                ) -MessageData $this -SourceIdentifier $ROEID 
            } ELSE {
                Write-Host "INIT_ACTION BUSY NOW, QUEUEING... ($($this.PID))" -ForegroundColor Yellow
                $this.Q.Enqueue($Event)
            }
        }
        , $START_NOW = $true
        , $GESEV      
    )
    $PROCID = [GUID]::NewGuid().ToString()
    $ES = Get-EventSubscriber -SourceIdentifier $PROCID -ErrorVariable GESEV -ErrorAction SilentlyContinue
    $ES | Unregister-Event -ErrorAction SilentlyContinue
    
    New-Module -AsCustomObject -OutVariable NM -ScriptBlock {
        PARAM(
            $PROCID
            , $NODE
            , $PSS_JOB_DEF
            , $INIT_ACTION
        )
        $REE = $null
        $RECURSING_PROCESS = $null
        $RECURSING_PROCESS_STAGING = $null
        $PID = $PROCID
        $Q = New-Object collections.queue
        $PSS = New-PSSession -ComputerName $NODE -ErrorAction Stop -Name $PID
        $CURRENT_JOB = $null
        $CURRENT_JOB_RESULT = $null
        $CURRENT_JOB_RECEIVED = $false
        $PSS_JOB_DEF_CHANGED = $false
        $PSS_JOB_DEF_IN_CHANGING = $false
        $PSS_JOB_DEF_NEXT = $null
        $MSG_NEXT = $null
        $INVOKING_JOB = $false

        FUNCTION SUPER{
            return $this
        }
                
        FUNCTION START_PROC{
            Write-Host "STARTING PROCESS $PROCID" -ForegroundColor Yellow
            Invoke-Command -Session $this.PSS -ScriptBlock {
                Register-EngineEvent -SourceIdentifier PARENT_PROC -Forward
            } -ArgumentList $PROCID

            #LISTEN TO MSG TO PSS
            $this.REE = Register-EngineEvent -SourceIdentifier $this.PID -Action $this.INIT_ACTION
            $this.RECURSING_PROCESS = Register-ObjectEvent -InputObject $this.PSS.Runspace -EventName AvailabilityChanged -Action {
                $this = $EVENT.MessageData
                Write-Host "PROCESS STATE CHANGED... ($($this.PID))" -ForegroundColor Yellow
                IF(($this.PSS.STATE -EQ "Opened") -AND ($this.PSS.Availability -eq "Available")){
                    Write-Host "PROCESS OPENED AND AVAILABLE NOW... ($($this.PID))" -ForegroundColor Yellow
                    IF($this.PSS_JOB_DEF_IN_CHANGING){
                        Write-Host "PROCESS JOB DEF CHANGING NOW... ($($this.PID))" -ForegroundColor Yellow
                    } ELSE {
                        if($this.PSS_JOB_DEF_CHANGED){
                            $this.CHANGE_JOBDEF()
                        } else {
                            Write-Host "PROCESS STARTING TO DEQUEUE NOW... ($($this.PID))" -ForegroundColor Yellow
                            if($this.Q.Count -ne 0){
                                Write-Host "DEQUEUE AND PROCESSING NOW... ($($this.PID))" -ForegroundColor Yellow
                                $event_obj_dequeued = $this.Q.Dequeue()
                                $this.CURRENT_JOB = Invoke-Command -Session $this.PSS -AsJob -ScriptBlock $this.PSS_JOB_DEF -ArgumentList $event_obj_dequeued
                                $ROEID = [GUID]::NewGuid().ToString()
                                $ROE = Register-ObjectEvent -InputObject $this.CURRENT_JOB -EventName StateChanged -Action $(
                                    [scriptblock]::Create("
                                        `$this = `$EVENT.MessageData
                                        `$this.CURRENT_JOB_RECEIVED = `$false
                                        `$this.RECEIVE_JOB()
                                        `$this.CURRENT_JOB_RECEIVED = `$true
                                        Get-EventSubscriber -SourceIdentifier $ROEID | Unregister-Event")
                                ) -MessageData $this -SourceIdentifier $ROEID 
                            } else {
                                Write-Host "NO ITEM TO DEQUEUE... ($($this.PID))" -ForegroundColor Yellow
                            }
                        }
                    }
                } ELSE {
                    Write-Host "PROCESS NOT AVAILABLE NOW... ($($this.PID))" -ForegroundColor Yellow
                }
            } -MessageData $this
        }

        FUNCTION DISPOSE_PROC{
            Write-Host "DISPOSING PROCESS $PROCID" -ForegroundColor Yellow
            Get-EventSubscriber -SourceIdentifier $this.PID | Unregister-Event
        }

        FUNCTION SEND_MSG{
            PARAM(
                $MSG
                , [SCRIPTBLOCK] $AD_HOC_PSS_JOB_DEF = {}
            )
            IF($AD_HOC_PSS_JOB_DEF.ToString() -NE ""){
                $this.PSS_JOB_DEF_CHANGED = $true
                $this.PSS_JOB_DEF_NEXT = $AD_HOC_PSS_JOB_DEF
                $this.MSG_NEXT = $MSG
                IF(($this.PSS.STATE -EQ "Opened") -AND ($this.PSS.Availability -eq "Available")){
                    $this.CHANGE_JOBDEF()
                }
            } ELSE {
                $NE = New-Event -SourceIdentifier $this.PID -Sender ([ref] $this) -MessageData $MSG
            }
        }

        FUNCTION QUEUE_MSG{
            PARAM(
                $MSG
                , [SCRIPTBLOCK] $AD_HOC_PSS_JOB_DEF = {}
            )
        }

        FUNCTION CHANGE_JOBDEF{
            Write-Host "PROCESS JOB DEF START TO CHANGE NOW... ($($this.PID))" -ForegroundColor Yellow
            $this.PSS_JOB_DEF_IN_CHANGING = $true
            $this.Q.Clear();
            $this.PSS_JOB_DEF = $this.PSS_JOB_DEF_NEXT
            $this.PSS_JOB_DEF_NEXT = $null
            $this.PSS_JOB_DEF_CHANGED = $false
            $this.PSS_JOB_DEF_IN_CHANGING = $false
            $NE = New-Event -SourceIdentifier $this.PID -Sender ([ref] $this) -MessageData $this.MSG_NEXT
            $this.CURRENT_JOB_RECEIVED = $false
            $this.MSG_NEXT = $null
        }

        FUNCTION RECEIVE_JOB{
            IF($this.REE.State -ne "NotStarted"){
                WHILE($this.CURRENT_JOB -EQ $null){
                    Start-Sleep -Milliseconds 50
                    IF($TIMEOUT++ -EQ 99){BREAK}
                }
                IF($TIMEOUT -GE 99){THROW "NULL CURRENT_JOB"}
                IF(!$this.CURRENT_JOB_RECEIVED){
                    $WJ = $this.CURRENT_JOB | Wait-Job
                    Write-Host "RECEIVING JOB NOW... ($($this.PID))" -ForegroundColor Yellow
                    $this.CURRENT_JOB_RESULT = $($this.CURRENT_JOB | Receive-Job)
                    $this.CURRENT_JOB_RECEIVED = $true
                }                
                return $this.CURRENT_JOB_RESULT
            } else {$null}            
        }

        $VAR = @("REE", "PID", "Q", "PSS", "RECURSING_PROCESS", "PSS_JOB_DEF", "INIT_ACTION", "CURRENT_JOB", "PSS_JOB_DEF_CHANGED",
            "PSS_JOB_DEF_NEXT", "MSG_NEXT", "PSS_JOB_DEF_IN_CHANGING", "RECURSING_PROCESS_STAGING", "CURRENT_JOB_RESULT",
            "CURRENT_JOB_RECEIVED")
        $FUNC = @("START_PROC", "STOP_PROC", "DISPOSE_PROC", "SEND_MSG", "QUEUE_MSG", "SUPER", "CHANGE_JOBDEF", "RECEIVE_JOB")

        Export-ModuleMember -Function $FUNC -Variable $VAR
    } -ArgumentList $PROCID, $NODE, $PSS_JOB_DEF, $INIT_ACTION

    IF($START_NOW){$NM.START_PROC()}
}
<#
$P = NEW-PROCESS

$P.SEND_MSG("123", {Start-Sleep 10})
$P.SEND_MSG("1234", {Start-Sleep 11})
#>
<#
$Y = NEW-PROCESS -PSS_JOB_DEF {PARAM($EVENT) DIR $EVENT.MESSAGEDATA["DRIVE"]}
$Y.SEND_MSG(@{DRIVE = "C:\"},{})

$Y.RECEIVE_JOB()
BREAK
#>
$Y = NEW-PROCESS -PSS_JOB_DEF {Import-Module SQLDATA -Force -DisableNameChecking}
$Y.SEND_MSG($NULL,{})


$Y.SEND_MSG($NULL,{. "C:\Users\ANIBAL\Documents\WindowsPowerShell\Modules\POSHLS\globalfunc.ps1"})
$Y.SEND_MSG($NULL,{. invokeLSparam -configID 1; $S2D})

#$P.PSS.Availability
#$P.CURRENT_JOB
#Get-PSSession | Remove-PSSession
#New-Event -SourceIdentifier $P.PID -Sender ([ref] $P) -EventArguments ([ref] $P) -MessageData "MD"

BREAK
Get-EventSubscriber | Unregister-Event



Get-EventSubscriber | Unregister-Event

Register-EngineEvent -SourceIdentifier TTC4 -Action {
Write-Host (Get-Variable | FT -AutoSize | Out-String); 
Write-Host "===============================" -ForegroundColor Yellow; 
Write-Host ($args | FT -AutoSize | Out-String);
Write-Host "===============================" -ForegroundColor Yellow;  
Write-Host ($Event | FT -AutoSize | Out-String);
Write-Host "===============================" -ForegroundColor Yellow;  
Write-Host ($EventArgs | FT -AutoSize | Out-String) 
Write-Host "===============================" -ForegroundColor Yellow;  
Write-Host ($eventSubscriber | FT -AutoSize | Out-String) }

$N = New-Event -SourceIdentifier ttc4 -Sender "sender11" -MessageData "msgdt", "GG" -EventArguments "ea", "OO"

$N
Comments