From f069c93cb3591a65f9233094a8664e23d8fea34c Mon Sep 17 00:00:00 2001 From: Wojtek Majewski Date: Wed, 8 Oct 2025 10:50:34 +0200 Subject: [PATCH] chore: add flow example with async functions and update CI to test for issue #123 - Introduced a new flow example demonstrating async function hang scenario - Updated project configuration to include a new end-to-end test for async hang issue - Added a script to reproduce and verify if compilation hangs on flows with async functions - Enhanced CI pipeline to run the new test, aiding in regression detection for issue #123 --- pkgs/cli/examples/async-function-hang.ts | 48 +++++++++++++++++++ pkgs/cli/project.json | 12 ++++- pkgs/cli/scripts/test-async-hang-issue-123 | 56 ++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 pkgs/cli/examples/async-function-hang.ts create mode 100755 pkgs/cli/scripts/test-async-hang-issue-123 diff --git a/pkgs/cli/examples/async-function-hang.ts b/pkgs/cli/examples/async-function-hang.ts new file mode 100644 index 000000000..33babbaaa --- /dev/null +++ b/pkgs/cli/examples/async-function-hang.ts @@ -0,0 +1,48 @@ +import { Flow } from '@pgflow/dsl'; + +type Input = { + logo_url: string; + company_slug: string; + company_id: string; +}; + +// Dummy async task that simulates real async work +async function processCompanyLogoTask(input: { logo_url: string; company_slug: string }) { + // Simulate some async work with a promise + await new Promise((resolve) => setTimeout(resolve, 100)); + return { + file_path: `/uploads/${input.company_slug}/logo.png`, + }; +} + +// Another dummy async task +async function updateCompanyLogoUrlTask(input: { company_id: string; file_path: string }) { + // Simulate some async work + await new Promise((resolve) => setTimeout(resolve, 50)); + return { + success: true, + company_id: input.company_id, + logo_url: input.file_path, + }; +} + +export default new Flow({ + slug: 'upload_company_logo', + maxAttempts: 3, + timeout: 60, + baseDelay: 2, +}) + .step( + { slug: 'process_company_logo' }, + async (input) => await processCompanyLogoTask({ + logo_url: input.run.logo_url, + company_slug: input.run.company_slug, + }) + ) + .step( + { slug: 'update_company_logo_url', dependsOn: ['process_company_logo'] }, + async (input) => await updateCompanyLogoUrlTask({ + company_id: input.run.company_id, + file_path: (input.process_company_logo as { file_path: string }).file_path, + }) + ); diff --git a/pkgs/cli/project.json b/pkgs/cli/project.json index 2544600dc..ef2a82f31 100644 --- a/pkgs/cli/project.json +++ b/pkgs/cli/project.json @@ -37,7 +37,8 @@ "test:vitest", "test:e2e:install", "test:e2e:install:duplicates", - "test:e2e:compile" + "test:e2e:compile", + "test:e2e:async-hang-issue-123" ], "options": { "parallel": false @@ -77,6 +78,15 @@ "cwd": "{projectRoot}", "parallel": false } + }, + "test:e2e:async-hang-issue-123": { + "executor": "nx:run-commands", + "local": true, + "dependsOn": ["build"], + "options": { + "command": "./scripts/test-async-hang-issue-123", + "cwd": "{projectRoot}" + } } } } diff --git a/pkgs/cli/scripts/test-async-hang-issue-123 b/pkgs/cli/scripts/test-async-hang-issue-123 new file mode 100755 index 000000000..d6d8c318b --- /dev/null +++ b/pkgs/cli/scripts/test-async-hang-issue-123 @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +set -e + +# Script to test if pgflow CLI compile hangs on flows with async functions +# This reproduces issue #123: https://github.com/pgflow-dev/pgflow/issues/123 +# +# Issue: Compilation hangs on flow with async functions +# Reporter: @cpursley +# Description: Running compile on a flow with async function handlers was hanging. +# After commenting out the async keywords, compilation worked. + +cd "$(dirname "$0")/.." +ROOT_DIR=$(pwd) + +echo "๐Ÿงช Testing async function compilation" +echo " Issue #123: https://github.com/pgflow-dev/pgflow/issues/123" +echo "" + +# Clean up any existing output +echo "๐Ÿงน Cleaning up old test directory" +rm -rf supabase/ + +# Initialize a fresh Supabase project +echo "๐Ÿ—๏ธ Creating new Supabase project" +npx -y supabase@latest init --force --with-vscode-settings --with-intellij-settings + +# Install pgflow with our CLI +echo "๐Ÿ“ฆ Installing pgflow with CLI" +node dist/index.js install --supabase-path supabase/ --yes + +# Try to compile the flow with async functions +echo "๐Ÿ”ง Compiling flow with async functions" +timeout 30s node dist/index.js compile examples/async-function-hang.ts --deno-json examples/deno.json --supabase-path supabase || { + EXIT_CODE=$? + if [ $EXIT_CODE -eq 124 ]; then + echo "โŒ FAILURE: Compilation hung and was killed by timeout (30s)" + echo "This confirms issue #123 - compilation hangs on flows with async functions" + exit 1 + else + echo "โŒ FAILURE: Compilation failed with exit code $EXIT_CODE" + exit $EXIT_CODE + fi +} + +# Verify compilation succeeded +echo "โœ… Verifying flow compilation" +if ! grep -q "create_flow.*upload_company_logo" supabase/migrations/*.sql; then + echo "โŒ FAILURE: No migration found with create_flow for 'upload_company_logo'" + exit 1 +fi + +# Show success message +echo "" +echo "โœจ Async function compilation test complete!" +echo " Issue #123 appears to be fixed or not reproducible in this environment." +echo " See: https://github.com/pgflow-dev/pgflow/issues/123"