Enhance start-api-and-workers.sh and vibe-dev-server.sh scripts
- Added support for Swagger in the API by setting EnableSwagger environment variable. - Implemented build error handling for both API and Workers, providing detailed feedback and suggestions for resolution. - Updated vibe-dev-server.sh to start the API and Workers using Aspire, including improved logging and dashboard URL extraction. - Enhanced waiting mechanisms for API readiness and Aspire dashboard availability, ensuring smoother startup experience.
This commit is contained in:
@@ -56,6 +56,7 @@ WORKERS_PID_FILE="$PID_DIR/workers-${TASK_ID}.pid"
|
|||||||
# Set environment variables for API
|
# Set environment variables for API
|
||||||
export ASPNETCORE_ENVIRONMENT=Development
|
export ASPNETCORE_ENVIRONMENT=Development
|
||||||
export ASPNETCORE_URLS="http://localhost:${API_PORT}"
|
export ASPNETCORE_URLS="http://localhost:${API_PORT}"
|
||||||
|
export EnableSwagger=true
|
||||||
export RUN_ORLEANS_GRAINS=true
|
export RUN_ORLEANS_GRAINS=true
|
||||||
export SILO_ROLE=Trading
|
export SILO_ROLE=Trading
|
||||||
export TASK_SLOT=${TASK_SLOT}
|
export TASK_SLOT=${TASK_SLOT}
|
||||||
@@ -93,8 +94,28 @@ fi
|
|||||||
|
|
||||||
echo "🚀 Starting API on port $API_PORT..."
|
echo "🚀 Starting API on port $API_PORT..."
|
||||||
echo "📁 Running from: $PROJECT_ROOT"
|
echo "📁 Running from: $PROJECT_ROOT"
|
||||||
|
echo "📚 Swagger enabled: true"
|
||||||
cd "$PROJECT_ROOT/src/Managing.Api"
|
cd "$PROJECT_ROOT/src/Managing.Api"
|
||||||
|
|
||||||
|
# Try to build first to catch build errors early
|
||||||
|
echo "🔨 Building API project..."
|
||||||
|
if ! dotnet build --no-incremental > "$PID_DIR/api-${TASK_ID}-build.log" 2>&1; then
|
||||||
|
echo "❌ Build failed! Showing build errors:"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
tail -n 50 "$PID_DIR/api-${TASK_ID}-build.log" 2>/dev/null || cat "$PID_DIR/api-${TASK_ID}-build.log" 2>/dev/null
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "💡 Try:"
|
||||||
|
echo " 1. Clean build: cd $PROJECT_ROOT/src/Managing.Api && dotnet clean && dotnet build"
|
||||||
|
echo " 2. Disable parallel builds: export DOTNET_CLI_MSBUILD_PARALLEL=0"
|
||||||
|
echo " 3. Check for compilation errors in the log above"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✅ Build successful"
|
||||||
|
|
||||||
# Write all output to log file (warnings will be filtered when displaying)
|
# Write all output to log file (warnings will be filtered when displaying)
|
||||||
|
# Disable parallel MSBuild nodes to avoid child node crashes
|
||||||
|
export DOTNET_CLI_MSBUILD_PARALLEL=0
|
||||||
dotnet run > "$PID_DIR/api-${TASK_ID}.log" 2>&1 &
|
dotnet run > "$PID_DIR/api-${TASK_ID}.log" 2>&1 &
|
||||||
API_PID=$!
|
API_PID=$!
|
||||||
echo $API_PID > "$API_PID_FILE"
|
echo $API_PID > "$API_PID_FILE"
|
||||||
@@ -105,18 +126,39 @@ sleep 3
|
|||||||
|
|
||||||
echo "🚀 Starting Workers..."
|
echo "🚀 Starting Workers..."
|
||||||
cd "$PROJECT_ROOT/src/Managing.Workers"
|
cd "$PROJECT_ROOT/src/Managing.Workers"
|
||||||
# Set workers environment variables (separate from API)
|
|
||||||
# Write all output to log file (warnings will be filtered when displaying)
|
# Try to build first to catch build errors early
|
||||||
ASPNETCORE_ENVIRONMENT=Development \
|
echo "🔨 Building Workers project..."
|
||||||
PostgreSql__ConnectionString="Host=localhost;Port=${POSTGRES_PORT};Database=${DB_NAME};Username=postgres;Password=postgres" \
|
if ! dotnet build --no-incremental > "$PID_DIR/workers-${TASK_ID}-build.log" 2>&1; then
|
||||||
InfluxDb__Url="http://localhost:8086/" \
|
echo "❌ Build failed! Showing build errors:"
|
||||||
InfluxDb__Token="Fw2FPL2OwTzDHzSbR2Sd5xs0EKQYy00Q-hYKYAhr9cC1_q5YySONpxuf_Ck0PTjyUiF13xXmi__bu_pXH-H9zA==" \
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
KAIGEN_SECRET_KEY="KaigenXCowchain" \
|
tail -n 50 "$PID_DIR/workers-${TASK_ID}-build.log" 2>/dev/null || cat "$PID_DIR/workers-${TASK_ID}-build.log" 2>/dev/null
|
||||||
Flagsmith__ApiKey="ser.ShJJJMtWYS9fwuzd83ejwR" \
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
dotnet run > "$PID_DIR/workers-${TASK_ID}.log" 2>&1 &
|
echo ""
|
||||||
WORKERS_PID=$!
|
echo "💡 Try:"
|
||||||
echo $WORKERS_PID > "$WORKERS_PID_FILE"
|
echo " 1. Clean build: cd $PROJECT_ROOT/src/Managing.Workers && dotnet clean && dotnet build"
|
||||||
echo "✅ Workers started (PID: $WORKERS_PID) from worktree: $PROJECT_ROOT"
|
echo " 2. Disable parallel builds: export DOTNET_CLI_MSBUILD_PARALLEL=0"
|
||||||
|
echo " 3. Check for compilation errors in the log above"
|
||||||
|
# Don't exit - API might still be running
|
||||||
|
echo "⚠️ Continuing without Workers..."
|
||||||
|
else
|
||||||
|
echo "✅ Build successful"
|
||||||
|
|
||||||
|
# Set workers environment variables (separate from API)
|
||||||
|
# Write all output to log file (warnings will be filtered when displaying)
|
||||||
|
# Disable parallel MSBuild nodes to avoid child node crashes
|
||||||
|
export DOTNET_CLI_MSBUILD_PARALLEL=0
|
||||||
|
ASPNETCORE_ENVIRONMENT=Development \
|
||||||
|
PostgreSql__ConnectionString="Host=localhost;Port=${POSTGRES_PORT};Database=${DB_NAME};Username=postgres;Password=postgres" \
|
||||||
|
InfluxDb__Url="http://localhost:8086/" \
|
||||||
|
InfluxDb__Token="Fw2FPL2OwTzDHzSbR2Sd5xs0EKQYy00Q-hYKYAhr9cC1_q5YySONpxuf_Ck0PTjyUiF13xXmi__bu_pXH-H9zA==" \
|
||||||
|
KAIGEN_SECRET_KEY="KaigenXCowchain" \
|
||||||
|
Flagsmith__ApiKey="ser.ShJJJMtWYS9fwuzd83ejwR" \
|
||||||
|
dotnet run > "$PID_DIR/workers-${TASK_ID}.log" 2>&1 &
|
||||||
|
WORKERS_PID=$!
|
||||||
|
echo $WORKERS_PID > "$WORKERS_PID_FILE"
|
||||||
|
echo "✅ Workers started (PID: $WORKERS_PID) from worktree: $PROJECT_ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ API and Workers started!"
|
echo "✅ API and Workers started!"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# scripts/vibe-kanban/vibe-dev-server.sh
|
# scripts/vibe-kanban/vibe-dev-server.sh
|
||||||
# Simplified script for Vibe Kanban - starts API and Workers only
|
# Simplified script for Vibe Kanban - starts API and Workers using Aspire
|
||||||
# Assumes database setup is already done by vibe-setup.sh
|
# Assumes database setup is already done by vibe-setup.sh
|
||||||
|
|
||||||
# Detect worktree root
|
# Detect worktree root
|
||||||
@@ -89,21 +89,22 @@ MAIN_REPO_PATHS=(
|
|||||||
|
|
||||||
MAIN_REPO=""
|
MAIN_REPO=""
|
||||||
for path in "${MAIN_REPO_PATHS[@]}"; do
|
for path in "${MAIN_REPO_PATHS[@]}"; do
|
||||||
if [ -n "$path" ] && [ -d "$path" ] && [ -d "$path/scripts" ] && [ -f "$path/scripts/start-api-and-workers.sh" ]; then
|
if [ -n "$path" ] && [ -d "$path" ] && [ -d "$path/src/Managing.AppHost" ]; then
|
||||||
MAIN_REPO="$path"
|
MAIN_REPO="$path"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ -z "$MAIN_REPO" ]; then
|
if [ -z "$MAIN_REPO" ]; then
|
||||||
echo "❌ Cannot find main repository with scripts"
|
echo "❌ Cannot find main repository with Aspire AppHost"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "📁 Main repository: $MAIN_REPO"
|
echo "📁 Main repository: $MAIN_REPO"
|
||||||
echo "🚀 Starting API and Workers..."
|
echo "🚀 Starting API and Workers using Aspire..."
|
||||||
echo " Task ID: $TASK_ID"
|
echo " Task ID: $TASK_ID"
|
||||||
echo " Port offset: $PORT_OFFSET"
|
echo " Port offset: $PORT_OFFSET"
|
||||||
|
echo " Task Slot: $TASK_SLOT"
|
||||||
|
|
||||||
# Verify database is ready
|
# Verify database is ready
|
||||||
if [ -n "$POSTGRES_PORT" ]; then
|
if [ -n "$POSTGRES_PORT" ]; then
|
||||||
@@ -116,93 +117,163 @@ if [ -n "$POSTGRES_PORT" ]; then
|
|||||||
echo "✅ Database is ready"
|
echo "✅ Database is ready"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Export worktree path so main repo scripts know where to run dotnet from
|
# Ensure API_PORT is set (should be from config, but fallback if needed)
|
||||||
export VIBE_WORKTREE_ROOT="$WORKTREE_PROJECT_ROOT"
|
if [ -z "$API_PORT" ]; then
|
||||||
|
API_PORT=$((5000 + PORT_OFFSET))
|
||||||
|
fi
|
||||||
|
|
||||||
# Start API and Workers only (database setup is already done)
|
# Set environment variables for Aspire
|
||||||
bash "$MAIN_REPO/scripts/start-api-and-workers.sh" "$TASK_ID" "$PORT_OFFSET"
|
export TASK_ID="$TASK_ID"
|
||||||
|
export PORT_OFFSET="$PORT_OFFSET"
|
||||||
|
export TASK_SLOT="$TASK_SLOT"
|
||||||
|
|
||||||
# Determine log file paths (logs are created in the worktree root)
|
# Change to AppHost directory
|
||||||
PID_DIR="$WORKTREE_PROJECT_ROOT/.task-pids"
|
cd "$MAIN_REPO/src/Managing.AppHost"
|
||||||
API_LOG="$PID_DIR/api-${TASK_ID}.log"
|
|
||||||
WORKERS_LOG="$PID_DIR/workers-${TASK_ID}.log"
|
|
||||||
|
|
||||||
# Wait for log files to be created
|
# Run Aspire (this will start the API and Workers)
|
||||||
echo ""
|
echo ""
|
||||||
echo "⏳ Waiting for services to start and log files to be created..."
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
for i in {1..30}; do
|
echo "🚀 Starting Aspire..."
|
||||||
if [ -f "$API_LOG" ] && [ -f "$WORKERS_LOG" ]; then
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
echo "✅ Log files found"
|
echo ""
|
||||||
|
|
||||||
|
# Run Aspire in the background and capture output
|
||||||
|
ASPIRE_LOG="$WORKTREE_PROJECT_ROOT/.task-pids/aspire-${TASK_ID}.log"
|
||||||
|
mkdir -p "$(dirname "$ASPIRE_LOG")"
|
||||||
|
|
||||||
|
# Start Aspire
|
||||||
|
dotnet run > "$ASPIRE_LOG" 2>&1 &
|
||||||
|
ASPIRE_PID=$!
|
||||||
|
|
||||||
|
# Save PID
|
||||||
|
echo $ASPIRE_PID > "$WORKTREE_PROJECT_ROOT/.task-pids/aspire-${TASK_ID}.pid"
|
||||||
|
|
||||||
|
echo "✅ Aspire started (PID: $ASPIRE_PID)"
|
||||||
|
echo "📋 Log: $ASPIRE_LOG"
|
||||||
|
echo ""
|
||||||
|
echo "⏳ Aspire is starting (this may take 30-60 seconds on first run)..."
|
||||||
|
echo " Building projects and starting services..."
|
||||||
|
|
||||||
|
# Wait a bit for Aspire to start writing to the log
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
# Try to extract the dashboard URL from the log (Aspire prints it when it starts)
|
||||||
|
ASPIRE_DASHBOARD_URL=""
|
||||||
|
ASPIRE_DASHBOARD_PORT=""
|
||||||
|
|
||||||
|
# Common Aspire dashboard ports to try
|
||||||
|
POSSIBLE_PORTS=(15242 15000 15888 17247)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "⏳ Waiting for Aspire dashboard to be ready..."
|
||||||
|
for i in {1..120}; do
|
||||||
|
# Try to extract dashboard URL from log
|
||||||
|
if [ -f "$ASPIRE_LOG" ]; then
|
||||||
|
# Look for "Now listening on: http://localhost:PORT" or similar patterns
|
||||||
|
DASHBOARD_LINE=$(grep -i "listening\|dashboard\|http://localhost" "$ASPIRE_LOG" 2>/dev/null | tail -1)
|
||||||
|
if [ -n "$DASHBOARD_LINE" ]; then
|
||||||
|
# Extract port from the line
|
||||||
|
EXTRACTED_PORT=$(echo "$DASHBOARD_LINE" | grep -oE 'localhost:[0-9]+' | head -1 | cut -d: -f2)
|
||||||
|
if [ -n "$EXTRACTED_PORT" ]; then
|
||||||
|
ASPIRE_DASHBOARD_PORT="$EXTRACTED_PORT"
|
||||||
|
ASPIRE_DASHBOARD_URL="http://localhost:${ASPIRE_DASHBOARD_PORT}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If we don't have a URL yet, try common ports
|
||||||
|
if [ -z "$ASPIRE_DASHBOARD_URL" ]; then
|
||||||
|
for port in "${POSSIBLE_PORTS[@]}"; do
|
||||||
|
if curl -s -f "http://localhost:${port}" > /dev/null 2>&1; then
|
||||||
|
ASPIRE_DASHBOARD_PORT="$port"
|
||||||
|
ASPIRE_DASHBOARD_URL="http://localhost:${port}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
if [ $i -eq 30 ]; then
|
done
|
||||||
echo "⚠️ Log files not found after 30 seconds"
|
fi
|
||||||
echo " API log: $API_LOG"
|
|
||||||
echo " Workers log: $WORKERS_LOG"
|
# If we found the dashboard, break
|
||||||
echo " Continuing anyway..."
|
if [ -n "$ASPIRE_DASHBOARD_URL" ] && curl -s -f "$ASPIRE_DASHBOARD_URL" > /dev/null 2>&1; then
|
||||||
|
echo "✅ Aspire dashboard is ready at $ASPIRE_DASHBOARD_URL!"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show progress every 10 seconds
|
||||||
|
if [ $((i % 10)) -eq 0 ]; then
|
||||||
|
echo " Still starting... (${i}/120 seconds)"
|
||||||
|
# Show last few lines of log for progress
|
||||||
|
if [ -f "$ASPIRE_LOG" ]; then
|
||||||
|
LAST_LINE=$(tail -1 "$ASPIRE_LOG" 2>/dev/null | cut -c1-80)
|
||||||
|
if [ -n "$LAST_LINE" ]; then
|
||||||
|
echo " Latest: $LAST_LINE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $i -eq 120 ]; then
|
||||||
|
echo "⚠️ Aspire dashboard did not become ready after 120 seconds"
|
||||||
|
echo "💡 Check the log: $ASPIRE_LOG"
|
||||||
|
echo "💡 Last 10 lines of log:"
|
||||||
|
tail -10 "$ASPIRE_LOG" 2>/dev/null || echo " (log file not found)"
|
||||||
|
# Try to use default port anyway
|
||||||
|
if [ -z "$ASPIRE_DASHBOARD_URL" ]; then
|
||||||
|
ASPIRE_DASHBOARD_PORT=15242
|
||||||
|
ASPIRE_DASHBOARD_URL="http://localhost:15242"
|
||||||
|
echo "💡 Using default port: $ASPIRE_DASHBOARD_URL"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# Show logs with labels
|
# Wait for API to be ready (give it more time since Aspire needs to build first)
|
||||||
echo ""
|
echo ""
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "⏳ Waiting for API to be ready..."
|
||||||
echo "📋 Showing API and Workers logs (Press Ctrl+C to stop)"
|
API_READY=false
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
for i in {1..90}; do
|
||||||
echo ""
|
if curl -s -f "http://localhost:${API_PORT}/alive" > /dev/null 2>&1; then
|
||||||
|
API_READY=true
|
||||||
# Check if log files exist
|
echo "✅ API is ready!"
|
||||||
if [ ! -f "$API_LOG" ] && [ ! -f "$WORKERS_LOG" ]; then
|
break
|
||||||
echo "❌ No log files found"
|
|
||||||
echo " API log: $API_LOG"
|
|
||||||
echo " Workers log: $WORKERS_LOG"
|
|
||||||
echo "💡 Services may still be starting. You can manually view logs with:"
|
|
||||||
echo " tail -f $API_LOG"
|
|
||||||
echo " tail -f $WORKERS_LOG"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use multitail if available for better viewing, otherwise use simple tail
|
|
||||||
if command -v multitail >/dev/null 2>&1; then
|
|
||||||
echo "📋 Using multitail for split-screen log viewing..."
|
|
||||||
if [ -f "$API_LOG" ] && [ -f "$WORKERS_LOG" ]; then
|
|
||||||
multitail -s 2 \
|
|
||||||
-ci green -T "API" "$API_LOG" \
|
|
||||||
-ci yellow -T "Workers" "$WORKERS_LOG"
|
|
||||||
elif [ -f "$API_LOG" ]; then
|
|
||||||
tail -f "$API_LOG"
|
|
||||||
elif [ -f "$WORKERS_LOG" ]; then
|
|
||||||
tail -f "$WORKERS_LOG"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Show progress every 15 seconds
|
||||||
|
if [ $((i % 15)) -eq 0 ]; then
|
||||||
|
echo " Still waiting for API... (${i}/90 seconds)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $i -eq 90 ]; then
|
||||||
|
echo "⚠️ API did not become ready after 90 seconds"
|
||||||
|
echo "💡 Check the log: $ASPIRE_LOG"
|
||||||
|
echo "💡 The API may still be building or starting"
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# Print the Aspire dashboard URL in the format Vibe Kanban expects
|
||||||
|
# This must be printed so Vibe Kanban can detect the server is running
|
||||||
|
echo ""
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
if [ "$API_READY" = true ]; then
|
||||||
|
echo "✅ Dev server is running"
|
||||||
else
|
else
|
||||||
# Simple approach: tail both files with prefixes
|
echo "⚠️ Dev server started (API may still be initializing)"
|
||||||
# Use a subshell to manage background processes
|
|
||||||
(
|
|
||||||
# Start tailing API logs in background (filter out NuGet build warnings)
|
|
||||||
if [ -f "$API_LOG" ]; then
|
|
||||||
tail -f "$API_LOG" 2>/dev/null | grep -vE "(warning NU|\.csproj : warning)" | while IFS= read -r line; do
|
|
||||||
echo "[API] $line"
|
|
||||||
done &
|
|
||||||
TAIL_API_PID=$!
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start tailing Workers logs in background (filter out NuGet build warnings)
|
|
||||||
if [ -f "$WORKERS_LOG" ]; then
|
|
||||||
tail -f "$WORKERS_LOG" 2>/dev/null | grep -vE "(warning NU|\.csproj : warning)" | while IFS= read -r line; do
|
|
||||||
echo "[WORKERS] $line"
|
|
||||||
done &
|
|
||||||
TAIL_WORKERS_PID=$!
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clean up background processes on exit
|
|
||||||
cleanup() {
|
|
||||||
[ -n "$TAIL_API_PID" ] && kill "$TAIL_API_PID" 2>/dev/null
|
|
||||||
[ -n "$TAIL_WORKERS_PID" ] && kill "$TAIL_WORKERS_PID" 2>/dev/null
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
trap cleanup INT TERM EXIT
|
|
||||||
|
|
||||||
# Wait for background processes
|
|
||||||
wait
|
|
||||||
)
|
|
||||||
fi
|
fi
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo "$ASPIRE_DASHBOARD_URL"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
echo "📊 Additional URLs:"
|
||||||
|
echo " API: http://localhost:${API_PORT}"
|
||||||
|
echo " Swagger UI: http://localhost:${API_PORT}/swagger"
|
||||||
|
echo " Health check: http://localhost:${API_PORT}/alive"
|
||||||
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Tail the Aspire log
|
||||||
|
echo "📋 Showing Aspire logs (Press Ctrl+C to stop)"
|
||||||
|
echo ""
|
||||||
|
tail -f "$ASPIRE_LOG" 2>/dev/null || {
|
||||||
|
echo "❌ Cannot read Aspire log: $ASPIRE_LOG"
|
||||||
|
echo "💡 Aspire may still be starting. Check the log manually."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,36 +11,37 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Npgsql" Version="8.1.0"/>
|
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0"/>
|
<PackageReference Include="AspNetCore.HealthChecks.Npgsql" Version="8.1.0" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="9.0.0"/>
|
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0" />
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0"/>
|
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="9.0.0" />
|
||||||
<PackageReference Include="Essential.LoggerProvider.Elasticsearch" Version="1.3.2"/>
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.5"/>
|
<PackageReference Include="Essential.LoggerProvider.Elasticsearch" Version="1.3.2" />
|
||||||
<PackageReference Include="Microsoft.Orleans.Core" Version="9.2.1"/>
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.5" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1"/>
|
<PackageReference Include="Microsoft.Orleans.Core" Version="9.2.1" />
|
||||||
<PackageReference Include="NSwag.AspNetCore" Version="14.0.7"/>
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
|
||||||
<PackageReference Include="OrleansDashboard" Version="8.2.0"/>
|
<PackageReference Include="NSwag.AspNetCore" Version="14.0.7" />
|
||||||
<PackageReference Include="Sentry.AspNetCore" Version="5.5.1"/>
|
<PackageReference Include="OrleansDashboard" Version="8.2.0" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1"/>
|
<PackageReference Include="Sentry.AspNetCore" Version="5.5.1" />
|
||||||
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.3.0"/>
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0"/>
|
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.3.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1"/>
|
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0"/>
|
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="10.0.0"/>
|
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.6.1"/>
|
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="10.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.6.1"/>
|
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.6.1" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.1"/>
|
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.6.1" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.1"/>
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.6.1" />
|
||||||
<PackageReference Include="xunit" Version="2.8.0"/>
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.6.1" />
|
||||||
<PackageReference Include="Polly" Version="8.4.0"/>
|
<PackageReference Include="xunit" Version="2.8.0" />
|
||||||
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0"/>
|
<PackageReference Include="Polly" Version="8.4.0" />
|
||||||
<PackageReference Include="DotNetEnv" Version="3.1.1"/>
|
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
|
||||||
|
<PackageReference Include="DotNetEnv" Version="3.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Managing.Bootstrap\Managing.Bootstrap.csproj"/>
|
<ProjectReference Include="..\Managing.Bootstrap\Managing.Bootstrap.csproj" />
|
||||||
<ProjectReference Include="..\Managing.Core\Managing.Core.csproj"/>
|
<ProjectReference Include="..\Managing.Core\Managing.Core.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -59,6 +60,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Extensions\"/>
|
<Folder Include="Extensions\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
22
src/Managing.AppHost/Managing.AppHost.csproj
Normal file
22
src/Managing.AppHost/Managing.AppHost.csproj
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<IsAspireHost>true</IsAspireHost>
|
||||||
|
<UserSecretsId>05b5e3ae-42a0-4689-826a-9fe60d831704</UserSecretsId>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Managing.Api\Managing.Api.csproj" />
|
||||||
|
<ProjectReference Include="..\Managing.Workers\Managing.Workers.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
58
src/Managing.AppHost/Program.cs
Normal file
58
src/Managing.AppHost/Program.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using Aspire.Hosting;
|
||||||
|
|
||||||
|
var builder = DistributedApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Get task-specific configuration from environment variables
|
||||||
|
var taskId = Environment.GetEnvironmentVariable("TASK_ID") ?? "DEFAULT";
|
||||||
|
var portOffset = int.Parse(Environment.GetEnvironmentVariable("PORT_OFFSET") ?? "0");
|
||||||
|
var taskSlot = Environment.GetEnvironmentVariable("TASK_SLOT") ?? "1";
|
||||||
|
|
||||||
|
// Calculate ports based on task configuration
|
||||||
|
var apiPort = 5000 + portOffset;
|
||||||
|
var postgresPort = 5432 + portOffset;
|
||||||
|
var redisPort = 6379 + portOffset;
|
||||||
|
|
||||||
|
// Calculate Orleans ports from TASK_SLOT
|
||||||
|
var taskSlotInt = int.Parse(taskSlot);
|
||||||
|
var orleansSiloPort = 11111 + (taskSlotInt - 1) * 10;
|
||||||
|
var orleansGatewayPort = 30000 + (taskSlotInt - 1) * 10;
|
||||||
|
var orleansDashboardPort = 9999 + (taskSlotInt - 1);
|
||||||
|
|
||||||
|
// Database names
|
||||||
|
var dbName = $"managing_{taskId.ToLower()}";
|
||||||
|
var orleansDbName = $"orleans_{taskId.ToLower()}";
|
||||||
|
|
||||||
|
// Connection strings (using existing Docker containers managed by Docker Compose)
|
||||||
|
var postgresConnectionString = $"Host=localhost;Port={postgresPort};Database={dbName};Username=postgres;Password=postgres";
|
||||||
|
var postgresOrleansConnectionString = $"Host=localhost;Port={postgresPort};Database={orleansDbName};Username=postgres;Password=postgres";
|
||||||
|
var redisConnectionString = $"localhost:{redisPort}";
|
||||||
|
|
||||||
|
// Add API project
|
||||||
|
var api = builder.AddProject("api", "../Managing.Api/Managing.Api.csproj")
|
||||||
|
.WithHttpEndpoint(port: apiPort)
|
||||||
|
.WithEnvironment("TASK_ID", taskId)
|
||||||
|
.WithEnvironment("TASK_SLOT", taskSlot)
|
||||||
|
.WithEnvironment("PORT_OFFSET", portOffset.ToString())
|
||||||
|
.WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development")
|
||||||
|
.WithEnvironment("EnableSwagger", "true")
|
||||||
|
.WithEnvironment("RUN_ORLEANS_GRAINS", "true")
|
||||||
|
.WithEnvironment("SILO_ROLE", "Trading")
|
||||||
|
.WithEnvironment("PostgreSql__ConnectionString", postgresConnectionString)
|
||||||
|
.WithEnvironment("PostgreSql__Orleans", postgresOrleansConnectionString)
|
||||||
|
.WithEnvironment("InfluxDb__Url", "http://localhost:8086/")
|
||||||
|
.WithEnvironment("InfluxDb__Token", "Fw2FPL2OwTzDHzSbR2Sd5xs0EKQYy00Q-hYKYAhr9cC1_q5YySONpxuf_Ck0PTjyUiF13xXmi__bu_pXH-H9zA==")
|
||||||
|
.WithEnvironment("ORLEANS_SILO_PORT", orleansSiloPort.ToString())
|
||||||
|
.WithEnvironment("ORLEANS_GATEWAY_PORT", orleansGatewayPort.ToString())
|
||||||
|
.WithEnvironment("ORLEANS_DASHBOARD_PORT", orleansDashboardPort.ToString());
|
||||||
|
|
||||||
|
// Add Workers project
|
||||||
|
var workers = builder.AddProject("workers", "../Managing.Workers/Managing.Workers.csproj")
|
||||||
|
.WithEnvironment("TASK_ID", taskId)
|
||||||
|
.WithEnvironment("TASK_SLOT", taskSlot)
|
||||||
|
.WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development")
|
||||||
|
.WithEnvironment("PostgreSql__ConnectionString", postgresConnectionString)
|
||||||
|
.WithEnvironment("InfluxDb__Url", "http://localhost:8086/")
|
||||||
|
.WithEnvironment("InfluxDb__Token", "Fw2FPL2OwTzDHzSbR2Sd5xs0EKQYy00Q-hYKYAhr9cC1_q5YySONpxuf_Ck0PTjyUiF13xXmi__bu_pXH-H9zA==");
|
||||||
|
|
||||||
|
// Build and run
|
||||||
|
builder.Build().Run();
|
||||||
8
src/Managing.AppHost/appsettings.Development.json
Normal file
8
src/Managing.AppHost/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/Managing.AppHost/appsettings.json
Normal file
9
src/Managing.AppHost/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning",
|
||||||
|
"Aspire.Hosting.Dcp": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,24 +8,25 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1"/>
|
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11"/>
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10"/>
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
|
||||||
<PackageReference Include="Sentry" Version="5.5.1"/>
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0"/>
|
<PackageReference Include="Sentry" Version="5.5.1" />
|
||||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0"/>
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.1.0" />
|
||||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0"/>
|
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
|
||||||
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0"/>
|
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
|
||||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0"/>
|
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Managing.Bootstrap\Managing.Bootstrap.csproj"/>
|
<ProjectReference Include="..\Managing.Bootstrap\Managing.Bootstrap.csproj" />
|
||||||
<ProjectReference Include="..\Managing.Application\Managing.Application.csproj"/>
|
<ProjectReference Include="..\Managing.Application\Managing.Application.csproj" />
|
||||||
<ProjectReference Include="..\Managing.Application.Abstractions\Managing.Application.Abstractions.csproj"/>
|
<ProjectReference Include="..\Managing.Application.Abstractions\Managing.Application.Abstractions.csproj" />
|
||||||
<ProjectReference Include="..\Managing.Infrastructure.Database\Managing.Infrastructure.Databases.csproj"/>
|
<ProjectReference Include="..\Managing.Infrastructure.Database\Managing.Infrastructure.Databases.csproj" />
|
||||||
<ProjectReference Include="..\Managing.Infrastructure.Exchanges\Managing.Infrastructure.Exchanges.csproj"/>
|
<ProjectReference Include="..\Managing.Infrastructure.Exchanges\Managing.Infrastructure.Exchanges.csproj" />
|
||||||
<ProjectReference Include="..\Managing.Common\Managing.Common.csproj"/>
|
<ProjectReference Include="..\Managing.Common\Managing.Common.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Managing.Workers.Tests", "M
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Managing.Domain.Tests", "Managing.Domain.Tests\Managing.Domain.Tests.csproj", "{3F835B88-4720-49C2-A4A5-FED2C860C4C4}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Managing.Domain.Tests", "Managing.Domain.Tests\Managing.Domain.Tests.csproj", "{3F835B88-4720-49C2-A4A5-FED2C860C4C4}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Managing.AppHost", "Managing.AppHost\Managing.AppHost.csproj", "{4712128B-F222-47C4-A347-AFF4E5BA02AE}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -246,6 +248,14 @@ Global
|
|||||||
{3F835B88-4720-49C2-A4A5-FED2C860C4C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
{3F835B88-4720-49C2-A4A5-FED2C860C4C4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{3F835B88-4720-49C2-A4A5-FED2C860C4C4}.Release|x64.ActiveCfg = Release|Any CPU
|
{3F835B88-4720-49C2-A4A5-FED2C860C4C4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
{3F835B88-4720-49C2-A4A5-FED2C860C4C4}.Release|x64.Build.0 = Release|Any CPU
|
{3F835B88-4720-49C2-A4A5-FED2C860C4C4}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{4712128B-F222-47C4-A347-AFF4E5BA02AE}.Release|x64.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
Reference in New Issue
Block a user