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

Enhance Pode Server with Suspend, Resume, and Advanced Console Features #1461

Open
wants to merge 94 commits into
base: develop
Choose a base branch
from

Conversation

mdaneri
Copy link
Contributor

@mdaneri mdaneri commented Dec 8, 2024

Description

This pull request introduces the Suspend and Resume functionality for Pode, enabling the server to temporarily pause and later resume all activities without requiring a full restart. It also enhances the server's console output and interactivity, providing a more robust and user-friendly experience. Furthermore, server configurations (server.psd1) now support advanced console settings and control over allowed actions. New parameters have been added to the Start-PodeServer function, including -IgnoreServerPsConfig, enabling users to bypass loading configuration data from server.psd1.

Additionally, this pull request introduces the Disable-PodeServer and Enable-PodeServer functions, allowing for granular control over the server’s ability to accept incoming requests without impacting its overall state.


Key Features

  1. Suspend-PodeServer:

    • Temporarily pauses all server operations, including associated runspaces.
    • Triggers a Suspend event and updates the server status.
    • Includes an optional -Timeout parameter to specify the maximum wait time for runspaces to suspend.
  2. Resume-PodeServer:

    • Resumes server activities and restores all runspaces to their normal state.
    • Triggers a Resume event, clears the server's suspended status, and updates the console view.
  3. Disable-PodeServer:

    • Temporarily blocks all new incoming requests to the Pode server while maintaining its active state.
    • Responds to incoming requests with a 503 Service Unavailable status.
    • Includes a Retry-After header, specifying the time (in seconds) clients should wait before retrying. The default value is 3600 seconds (1 hour).
    • Example:
      # Disable the Pode server with the default retry time
      Disable-PodeServer
      
      # Disable the Pode server with a custom retry time of 5 minutes
      Disable-PodeServer -RetryAfter 300
  4. Enable-PodeServer:

    • Re-enables the Pode server to accept new incoming requests after being disabled.
    • Resets the server's cancellation token for the disable action, allowing normal request handling to resume.
    • Example:
      # Re-enable the Pode server
      Enable-PodeServer
  5. Improved Console Output:

    • Adds multiple interactive features for better server control:
      • Ctrl+C: Gracefully terminate the server.
      • Ctrl+R: Restart the server and reload configurations.
      • Ctrl+P: Suspend the server.
      • Ctrl+D: Disable new incoming requests (Disable-PodeServer).
      • Ctrl+B: Open the first HTTP endpoint in the default browser.
      • Ctrl+M: Display the server metrics.
      • Ctrl+H: Hide this help.
      • Ctrl+E: Hide Endpoints.
      • Ctrl+O: Hide OpenAPI details.
      • Ctrl+L: Clear the console.
      • Ctrl+Q: Enable Quiet Mode.
  6. Endpoint and Schedule Initialization:

    • Endpoints will no longer receive input, and schedules are not executed until the server is fully initialized, avoiding potential unstable states.
  7. New Console Settings in server.psd1:

    • Introduced support for detailed console customization in the server configuration file:
      @{
          Server = @{
              Console = @{
                   DisableTermination  = $false    # Prevent Ctrl+C from terminating the server.
                       DisableConsoleInput = $false    # Disable all console input controls.
                       Quiet               = $false    # Suppress console output.
                       ClearHost           = $false    # Clear the console output at startup.
                       ShowOpenAPI         = $true     # Display OpenAPI information.
                       ShowEndpoints       = $true     # Display listening endpoints.
                       ShowHelp            = $false    # Show help instructions in the console.
                       ShowDivider         = $true     # Display dividers between sections.
                       DividerLength       = 75        # Length of dividers in the console.
                       ShowTimeStamp       = $true     # Display timestamp in the header.
           
                       Colors              = @{            # Customize console colors.
                           Header           = 'White'      # The server's header section, including the Pode version and timestamp.
                           EndpointsHeader  = 'Yellow'     # The header for the endpoints list.
                           Endpoints        = 'Cyan'       # The endpoints themselves, including protocol and URLs.
                           OpenApiUrls      = 'Cyan'       # URLs listed under the OpenAPI information section.
                           OpenApiHeaders   = 'Yellow'     # Section headers for OpenAPI information.
                           OpenApiTitles    = 'White'      # The OpenAPI "default" title.
                           OpenApiSubtitles = 'Yellow'     # Subtitles under OpenAPI (e.g., Specification, Documentation).
                           HelpHeader       = 'Yellow'     # Header for the Help section.
                           HelpKey          = 'Green'      # Key bindings listed in the Help section (e.g., Ctrl+c).
                           HelpDescription  = 'White'      # Descriptions for each Help section key binding.
                           HelpDivider      = 'Gray'       # Dividers used in the Help section.
                           Divider          = 'DarkGray'   # Dividers between console sections.
                           MetricsHeader    = 'Yellow'     # Header for the Metric section.
                           MetricsLabel     = 'White'      # Labels for values displayed in the Metrics section.
                           MetricsValue     = 'Green'      # The actual values displayed in the Metrics section.
                       }
           
                       KeyBindings         = @{        # Define custom key bindings for controls.
                           Browser   = 'B'             # Open the default browser.
                           Help      = 'H'             # Show/hide help instructions.
                           OpenAPI   = 'O'             # Show/hide OpenAPI information.
                           Endpoints = 'E'             # Show/hide endpoints.
                           Clear     = 'L'             # Clear the console output.
                           Quiet     = 'Q'             # Toggle quiet mode.
                           Terminate = 'C'             # Terminate the server.
                           Restart   = 'R'             # Restart the server.
                           Disable   = 'D'             # Disable the server.
                           Suspend   = 'P'             # Suspend the server.
                           Metrics   = 'M'             # Show Metrics.
                       }
                  }
              }
          }
      }
  8. Allowed Actions Settings:

    • Added a new section in server.psd1 to control server behaviors, including timeouts for suspend and resume operations:
      @{
          Server = @{
              AllowedActions = @{
                 Suspend = $true        # Enable or disable the suspend operation
                 Restart = $true          # Enable or disable the restart operation
                 Disable = $true         # Enable or disable the disable operation
                 DisableSettings = @{
                     RetryAfter = 3600                               # Default retry time (in seconds) for Disable-PodeServer
                     MiddlewareName = '__Pode_Midleware_Code_503'    # Name of the middleware scriptblock
                 }
                 Timeout = @{
                     Suspend = 30       # Maximum seconds to wait before suspending
                     Resume  = 30       # Maximum seconds to wait before resuming
                 }
          }
      }
  9. New Console Settings for Start-PodeServer:

    • New parameters to customize the console behavior:
      • -DisableConsoleInput: Disables keyboard interaction.
      • -ClearHost: Clears the console screen whenever the server changes state (e.g., running → suspend → resume).
      • -HideOpenAPI: Hides OpenAPI details in the console output.
      • -HideEndpoints: Hides the endpoint list in the console output.
      • -ShowHelp: Displays control commands in the console.
      • -IgnoreServerConfig: Ignores the server.psd1 configuration file when starting the server. This ensures that no settings defined in the server.psd1 file are loaded, allowing for manual runtime configuration.
      • -ConfigFile: Specifies a custom configuration file instead of using the default server.psd1.
      • -Daemon: Configures the server to run as a daemon with minimal console interaction and output.

Use Cases

  • Maintenance: Suspend or disable server activities for quick maintenance without a restart.
  • Traffic Management: Use Disable-PodeServer to block new incoming requests during high traffic and re-enable using Enable-PodeServer.
  • Custom Console Behavior: Enhance the server console with customizable settings and interactive features.
  • Fine-Grained Control: Use server.psd1 to define allowed actions and timeouts for suspend/resume transitions.

Example Usage

  1. Start a server with custom console behavior:
    Start-PodeServer -ClearHost -HideEndpoints -ShowHelp

Console Control Commands

Server Control Commands:
    Ctrl+C   : Gracefully terminate the server.
    Ctrl+R   : Restart the server and reload configurations.
    Ctrl+P   : Suspend the server.
    Ctrl+D   : Disable Server
    Ctrl+H   : Hide Help
    Ctrl+B   : Open the first HTTP endpoint in the default browser.
    ----
    Ctrl+M   : Show Metrics
    Ctrl+E   : Hide Endpoints
    Ctrl+Q   : Hide OpenAPI
    Ctrl+L   : Clear the Console
    Ctrl+Q   : Enable Quiet Mode

Notes

  • Events like Suspend and Resume provide hooks for additional custom behavior during these transitions.
  • The Disable-PodeServer and Enable-PodeServer functions offer a lightweight alternative to suspend/resume by controlling only incoming requests, leaving the server's internal state intact.
  • The improved initialization process ensures that endpoints do not receive input and schedules are not executed until the server is fully initialized, maintaining stability.

Copy link
Owner

@Badgerati Badgerati left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed all the code, just not the docs.

Also, I'm guessing you've edited some of this outside of VSCode? As the auto-formatting in some files seems to have not triggered 🤔

src/Locales/en/Pode.psd1 Outdated Show resolved Hide resolved
src/Private/CancellationToken.ps1 Outdated Show resolved Hide resolved
src/Private/CancellationToken.ps1 Outdated Show resolved Hide resolved
src/Private/CancellationToken.ps1 Outdated Show resolved Hide resolved
src/Private/CancellationToken.ps1 Show resolved Hide resolved
src/Private/Console.ps1 Outdated Show resolved Hide resolved
Comment on lines +459 to +468
$protocolLabel = switch ($protocol) {
'HTTP' { 'HTTP ' }
'HTTPS' { 'HTTPS ' }
'WS' { 'WebSocket ' }
'SMTP' { 'SMTP ' }
'SMTPS' { 'SMTPS ' }
'TCP' { 'TCP ' }
'TCPS' { 'TCPS ' }
default { 'UNKNOWN ' }
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary, as every endpoint printed is already prepended with the protocol? https:// etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s looking good 😀

src/Private/Console.ps1 Outdated Show resolved Hide resolved
src/Private/Console.ps1 Outdated Show resolved Hide resolved
src/Private/Console.ps1 Outdated Show resolved Hide resolved
@mdaneri
Copy link
Contributor Author

mdaneri commented Dec 18, 2024

Not everything in vscode. Multiple instances on different platforms but always in vscode.
I noted that sometimes when opening a C# file, VS code stops to consider PowerShell settings.
It happened more than once time but Im not sure how to reproduce it

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.

2 participants