Celery
Design & architecture - Asynchronous background processes
Overview
The Celery modules provide an asynchronous task processing system for the G2P Bridge platform. The system is divided into two complementary modules:
openg2p-g2p-bridge-celery-beat-producers: Periodically checks the database for pending tasks and dispatches them to the message queue
openg2p-g2p-bridge-celery-workers: Executes the dispatched tasks by implementing business logic
This document provides a comprehensive overview of both modules and how they work together.
Architecture Overview
Celery Beat Scheduler
↓
Runs periodically
↓
Beat Producer Tasks (Query DB for pending work)
↓
Send task to Celery Queue (Redis)
↓
Celery Worker Pool
↓
Worker Tasks (Execute actual business logic)
↓
Update Database StatusModule Locations
In the consolidated g2p-bridge monorepo:
Beat Producers:
core/celery-beat-producers/Workers:
core/celery-workers/
Both ship as a single Docker image (registry.gitlab.com/openg2p/g2p-bridge/g2p-bridge/celery), run as beat or worker by Helm configuration.
Core Components
Celery Configuration
Both modules use:
Message Broker: Redis (default:
redis://localhost:6379/0)Result Backend: Redis (default:
redis://localhost:6379/0)Worker Queue:
g2p_bridge_celery_worker_tasksTimezone: UTC
Database Connections
Beat Producers:
Single database connection to G2P Bridge database
Configuration prefix:
g2p_bridge_celery_beat_
Workers:
Dual database connections:
db_engine_pbms: PBMS (PBMS database for agency/warehouse/program data)
db_engine_bridge: G2P Bridge database
Configuration prefix:
g2p_bridge_celery_workers_
Task Scheduler Configuration
The Celery Beat scheduler runs the following producers on configurable intervals (all times in seconds):
Default: All frequencies are 3600 seconds (1 hour), configurable via environment variables.
Task Pairs: Beat Producer → Worker
The system contains 11 task pairs, each following the same pattern:
Pattern Overview
Beat Producer:
Queries database for records with status = PENDING
Limits results to
no_of_tasks_to_process(default: 2)Updates status to PROCESSING
Sends task to worker queue with record ID
Worker:
Receives task from queue with record ID
Fetches record from database
Executes business logic
Updates database with results
Handles errors with retry logic
Task Pair Details
1. Mapper Resolution (Financial Address Resolution)
Purpose: Resolve financial addresses (bank accounts, mobile wallets, email wallets) for beneficiaries.
Beat Producer: mapper_resolution_beat_producer
Status Field:
fa_resolution_statusDatabase Model:
DisbursementBatchControlQuery Logic:
Fetches batches where
fa_resolution_status == PENDINGResets stale tasks (PROCESSING > task_stale_threshold_minutes)
Limits to
no_of_tasks_to_process
Worker: mapper_resolution_worker
Input:
disbursement_batch_control_id(string)Process:
Fetches disbursement batch control record
Fetches all disbursements in batch without FA resolution
Constructs
ResolveRequestwith beneficiary IDsCalls
MapperFactory.get_mapper().resolve()(async)Processes resolution responses
Stores financial address details in
DisbursementResolutionFinancialAddresstableUpdates batch status to PROCESSED and triggers sponsor bank dispatch
Uses:
ResolveHelperfor request constructionMapperFactoryfor SPAR mapper integrationAsync event loop for async mapper calls
Max Attempts:
mapper_resolution_max_attempts(default: 3)FA Types Extracted:
Account number, bank code, branch code (bank transfers)
Mobile number, mobile wallet provider (mobile wallet)
Email address, email wallet provider (email wallet)
2. Check Funds with Bank
Purpose: Check if sponsor bank has sufficient funds for disbursement.
Beat Producer: check_funds_with_bank_beat_producer
Status Field:
funds_available_with_bank(EnvelopeBatchStatusForCash)Database Models:
DisbursementEnvelope,EnvelopeBatchStatusForCashQuery Logic:
Checks
disbursement_schedule_date(current day or future based on config)Filters:
cancellation_status == NOT_CANCELLEDFilters: All disbursements received, all quantities received
Status: PENDING_CHECK or FUNDS_NOT_AVAILABLE
Limits to
no_of_tasks_to_process
Worker: check_funds_with_bank_worker
Input:
disbursement_envelope_id(string)Process:
Fetches disbursement envelope
Retrieves sponsor bank configuration (program account, bank code)
Gets bank connector for sponsor bank
Calls
bank_connector.check_funds()with:Account number
Currency (measurement unit)
Total amount needed
Updates
EnvelopeBatchStatusForCash.funds_available_with_bankstatusRecords attempt count and timestamp
Status Values:
FUNDS_AVAILABLE: Funds are available
FUNDS_NOT_AVAILABLE: Funds are insufficient
ERROR: Max attempts exceeded
Max Attempts:
check_funds_with_bank_max_attempts(default: 3)
3. Block Funds with Bank
Purpose: Block/reserve funds at the sponsor bank for the disbursement.
Beat Producer: block_funds_with_bank_beat_producer
Status Field:
funds_blocked_with_bank(EnvelopeBatchStatusForCash)Database Models:
DisbursementEnvelope,EnvelopeBatchStatusForCashQuery Logic:
Similar date filtering as check funds
Status: PENDING or FUNDS_NOT_AVAILABLE
Previous status: FUNDS_AVAILABLE
Worker: block_funds_with_bank_worker
Input:
disbursement_envelope_id(string)Process:
Fetches disbursement envelope and batch status
Retrieves sponsor bank configuration
Gets bank connector
Calls
bank_connector.block_funds()with account and amountStores block reference number from bank
Updates
funds_blocked_with_bankstatusRecords block reference for later payment initiation
Status Values:
BLOCKED: Funds successfully blocked
FUNDS_NOT_AVAILABLE: Blocking failed
ERROR: Max attempts exceeded
Max Attempts:
block_funds_with_bank_max_attempts(default: 3)
4. Disburse Funds from Bank
Purpose: Initiate actual payment disbursements from sponsor bank to beneficiaries.
Beat Producer: disburse_funds_from_bank_beat_producer
Status Field:
sponsor_bank_dispatch_status(DisbursementBatchControl)Database Model:
DisbursementBatchControlQuery Logic:
Fetches batches where status = PENDING
Checks all required predecessor statuses are PROCESSED
Limits to
no_of_tasks_to_process
Worker: disburse_funds_from_bank_worker
Input:
disbursement_batch_control_id(string)Process:
Fetches batch control and related disbursements
Retrieves resolved financial addresses for beneficiaries
Constructs payment payloads for each disbursement
Groups by payment method (bank, mobile wallet, email wallet)
Calls
bank_connector.initiate_payment()with batch of payloadsStores transaction IDs and payment status
Updates batch status and triggers status monitoring
Payment Methods Supported:
Bank account transfer (IFSC/BIC)
Mobile wallet (phone + provider)
Email wallet (email + provider)
Max Attempts:
disburse_funds_with_bank_max_attempts(default: 3)
5. MT940 Processor
Purpose: Process and parse bank statement files in MT940 format.
Beat Producer: mt940_processor_beat_producer
Status Field:
mt940_status(AccountStatement)Database Model:
AccountStatementQuery Logic:
Fetches statements where status = PENDING
Limits to
no_of_tasks_to_process
Worker: mt940_processor_worker
Input:
account_statement_id(string)Process:
Fetches account statement record
Retrieves uploaded file from storage
Parses MT940 format
Extracts transactions and balances
Validates transactions against disbursement records
Reconciles transactions with disbursement statuses
Updates transaction records with bank confirmation
Max Attempts:
mt940_processor_max_attempts(default: 3)
6. Geo Resolution
Purpose: Resolve geographic zones (state/district) for beneficiaries.
Beat Producer: geo_resolution_beat_producer
Status Field:
geo_resolution_status(DisbursementBatchControl)Database Model:
DisbursementBatchControlQuery Logic:
Fetches batches where status = PENDING
Limits to
no_of_tasks_to_process
Worker: geo_resolution_worker
Input:
disbursement_batch_control_id(string)Process:
Fetches batch control and beneficiaries
Calls
GeoResolverFactory.get_geo_resolver().resolve_geo()with beneficiary IDsReceives geographic zone assignments (large and small areas)
Stores geographic information in
DisbursementBatchControlGeotableUpdates batch status
Uses: Farmer registry for geographic zone lookup
Max Attempts:
geo_resolution_max_attempts(default: 3)
7. Warehouse Allocation
Purpose: Allocate warehouses to geographic zones for commodity distribution.
Beat Producer: warehouse_allocation_beat_producer
Status Field:
warehouse_allocation_status(DisbursementBatchControl)Database Model:
DisbursementBatchControlQuery Logic:
Fetches batches where status = PENDING
Verifies geo resolution is PROCESSED
Limits to
no_of_tasks_to_process
Worker: warehouse_allocation_worker
Input:
disbursement_batch_control_id(string)Process:
Fetches batch control and geo information
Gets benefit code and program from envelope
Calls
WarehouseAllocatorFactory.get_allocator().allocate_warehouse()with:Large geographic zones
Benefit code ID
Program ID
Receives warehouse allocations
Stores allocations in
DisbursementBatchControlGeotableUpdates batch status
Database Tables: Intersects PBMS warehouse data with geographic coverage
Max Attempts:
warehouse_allocation_max_attempts(default: 3)
8. Agency Allocation
Purpose: Allocate agencies for final payment delivery to beneficiaries.
Beat Producer: agency_allocation_beat_producer
Status Field:
agency_allocation_status(DisbursementBatchControl)Database Model:
DisbursementBatchControlQuery Logic:
Fetches batches where status = PENDING
Limits to
no_of_tasks_to_process
Worker: agency_allocation_worker
Input:
disbursement_batch_control_id(string)Process:
Fetches batch control and geo information
Gets benefit code and program from envelope
Calls
AgencyAllocatorFactory.get_allocator().allocate_agency()with:Small geographic zones
Benefit code (dict with id and mnemonic)
Program (dict with id and mnemonic)
Receives agency allocations with:
Agency ID, name, mnemonic
Admin contact information
Additional attributes
Updates multiple tables:
DisbursementBatchControlGeo: Agency detailsDisbursementResolutionGeoAddress: Agency info and beneficiary notification statusDisbursementBatchControlGeoAttributes: Admin details
Sets notification status flags (PENDING or PROCESSED based on suppress_notifications config)
For CASH_PHYSICAL benefits: Sets sponsor_bank_dispatch_status to PENDING
Max Attempts:
agency_allocation_max_attempts(default: 3)
9. Warehouse Notification
Purpose: Send notifications to warehouses about commodity distribution tasks.
Beat Producer: warehouse_notification_beat_producer
Status Field:
warehouse_notification_status(DisbursementBatchControlGeo)Query Logic:
Fetches geo records where status = PENDING
Limits to
no_of_tasks_to_process
Worker: warehouse_notification_worker
Input:
batch_control_geo_id(string)Process:
Fetches batch control geo and related warehouse info
Constructs notification payload with warehouse allocation details
Calls notification service to send warehouse notification
Updates notification status to PROCESSED
Notification Type:
NotificationType.WAREHOUSE_NOTIFICATIONMax Attempts:
warehouse_notification_max_attempts(default: 3)
10. Agency Notification
Purpose: Send notifications to agencies about their payment delivery tasks.
Beat Producer: agency_notification_beat_producer
Status Field:
agency_notification_status(DisbursementBatchControlGeo)Query Logic:
Fetches geo records where status = PENDING
Limits to
no_of_tasks_to_process
Worker: agency_notification_worker
Input:
batch_control_geo_id(string)Process:
Fetches batch control geo and related agency info
Constructs notification payload with agency allocation and beneficiary details
Calls notification service to send agency notification
Updates notification status to PROCESSED
Notification Type:
NotificationType.AGENCY_NOTIFICATIONMax Attempts:
agency_notification_max_attempts(default: 3)
11. Beneficiary Notification
Purpose: Send notifications to beneficiaries about their disbursements.
Beat Producer: beneficiary_notification_beat_producer
Status Field:
beneficiary_notification_status(DisbursementResolutionGeoAddress)Query Logic:
Fetches resolution records where status = PENDING
Limits to
no_of_tasks_to_process
Worker: beneficiary_notification_worker
Input:
resolution_geo_address_id(string)Process:
Fetches resolution geo address with beneficiary details
Constructs notification payload with disbursement information
Calls notification service to send beneficiary notification
Updates notification status to PROCESSED
Notification Type:
NotificationType.BENEFICIARY_NOTIFICATIONMax Attempts:
beneficiary_notification_max_attempts(default: 3)
Data Flow and Processing Pipeline
Error Handling and Retry Logic
Status Values
Retry Mechanism
For Each Task:
Beat producer checks status = PENDING
Updates status to PROCESSING
Dispatches to worker
Worker executes logic
On success: status = PROCESSED
On error:
Increments attempt counter
Stores error code/message
Updates timestamp
If attempts < max_attempts: status = PENDING (will be retried)
If attempts >= max_attempts: status = ERROR (stops retrying)
Stale Task Recovery
The mapper resolution producer includes special logic to recover stale tasks:
This prevents tasks from getting stuck if a worker crashes while processing.
Configuration Parameters
Beat Producer Configuration
Worker Configuration
Key Helpers (Workers)
Agency Helper
Provides utilities for agency-related operations:
Retrieve agency information from PBMS database
Get agency contact details
Validate agency allocations
Warehouse Helper
Provides utilities for warehouse operations:
Retrieve warehouse information
Get sponsor bank configuration for programs/benefits
Validate warehouse allocations
Resolve Helper
Provides utilities for address resolution:
Construct resolve requests for SPAR mapper
Parse financial address responses
Extract FA components (account number, bank code, etc.)
Database Models Used
Beat Producer Database Models
DisbursementBatchControl: Batch-level processing statusDisbursementEnvelope: Envelope container for disbursementsEnvelopeBatchStatusForCash: Cash-specific batch status trackingEnvelopeControl: Envelope control and receipt trackingAccountStatement: MT940 file upload tracking
Worker Database Models
DisbursementBatchControl: Batch processing and status updatesDisbursementBatchControlGeo: Geographic allocation trackingDisbursementBatchControlGeoAttributes: Geo-specific attributesDisbursementEnvelope: Envelope informationDisbursementEnvelopeStatusForCash: Envelope-specific statusDisbursement: Individual disbursement recordsDisbursementResolutionGeoAddress: Geographic resolution dataDisbursementResolutionFinancialAddress: Resolved financial addresses
Integration with Extension Modules
The workers integrate with extension modules:
Agency Allocator (
openg2p-g2p-bridge-agency-allocator):Called by agency_allocation_worker
Allocates agencies using set intersection algorithm
Warehouse Allocator (
openg2p-g2p-bridge-warehouse-allocator):Called by warehouse_allocation_worker
Allocates warehouses for commodity distribution
Geo Resolver (
openg2p-g2p-bridge-geo-resolver):Called by geo_resolution_worker
Resolves beneficiary geographic zones
Mapper Connectors (
openg2p-g2p-bridge-mapper-connectors):Called by mapper_resolution_worker
Resolves financial addresses via SPAR integration
Bank Connectors (
openg2p-g2p-bridge-bank-connectors):Called by funds-related workers
Interfaces with sponsor banks
Notification Connectors (
openg2p-g2p-bridge-notification-connectors):Called by notification workers
Sends notifications via Novu platform
Logging
Both modules use structured logging:
Beat Producers: Log task dispatch events, status updates, database queries
Workers: Log task execution, business logic progress, errors, and recovery
Logger names follow pattern:
Beat:
{task_name}_beat_producerWorker:
{task_name}_worker
Transaction Management
Beat Producers
Use SQLAlchemy sessionmaker with
expire_on_commit=FalseCommit status updates before dispatching task
Ensures consistency between task dispatch and database state
Workers
Use SQLAlchemy sessionmaker with
expire_on_commit=FalseWrap all logic in try-except blocks
Rollback on error and update error status
Commit all changes after processing or error handling
Performance Considerations
Batch Processing: Each beat cycle processes
no_of_tasks_to_process(default: 2) tasks to prevent queue congestionFrequency Control: Task frequencies configurable (default: 1 hour) to balance real-time responsiveness and system load
Stale Task Recovery: Automatic recovery of stuck tasks after
task_stale_threshold_minutes(default: 60)Async Operations: Mapper resolution uses async/await for non-blocking I/O
Database Connection Pooling: SQLAlchemy connection pooling for efficient database access
Monitoring and Observability
Key Metrics to Monitor
Task queue depth (number of pending tasks)
Worker throughput (tasks processed per minute)
Error rates by task type
Retry rates indicating systemic issues
Stale task recovery frequency
Task processing latency
Health Checks
Monitor Redis broker connectivity
Monitor database connectivity
Monitor worker availability
Track task completion rates vs. error rates
Deployment Considerations
Beat Scheduler: Run single instance (ensure only one Celery Beat scheduler)
Workers: Scale horizontally (multiple worker instances with consumer groups)
Queue: Ensure Redis is highly available
Database: Ensure G2P Bridge and PBMS databases are accessible
Notification Service: Ensure Novu platform is accessible for notifications
Bank Integration: Ensure bank connectors are properly configured
Summary
The Celery modules implement a robust, scalable asynchronous task processing system that:
Separates task discovery (beat producers) from task execution (workers)
Provides automatic retry logic with configurable max attempts
Includes stale task recovery for fault tolerance
Integrates with multiple extension modules for specialized operations
Supports parallel processing through worker pool
Provides comprehensive error tracking and status management
Enables monitoring and observability of batch processing operations
Last updated
Was this helpful?