Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customizing and Managing Runspace Names #1384

Merged
merged 8 commits into from
Sep 21, 2024

Conversation

mdaneri
Copy link
Contributor

@mdaneri mdaneri commented Sep 7, 2024

Recovered from Naming Runspaces #1364

Description of the Change

Assign a name to each runspace

Related Issue

#1363

Customizing and Managing Runspace Names

Distinguishing Runspace Names in Pode

In Pode, internal runspaces are automatically assigned distinct names. This naming convention helps in identifying and managing these runspaces efficiently during debugging and monitoring. However, this is not the case for runspaces created by user tasks and schedules (excluding AsyncTask). These user-created runspaces typically have names in the Runspace<number> format, which can make it challenging to distinguish between different runspaces.

Customizing Runspace Names

By default, Pode’s Tasks, Schedules, and Timers use their own names to label their associated runspaces, making it easier to identify them during debugging and monitoring.

However, if you wish to use a different name for the runspace, you can invoke Add-PodeTask, Add-PodeSchedule, or Add-PodeTimer with the -DisableRunspaceNaming parameter.
Then, within the script block, you can use the Set-PodeCurrentRunspaceName cmdlet to assign any custom name you prefer.

Another useful cmdlet is Get-PodeCurrentRunspaceName, which retrieves the current runspace's name. This can be helpful if you need to log or display the runspace name dynamically.

Example

Here is an updated example demonstrating how to set a custom runspace name in a Pode task:

Add-PodeTask -Name 'Test2' -DisableRunspaceNaming -ScriptBlock {
    param($value)
    # Set a custom name for the current runspace
    Set-PodeCurrentRunspaceName -Name 'My Fancy Runspace'
    Start-Sleep -Seconds 10
    "A $($value) is never late, it arrives exactly when it means to" | Out-Default
}

In this example, the Set-PodeCurrentRunspaceName cmdlet is used to assign the custom name 'My Fancy Runspace' to the runspace executing the task, enhancing identification during debugging or in logs.

Retrieving Runspace Names

Another useful cmdlet is Get-PodeCurrentRunspaceName, which retrieves the current runspace's name. This cmdlet can be particularly helpful if you need to log or display the runspace name dynamically during execution. It allows you to track and manage runspaces effectively, especially in complex scenarios where multiple runspaces are running concurrently.

 Add-PodeSchedule -Name 'test' -Cron '@hourly' -ScriptBlock { Write-PodeHost "Runspace name: $(Get-PodeCurrentRunspaceName)" }

@mdaneri mdaneri changed the title Naming Runspaces #1363 Customizing and Managing Runspace Names Sep 8, 2024
@Badgerati
Copy link
Owner

I like the idea of Set-PodeCurrentRunspaceName and Get-PodeCurrentRunspaceName, but I think the initial setting of all Runspace names should be done at the point of Add-PodeRunspace. We can still re-use Set-PodeCurrentRunspaceName, but this will allow use to centralise the setting of the initial Runspace names here, and will let us also standardise on an internal naming structure as well - saves use having to call Set-PodeCurrentRunspaceName everywhere internally when Add-PodeRunspace can do it for us. (or more precisely, Open-PodeRunspace). I'd also say to remove the DisableRunspaceNaming switches, if people want to change the name from the default standardised one - for say their schedule - they can do in their own ScriptBlock via Set-PodeCurrentRunspaceName even if it was already called prior, so I'm not sure what benefit the Disabling switch is adding.

This way, all Pode Runspaces get a default standardised name and if people need/want to set a different name they have that capability available to them as well. I'm happy with the setting of the primary PodeServer runspace name as well :)

I would also be very careful with Timers. The main Timer scheduler runspace will be named, but the runspace rename will change the scheduler runspace name; so the rapid renaming might get confusing, and it would never rename back to the original "scheduler" name so would look like one timer never ended.


I'm thinking the internal naming structure some be something like Pode_<Type>_<Name>_<ID>, where <ID> would be the ThreadId if available or just defaulted to 1. For example:

  • Pode_Web_Listener_1
  • Pode_Signals_Broadcaster_1
  • Pode_Signals_Listener_1
  • Pode_Web_KeepAlive_1
  • Pode_Files_Watcher_1
  • Pode_Main_Logging_1
  • Pode_Timers_Scheduler_1
  • Pode_Schedules_[Schedule Name]_1
  • Pode_Tasks_[Task Name]_1

The Add-PodeRunspace function would need to have a new -Name and -Id = 1 parameters added, as we generate the structured Runspace name near the top:

$rsName = "Pode_$($Type)_$($Name)_$($Id)"

Where Open-PodeRunspace is called would have to change slightly, from:

if (!$NoProfile) {
    $null = $ps.AddScript("Open-PodeRunspace -Type '$($Type)'")
}

to the following, where we pass the Name and NoProfile switch - removing the NoProfile if wrapper:

$null = $ps.AddScript("Open-PodeRunspace -Type '$($Type)' -Name '$($rsName)' -NoProfile:`$$($NoProfile.IsPresent)")

Add then the Open-PodeRunspace would need a -Name and -NoProfile parameters, and be changed to:

try {
    # set runspace name
    Set-PodeCurrentRunspaceName -Name $Name

    if (!$NoProfile) {
        # Importing internal Pode modules necessary for the runspace operations.
        Import-PodeModulesInternal

        # Adding PowerShell drives required by the runspace.
        Add-PodePSDrivesInternal
    }

    # Setting the state of the runspace pool to 'Ready', indicating it is ready to process requests.
    $PodeContext.RunspacePools[$Type].State = 'Ready'
}
catch {
    # ... unchanged ...
}

This would change, for example, the web listener runspace creation to:

1..$PodeContext.Threads.General | ForEach-Object {
    Add-PodeRunspace -Type Web -Name 'Listener' -Id $_ -ScriptBlock $listenScript -Parameters @{ 'Listener' = $listener; 'ThreadId' = $_ }
}

Or for Logging:

Add-PodeRunspace -Type Main -Name 'Logging' -ScriptBlock $script

Or when a Schedule triggers in Invoke-PodeInternalScheduleLogic:

$runspace = Add-PodeRunspace -Type Schedules -Name $Schedule.Name -ScriptBlock $scriptblock -Parameters $parameters -PassThru

@mdaneri
Copy link
Contributor Author

mdaneri commented Sep 18, 2024

I like that.
I was thinking to do something similar but at the end I decided for something less invasive. But I think the way you are suggesting is great.

@mdaneri
Copy link
Contributor Author

mdaneri commented Sep 19, 2024

Done but there is a bug in your last commit bug #1395

src/Private/FileWatchers.ps1 Outdated Show resolved Hide resolved
src/Private/Schedules.ps1 Outdated Show resolved Hide resolved
src/Private/WebSockets.ps1 Outdated Show resolved Hide resolved
docs/Getting-Started/Debug.md Outdated Show resolved Hide resolved
docs/Getting-Started/Debug.md Outdated Show resolved Hide resolved
docs/Getting-Started/Debug.md Outdated Show resolved Hide resolved
docs/Getting-Started/Debug.md Outdated Show resolved Hide resolved
This was linked to issues Sep 21, 2024
@Badgerati Badgerati merged commit 93df876 into Badgerati:develop Sep 21, 2024
16 checks passed
@mdaneri mdaneri deleted the issue-1363 branch September 22, 2024 13:50
@Badgerati Badgerati mentioned this pull request Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Schedule broken in Develop branch Naming Runspaces
2 participants