From 508b3e2a231be5765be5d8479fe751aea63760d4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:10:35 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Optimize=20webhook=20li?= =?UTF-8?q?stener=20for=20latency=20and=20efficiency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implemented the "Early Response" pattern in `webhooks/listener.ps1` to minimize turnaround time for webhook senders (e.g., GitHub). Key performance improvements: - Decoupled HTTP response from expensive logging/processing. - Switched from `Get-Date` cmdlet to `.NET [DateTime]::Now` for faster timestamping. - Replaced pipeline operations (`|`) with direct parameter passing (`-InputObject`) to reduce execution overhead in the listener loop. - Pre-allocated encoding and response buffers. - Ensured proper disposal of stream resources. Co-authored-by: Ruh-Al-Tarikh <203426218+Ruh-Al-Tarikh@users.noreply.github.com> --- .jules/bolt.md | 10 ++++++++++ webhooks/listener.ps1 | 39 ++++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..acbf18f --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,10 @@ +# Bolt's Performance Journal ⚡ + +## 2025-05-14 - [Webhook Latency Optimization & PowerShell Efficiency] +**Learning:** In event-driven systems like webhook listeners, the "Early Response" pattern is critical for minimizing sender-side latency. By closing the HTTP response immediately after reading the payload, we decouple the processing/logging time from the network turnaround time. Additionally, in PowerShell, cmdlets like `Get-Date` and the use of the pipeline (`|`) introduce significant overhead compared to direct .NET methods and parameter passing (`-InputObject`). + +**Action:** +1. Move `$response.Close()` to immediately follow the request body read. +2. Replace `Get-Date` with `[DateTime]::Now` for timestamping. +3. Replace pipeline operations with direct parameter passing in high-frequency loops. +4. Pre-allocate static buffers (like response bytes) outside the main request loop. diff --git a/webhooks/listener.ps1 b/webhooks/listener.ps1 index 8d8f929..0cb6a15 100644 --- a/webhooks/listener.ps1 +++ b/webhooks/listener.ps1 @@ -7,6 +7,10 @@ param() $port = 9000 $endpoint = "http://localhost:$port/" +# Performance: Pre-calculate encoding and response buffer to avoid redundant allocations in the loop +$utf8 = [System.Text.Encoding]::UTF8 +$responseBytes = $utf8.GetBytes("System Automation Hub: Event Received") + # Ensure we don't try to start another listener if one is already running in this session if ($null -ne $listener) { try { $listener.Stop() } catch { Write-Verbose "Listener already stopped." } @@ -29,7 +33,8 @@ try { $request = $context.Request $response = $context.Response - $timestamp = Get-Date -Format 'HH:mm:ss' + # Performance: Use .NET [DateTime]::Now for faster timestamp generation than Get-Date cmdlet + $timestamp = [DateTime]::Now.ToString('HH:mm:ss') $method = $request.HttpMethod $remote = $request.RemoteEndPoint $userAgent = $request.UserAgent @@ -37,21 +42,34 @@ try { $sourceIcon = if ($isGitHub) { "🐙 GitHub " } else { "🔗 Web " } + # Read body if available + $body = $null + if ($request.HasEntityBody) { + # Performance: Use constructor directly and ensure proper disposal of the stream reader + $reader = [System.IO.StreamReader]::new($request.InputStream, $utf8) + $body = $reader.ReadToEnd() + $reader.Dispose() + } + + # ⚡ BOLT OPTIMIZATION: Early Response + # We send the response IMMEDIATELY after reading the body to minimize latency for the sender (e.g. GitHub). + # Expensive operations like JSON pretty-printing and console logging happen AFTER the connection is closed. + $response.ContentLength64 = $responseBytes.Length + $response.OutputStream.Write($responseBytes, 0, $responseBytes.Length) + $response.Close() + Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline Write-Host "$sourceIcon" -ForegroundColor Magenta -NoNewline Write-Host "$method " -ForegroundColor Yellow -NoNewline Write-Host "from " -ForegroundColor Gray -NoNewline Write-Host "$remote" -ForegroundColor White - # Read body if available - if ($request.HasEntityBody) { - $reader = New-Object System.IO.StreamReader($request.InputStream, [System.Text.Encoding]::UTF8) - $body = $reader.ReadToEnd() - + if ($null -ne $body) { try { if ($request.ContentType -match "application/json") { - $jsonObj = $body | ConvertFrom-Json - $prettyBody = $jsonObj | ConvertTo-Json -Depth 10 + # Performance: Use -InputObject parameter instead of pipeline for faster processing + $jsonObj = ConvertFrom-Json -InputObject $body + $prettyBody = ConvertTo-Json -InputObject $jsonObj -Depth 10 Write-Host "Payload (JSON):" -ForegroundColor Cyan Write-Host $prettyBody -ForegroundColor DarkGray } else { @@ -64,11 +82,6 @@ try { } } - # Simple response - $buffer = [System.Text.Encoding]::UTF8.GetBytes("System Automation Hub: Event Received") - $response.ContentLength64 = $buffer.Length - $response.OutputStream.Write($buffer, 0, $buffer.Length) - $response.Close() Write-Host "Done.`n" -ForegroundColor DarkGray } } catch { From 17f20526f3eb1b0df483c230ad9091edfe5d9718 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:14:10 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Fix=20syntax=20errors?= =?UTF-8?q?=20in=20Pester=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrected incorrect backslash escapes in `tests/Project.Tests.ps1` that were causing CI failures. These escapes prevented PowerShell from parsing variables correctly during Pester discovery. Co-authored-by: Ruh-Al-Tarikh <203426218+Ruh-Al-Tarikh@users.noreply.github.com> --- tests/Project.Tests.ps1 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/Project.Tests.ps1 b/tests/Project.Tests.ps1 index 3e27506..45becca 100644 --- a/tests/Project.Tests.ps1 +++ b/tests/Project.Tests.ps1 @@ -1,10 +1,10 @@ -Describe "System Automation Hub Structure" { +Describe "System Automation Hub Structure" { It "Should have the main entry point (start-automation.ps1)" { - Test-Path "./start-automation.ps1" | Should -Be \$true + Test-Path "./start-automation.ps1" | Should -Be $true } It "Should have the webhooks/listener.ps1 script" { - Test-Path "./webhooks/listener.ps1" | Should -Be \$true + Test-Path "./webhooks/listener.ps1" | Should -Be $true } It "Should have at least one script in the scripts/ directory" { @@ -14,15 +14,15 @@ Describe "PowerShell Script Syntax Verification" { Context "Checking all .ps1 files" { - \$psFiles = Get-ChildItem -Path . -Include *.ps1 -Recurse + $psFiles = Get-ChildItem -Path . -Include *.ps1 -Recurse - foreach (\$file in \$psFiles) { - It "Should have valid syntax for \$(\$file.Name)" { - \$errorActionPreference = "Stop" + foreach ($file in $psFiles) { + It "Should have valid syntax for $($file.Name)" { + $errorActionPreference = "Stop" Get-Command -ErrorAction SilentlyContinue -Name Out-Null # Ensure we can run commands # Check for syntax errors by parsing the script - { [Microsoft.PowerShell.Commands.ScriptAnalyzer.Helper]::GetTokens(\$file.FullName, [ref]\$null, [ref]\$null) } | Should -Not -Throw + { [Microsoft.PowerShell.Commands.ScriptAnalyzer.Helper]::GetTokens($file.FullName, [ref]$null, [ref]$null) } | Should -Not -Throw } } } From b697b569eece1f13bc809d28823c825a1a42a5af Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 10:18:42 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Use=20robust=20PowerShe?= =?UTF-8?q?ll=20parser=20for=20syntax=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the dependency on `PSScriptAnalyzer` internal helpers in `tests/Project.Tests.ps1` with the built-in `[System.Management.Automation.Language.Parser]` class. This fix addresses "Unable to find type" exceptions in CI by using a native PowerShell method that doesn't require external module assemblies to be explicitly loaded in the Pester session. Co-authored-by: Ruh-Al-Tarikh <203426218+Ruh-Al-Tarikh@users.noreply.github.com> --- tests/Project.Tests.ps1 | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/Project.Tests.ps1 b/tests/Project.Tests.ps1 index 45becca..a4f48a6 100644 --- a/tests/Project.Tests.ps1 +++ b/tests/Project.Tests.ps1 @@ -18,11 +18,15 @@ Describe "PowerShell Script Syntax Verification" { foreach ($file in $psFiles) { It "Should have valid syntax for $($file.Name)" { - $errorActionPreference = "Stop" - Get-Command -ErrorAction SilentlyContinue -Name Out-Null # Ensure we can run commands + $errors = $null + $tokens = $null + # Use the built-in Parser to verify syntax without external module dependencies + [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$errors) | Out-Null - # Check for syntax errors by parsing the script - { [Microsoft.PowerShell.Commands.ScriptAnalyzer.Helper]::GetTokens($file.FullName, [ref]$null, [ref]$null) } | Should -Not -Throw + if ($errors) { + $errorMessages = $errors | ForEach-Object { "$($_.Message) at line $($_.Extent.StartLineNumber):$($_.Extent.StartColumnNumber)" } + throw "Syntax errors found in $($file.Name):`n$($errorMessages -join "`n")" + } } } }