Skip to content

Conversation

@mdaneri
Copy link
Contributor

@mdaneri mdaneri commented Feb 3, 2025

Description:

This PR introduces thread-safe shared state management in Pode, allowing developers to use more robust concurrent data structures without requiring explicit locking. Previously, Lock-PodeObject was mandatory for shared state variables, which could lead to performance bottlenecks and unnecessary complexity. With this update, Pode now supports natively thread-safe collections, reducing the risk of race conditions and improving overall execution efficiency.

This update is fully backward compatible. All existing Pode implementations will continue to work as expected without requiring any modifications.


Why This Is Needed:

  • Improves Performance: Eliminates unnecessary locking for inherently thread-safe structures, reducing execution overhead.
  • Enhances Stability: Prevents potential race conditions when accessing shared state across multiple runspaces.
  • Expands Usability: Supports modern concurrent data structures like ConcurrentDictionary, ConcurrentBag, and more.
  • Clarifies Best Practices: Distinguishes between thread-safe and non-thread-safe objects, helping developers write more efficient and error-free code.
  • Fully Backward Compatible: Ensures all existing Pode scripts and applications will continue to function without changes.

Key Features & Changes:

  • Added Support for Thread-Safe Structures

    • ConcurrentDictionary
    • ConcurrentBag
    • ConcurrentQueue
    • ConcurrentStack
  • Added the Set-PodeState -NewCollectionType parameter
    That allows users to specify the type of collection to initialize within the shared state. This eliminates the need to manually instantiate collections before setting them in the state.

  • Explicit Handling for Non-Thread-Safe Structures

    • Hashtable, OrderedDictionary, and PSCustomObject now explicitly require Lock-PodeObject for safe multi-threaded access.
  • Fully Backward Compatible

    • Existing Pode codebases that use Lock-PodeObject will continue to work without modification.
    • No breaking changes—this update only adds optional thread-safe functionality.
  • Updated Documentation & Examples

    • Clear examples demonstrating correct usage for both thread-safe and non-thread-safe objects.

Example Usage:

Thread-Safe (No Locking Required)

Start-PodeServer {
    Add-PodeTimer -Name 'update-data' -Interval 5 -ScriptBlock {
    Set-PodeState -Name 'data' -NewCollectionType 'ConcurrentDictionary'
    # Equivalent to :  Set-PodeState -Name 'data' -Value ([System.Collections.Concurrent.ConcurrentDictionary[string, string]]::new([System.StringComparer]::OrdinalIgnoreCase)) | Out-Null
    $data.Name = 'Rick Sanchez' 
    }
}

Non-Thread-Safe (Locking Required)

Start-PodeServer {
    Add-PodeTimer -Name 'update-data' -Interval 5 -ScriptBlock {
        Lock-PodeObject -ScriptBlock {
            Set-PodeState -Name 'data' -Value @{ 'Name' = 'Rick Sanchez' } | Out-Null
        }
    }
}

Impact & Considerations:

  • Backward Compatible: All existing Pode code continues to work without requiring any changes.
  • Performance Gains: Reduces unnecessary locking overhead for thread-safe structures.
  • Improved Developer Experience: Simplifies working with shared state by leveraging built-in concurrency mechanisms.

Looking for Feedback On:

  • Are there any additional concurrency scenarios that should be covered?
  • Any edge cases or concerns around backward compatibility?

PR Link: #1474

@Badgerati Badgerati added the priority: high Target for next release or soon after. A priority but not critical label Feb 22, 2025
This was referenced Mar 2, 2025
@mdaneri mdaneri mentioned this pull request Mar 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: high Target for next release or soon after. A priority but not critical

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants