Skip to content

Commit af10272

Browse files
committed
Add e2e test for async function compilation (issue #123) (#238)
Fixes #123 ### Summary Adds an e2e test to reproduce the async function compilation hang reported in issue #123. However, **the issue cannot be reproduced** in the current codebase - compilation with async function handlers co mpletes successfully. ### Issue Description @cpursley reported that compilation would hang when using async functions in flow step handlers. After removing the `async` keywords, compilation worked. The problematic pattern was: ```typescript .step( { slug: 'process_company_logo' }, async (input) => await processCompanyLogoTask({ ... }) ) ``` ### Changes Made - **Test Flow**: Added `pkgs/cli/examples/async-function-hang.ts` - reproduces the exact pattern from the issue with dummy async tasks - **E2E Test Script**: Added `pkgs/cli/scripts/test-async-hang-issue-123` - automated test with 30s timeout to detect hangs - **Nx Target**: Added `test:e2e:async-hang-issue-123` to `pkgs/cli/project.json` ### Test Results The test passes successfully, indicating: 1. Async functions in handlers compile without hanging 2. The compilation completes in under 30 seconds 3. Migration files are generated correctly ### Possible Explanations The issue may have been: - Fixed by other changes in the codebase - Specific to the user's environment or the actual task imports used - Related to network issues when Deno was fetching dependencies The test now provides regression protection if this issue resurfaces.
1 parent 706462d commit af10272

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Flow } from '@pgflow/dsl';
2+
3+
type Input = {
4+
logo_url: string;
5+
company_slug: string;
6+
company_id: string;
7+
};
8+
9+
// Dummy async task that simulates real async work
10+
async function processCompanyLogoTask(input: { logo_url: string; company_slug: string }) {
11+
// Simulate some async work with a promise
12+
await new Promise((resolve) => setTimeout(resolve, 100));
13+
return {
14+
file_path: `/uploads/${input.company_slug}/logo.png`,
15+
};
16+
}
17+
18+
// Another dummy async task
19+
async function updateCompanyLogoUrlTask(input: { company_id: string; file_path: string }) {
20+
// Simulate some async work
21+
await new Promise((resolve) => setTimeout(resolve, 50));
22+
return {
23+
success: true,
24+
company_id: input.company_id,
25+
logo_url: input.file_path,
26+
};
27+
}
28+
29+
export default new Flow<Input>({
30+
slug: 'upload_company_logo',
31+
maxAttempts: 3,
32+
timeout: 60,
33+
baseDelay: 2,
34+
})
35+
.step(
36+
{ slug: 'process_company_logo' },
37+
async (input) => await processCompanyLogoTask({
38+
logo_url: input.run.logo_url,
39+
company_slug: input.run.company_slug,
40+
})
41+
)
42+
.step(
43+
{ slug: 'update_company_logo_url', dependsOn: ['process_company_logo'] },
44+
async (input) => await updateCompanyLogoUrlTask({
45+
company_id: input.run.company_id,
46+
file_path: (input.process_company_logo as { file_path: string }).file_path,
47+
})
48+
);

pkgs/cli/project.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"test:vitest",
3838
"test:e2e:install",
3939
"test:e2e:install:duplicates",
40-
"test:e2e:compile"
40+
"test:e2e:compile",
41+
"test:e2e:async-hang-issue-123"
4142
],
4243
"options": {
4344
"parallel": false
@@ -77,6 +78,15 @@
7778
"cwd": "{projectRoot}",
7879
"parallel": false
7980
}
81+
},
82+
"test:e2e:async-hang-issue-123": {
83+
"executor": "nx:run-commands",
84+
"local": true,
85+
"dependsOn": ["build"],
86+
"options": {
87+
"command": "./scripts/test-async-hang-issue-123",
88+
"cwd": "{projectRoot}"
89+
}
8090
}
8191
}
8292
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
# Script to test if pgflow CLI compile hangs on flows with async functions
5+
# This reproduces issue #123: https://github.com/pgflow-dev/pgflow/issues/123
6+
#
7+
# Issue: Compilation hangs on flow with async functions
8+
# Reporter: @cpursley
9+
# Description: Running compile on a flow with async function handlers was hanging.
10+
# After commenting out the async keywords, compilation worked.
11+
12+
cd "$(dirname "$0")/.."
13+
ROOT_DIR=$(pwd)
14+
15+
echo "🧪 Testing async function compilation"
16+
echo " Issue #123: https://github.com/pgflow-dev/pgflow/issues/123"
17+
echo ""
18+
19+
# Clean up any existing output
20+
echo "🧹 Cleaning up old test directory"
21+
rm -rf supabase/
22+
23+
# Initialize a fresh Supabase project
24+
echo "🏗️ Creating new Supabase project"
25+
npx -y supabase@latest init --force --with-vscode-settings --with-intellij-settings
26+
27+
# Install pgflow with our CLI
28+
echo "📦 Installing pgflow with CLI"
29+
node dist/index.js install --supabase-path supabase/ --yes
30+
31+
# Try to compile the flow with async functions
32+
echo "🔧 Compiling flow with async functions"
33+
timeout 30s node dist/index.js compile examples/async-function-hang.ts --deno-json examples/deno.json --supabase-path supabase || {
34+
EXIT_CODE=$?
35+
if [ $EXIT_CODE -eq 124 ]; then
36+
echo "❌ FAILURE: Compilation hung and was killed by timeout (30s)"
37+
echo "This confirms issue #123 - compilation hangs on flows with async functions"
38+
exit 1
39+
else
40+
echo "❌ FAILURE: Compilation failed with exit code $EXIT_CODE"
41+
exit $EXIT_CODE
42+
fi
43+
}
44+
45+
# Verify compilation succeeded
46+
echo "✅ Verifying flow compilation"
47+
if ! grep -q "create_flow.*upload_company_logo" supabase/migrations/*.sql; then
48+
echo "❌ FAILURE: No migration found with create_flow for 'upload_company_logo'"
49+
exit 1
50+
fi
51+
52+
# Show success message
53+
echo ""
54+
echo "✨ Async function compilation test complete!"
55+
echo " Issue #123 appears to be fixed or not reproducible in this environment."
56+
echo " See: https://github.com/pgflow-dev/pgflow/issues/123"

0 commit comments

Comments
 (0)