Overview
Implement a background job that automatically pauses coaching sessions after a period of inactivity. This prevents abandoned sessions from blocking other users and ensures clean session lifecycle management.
Background
The coaching session infrastructure already supports:
inactivity_timeout_minutes configuration per topic (default: 30 minutes)
- Session status transitions including
active → paused
updated_at timestamp tracking on each session
What's missing is the scheduled job that checks for and auto-pauses inactive sessions.
Requirements
1. Scheduled Job Implementation
Create a Lambda function or background task that:
- Runs on a schedule (every 5 minutes recommended)
- Queries for all
active sessions where:
NOW() - updated_at > inactivity_timeout_minutes
- Transitions matching sessions to
paused status
- Logs the auto-pause action for observability
2. Query Strategy
Option A: DynamoDB Scan with Filter (Simple but less efficient)
# Scan all active sessions, filter by updated_at
response = table.scan(
FilterExpression="session_status = :active AND updated_at < :threshold",
ExpressionAttributeValues={
":active": "active",
":threshold": (datetime.now(UTC) - timedelta(minutes=30)).isoformat()
}
)
Option B: GSI on status + updated_at (More efficient, requires GSI)
- Create GSI:
status-updated_at-index
- PK:
session_status
- SK:
updated_at
- Query active sessions with
updated_at < threshold
3. Auto-Pause Logic
async def auto_pause_inactive_sessions() -> int:
"""Auto-pause sessions inactive beyond their timeout threshold.
Returns:
Number of sessions auto-paused
"""
from coaching.src.core.coaching_topic_registry import COACHING_TOPIC_REGISTRY
paused_count = 0
# Get all active sessions
active_sessions = await repository.get_active_sessions()
for session in active_sessions:
# Get topic-specific timeout (default 30 min)
topic = COACHING_TOPIC_REGISTRY.get(session.topic_id)
timeout_minutes = topic.inactivity_timeout_minutes if topic else 30
# Check if session exceeds timeout
threshold = datetime.now(UTC) - timedelta(minutes=timeout_minutes)
if session.updated_at < threshold:
session.pause()
await repository.update(session)
logger.info(
"session.auto_paused",
session_id=session.session_id,
topic_id=session.topic_id,
inactive_minutes=(datetime.now(UTC) - session.updated_at).total_seconds() / 60
)
paused_count += 1
return paused_count
4. Lambda Handler (if using AWS Lambda)
# coaching/src/lambdas/auto_pause_sessions.py
import structlog
from coaching.src.services.coaching_session_service import CoachingSessionService
logger = structlog.get_logger()
def handler(event, context):
"""Lambda handler for auto-pausing inactive sessions."""
service = CoachingSessionService(...)
try:
paused_count = service.auto_pause_inactive_sessions()
logger.info("auto_pause.completed", paused_count=paused_count)
return {
"statusCode": 200,
"body": {"paused_sessions": paused_count}
}
except Exception as e:
logger.error("auto_pause.failed", error=str(e))
raise
5. Infrastructure (Pulumi)
# Add to coaching/pulumi/__main__.py
auto_pause_lambda = aws.lambda_.Function(
"auto-pause-sessions",
runtime="python3.11",
handler="coaching.src.lambdas.auto_pause_sessions.handler",
role=lambda_role.arn,
timeout=60,
memory_size=256,
environment={
"variables": {
"DYNAMODB_TABLE": sessions_table.name,
"ENVIRONMENT": environment,
}
}
)
# CloudWatch Events Rule - Run every 5 minutes
schedule_rule = aws.cloudwatch.EventRule(
"auto-pause-schedule",
schedule_expression="rate(5 minutes)",
)
aws.cloudwatch.EventTarget(
"auto-pause-target",
rule=schedule_rule.name,
arn=auto_pause_lambda.arn,
)
# Permission for CloudWatch to invoke Lambda
aws.lambda_.Permission(
"auto-pause-cloudwatch-permission",
action="lambda:InvokeFunction",
function=auto_pause_lambda.name,
principal="events.amazonaws.com",
source_arn=schedule_rule.arn,
)
Files to Create/Modify
Create
coaching/src/lambdas/auto_pause_sessions.py - Lambda handler
coaching/tests/unit/lambdas/test_auto_pause_sessions.py - Unit tests
Modify
coaching/src/services/coaching_session_service.py - Add auto_pause_inactive_sessions() method
coaching/src/infrastructure/repositories/dynamodb_coaching_session_repository.py - Add get_active_sessions() method
coaching/pulumi/__main__.py - Add Lambda and CloudWatch infrastructure
Acceptance Criteria
Testing
async def test_auto_pause_inactive_sessions():
"""Test that inactive sessions are auto-paused."""
# Create a session with old updated_at
session = create_test_session(
status="active",
updated_at=datetime.now(UTC) - timedelta(minutes=45) # 45 min ago
)
await repository.create(session)
# Run auto-pause
paused_count = await service.auto_pause_inactive_sessions()
# Verify
assert paused_count == 1
updated = await repository.get(session.session_id)
assert updated.status == "paused"
Related
Overview
Implement a background job that automatically pauses coaching sessions after a period of inactivity. This prevents abandoned sessions from blocking other users and ensures clean session lifecycle management.
Background
The coaching session infrastructure already supports:
inactivity_timeout_minutesconfiguration per topic (default: 30 minutes)active→pausedupdated_attimestamp tracking on each sessionWhat's missing is the scheduled job that checks for and auto-pauses inactive sessions.
Requirements
1. Scheduled Job Implementation
Create a Lambda function or background task that:
activesessions where:pausedstatus2. Query Strategy
Option A: DynamoDB Scan with Filter (Simple but less efficient)
Option B: GSI on status + updated_at (More efficient, requires GSI)
status-updated_at-indexsession_statusupdated_atupdated_at < threshold3. Auto-Pause Logic
4. Lambda Handler (if using AWS Lambda)
5. Infrastructure (Pulumi)
Files to Create/Modify
Create
coaching/src/lambdas/auto_pause_sessions.py- Lambda handlercoaching/tests/unit/lambdas/test_auto_pause_sessions.py- Unit testsModify
coaching/src/services/coaching_session_service.py- Addauto_pause_inactive_sessions()methodcoaching/src/infrastructure/repositories/dynamodb_coaching_session_repository.py- Addget_active_sessions()methodcoaching/pulumi/__main__.py- Add Lambda and CloudWatch infrastructureAcceptance Criteria
auto_pause_inactive_sessions()method implemented in serviceinactivity_timeout_minutesTesting
Related
CoachingTopicDefinition.inactivity_timeout_minutes