@@ -102,29 +102,70 @@ The SDK requires Python 3.9+. To install the SDK, use the following command:
102102python3 -m pip install conductor-python
103103```
104104
105- ## ⚡ Performance Features (v1.2.5+)
105+ ## 🚀 Quick Start
106106
107- The Python SDK includes ultra-low latency optimizations for high-performance production workloads :
107+ For a complete end-to-end example, see [ examples/workers_e2e.py ] ( examples/workers_e2e.py ) :
108108
109- - ** 2-5ms average polling delay** (down from 15-90ms) - 10-18x improvement!
110- - ** HTTP/2 enabled by default** - 40-60% higher throughput, request multiplexing
111- - ** Batch polling** - 60-70% fewer API calls
112- - ** Adaptive backoff** - Prevents API hammering when queue is empty
113- - ** Concurrent execution** - ThreadPoolExecutor with configurable ` thread_count `
114- - ** Connection pooling** - 100 connections with 50 keep-alive
115- - ** 250+ tasks/sec throughput** with 80-85% efficiency (thread_count=10)
116-
117- See [ POLLING_LOOP_OPTIMIZATIONS.md] ( POLLING_LOOP_OPTIMIZATIONS.md ) and [ HTTP2_MIGRATION.md] ( HTTP2_MIGRATION.md ) for details.
118-
119- ## 📚 Key Documentation
109+ ``` bash
110+ export CONDUCTOR_SERVER_URL=" http://localhost:8080/api"
111+ python3 examples/workers_e2e.py
112+ ```
120113
121- - ** [ Worker Architecture] ( WORKER_ARCHITECTURE.md ) ** - Overview of worker architecture and design
122- - ** [ Worker Concurrency Design] ( WORKER_CONCURRENCY_DESIGN.md ) ** - Multiprocessing vs AsyncIO comparison
123- - ** [ Polling Loop Optimizations] ( POLLING_LOOP_OPTIMIZATIONS.md ) ** - Ultra-low latency polling details
124- - ** [ HTTP/2 Migration] ( HTTP2_MIGRATION.md ) ** - HTTP/2 benefits and connection pooling
125- - ** [ Lease Extension] ( LEASE_EXTENSION.md ) ** - How to handle long-running tasks
126- - ** [ Worker Configuration] ( WORKER_CONFIGURATION.md ) ** - Environment-based configuration
127- - ** [ Worker Documentation] ( docs/worker/README.md ) ** - Complete worker usage guide
114+ This example demonstrates:
115+ - Registering a workflow definition
116+ - Starting workflow execution
117+ - Running workers (sync + async)
118+ - Monitoring with Prometheus metrics
119+ - Long-running tasks with lease extension
120+
121+ ** What you'll see:**
122+ - Workflow URL to monitor execution in UI
123+ - Workers processing tasks (AsyncTaskRunner vs TaskRunner)
124+ - Metrics endpoint at http://localhost:8000/metrics
125+ - Long-running task with TaskInProgress (5 polls)
126+
127+ ## ⚡ Performance Features (SDK 1.3.0+)
128+
129+ The Python SDK provides high-performance worker execution with automatic optimization:
130+
131+ ** Worker Architecture:**
132+ - ** AsyncTaskRunner** for async workers (` async def ` ) - Pure async/await, zero thread overhead
133+ - ** TaskRunner** for sync workers (` def ` ) - ThreadPoolExecutor for concurrent execution
134+ - ** Automatic selection** - Based on function signature, no configuration needed
135+ - ** One process per worker** - Process isolation and fault tolerance
136+
137+ ** Performance Optimizations:**
138+ - ** Dynamic batch polling** - Batch size adapts to available capacity (thread_count - running tasks)
139+ - ** Adaptive backoff** - Exponential backoff when queue empty (1ms → 2ms → 4ms → poll_interval)
140+ - ** High concurrency** - Async workers: 100-1000+ tasks/sec, Sync workers: 10-50 tasks/sec
141+
142+ ** AsyncTaskRunner Benefits (async def workers):**
143+ - 67% fewer threads per worker
144+ - 40-50% less memory per worker
145+ - 10-100x better I/O throughput
146+ - Direct ` await worker_fn() ` execution
147+
148+ See [ docs/design/WORKER_DESIGN.md] ( docs/design/WORKER_DESIGN.md ) for complete architecture details.
149+
150+ ## 📚 Documentation
151+
152+ ** Getting Started:**
153+ - ** [ End-to-End Example] ( examples/workers_e2e.py ) ** - Complete workflow execution with workers
154+ - ** [ Examples Guide] ( examples/EXAMPLES_README.md ) ** - All examples with quick reference
155+
156+ ** Worker Documentation:**
157+ - ** [ Worker Design & Architecture] ( docs/design/WORKER_DESIGN.md ) ** - Complete worker architecture guide
158+ - AsyncTaskRunner vs TaskRunner
159+ - Automatic runner selection
160+ - Worker discovery, configuration, best practices
161+ - Long-running tasks and lease extension
162+ - Performance metrics and monitoring
163+ - ** [ Worker Configuration] ( WORKER_CONFIGURATION.md ) ** - Hierarchical environment-based configuration
164+ - ** [ Complete Worker Guide] ( docs/worker/README.md ) ** - Comprehensive worker documentation
165+
166+ ** Monitoring & Advanced:**
167+ - ** [ Metrics] ( METRICS.md ) ** - Prometheus metrics collection
168+ - ** [ Event-Driven Architecture] ( docs/design/event_driven_interceptor_system.md ) ** - Observability design
128169
129170## Hello World Application Using Conductor
130171
@@ -334,16 +375,34 @@ def greetings(name: str) -> str:
334375 return f ' Hello, { name} '
335376```
336377
337- ** Async Workers:** Workers can be defined as ` async def ` functions for I/O-bound tasks, which are automatically executed using a background event loop for high concurrency:
378+ ** Async Workers:** Workers can be defined as ` async def ` functions for I/O-bound tasks. The SDK automatically uses ** AsyncTaskRunner ** for pure async/await execution with high concurrency:
338379
339380``` python
340- @worker_task (task_definition_name = ' fetch_data' )
381+ @worker_task (task_definition_name = ' fetch_data' , thread_count = 50 )
341382async def fetch_data (url : str ) -> dict :
383+ # Automatically uses AsyncTaskRunner (not TaskRunner)
384+ # - Pure async/await execution (no thread overhead)
385+ # - Single event loop per process
386+ # - Up to 50 concurrent tasks
342387 async with httpx.AsyncClient() as client:
343388 response = await client.get(url)
344389 return response.json()
345390```
346391
392+ ** Sync Workers:** Use regular ` def ` functions for CPU-bound or blocking I/O tasks:
393+
394+ ``` python
395+ @worker_task (task_definition_name = ' process_data' , thread_count = 5 )
396+ def process_data (data : dict ) -> dict :
397+ # Automatically uses TaskRunner (ThreadPoolExecutor)
398+ # - 5 concurrent threads
399+ # - Best for CPU-bound tasks or blocking I/O
400+ result = expensive_computation(data)
401+ return {' result' : result}
402+ ```
403+
404+ ** The SDK automatically selects the right execution model** based on your function signature (` def ` vs ` async def ` ).
405+
347406A worker can take inputs which are primitives - ` str ` , ` int ` , ` float ` , ` bool ` etc. or can be complex data classes.
348407
349408Here is an example worker that uses ` dataclass ` as part of the worker input.
@@ -402,28 +461,34 @@ if __name__ == '__main__':
402461``` bash
403462# Global configuration (applies to all workers)
404463export conductor.worker.all.domain=production
405- export conductor.worker.all.poll_interval=250
464+ export conductor.worker.all.poll_interval_millis=250
465+ export conductor.worker.all.thread_count=20
406466
407467# Worker-specific configuration (overrides global)
408- export conductor.worker.greetings.thread_count=20
468+ export conductor.worker.greetings.thread_count=50
409469
410- # Runtime control (pause/resume workers)
470+ # Runtime control (pause/resume workers without code changes )
411471export conductor.worker.all.paused=true # Maintenance mode
412472```
413473
414- Workers log their configuration on startup:
474+ Workers log their resolved configuration on startup:
415475```
416- INFO - Conductor Worker[name=greetings, status=active, poll_interval=250ms, domain=production, thread_count=20 ]
476+ INFO - Conductor Worker[name=greetings, pid=12345, status=active, poll_interval=250ms, domain=production, thread_count=50 ]
417477```
418478
479+ ** Configuration Priority:** Worker-specific > Global > Code defaults
480+
419481For detailed configuration options, see [ WORKER_CONFIGURATION.md] ( WORKER_CONFIGURATION.md ) .
420482
421483** Monitoring:** Enable Prometheus metrics with built-in HTTP server:
422484
423485``` python
424486from conductor.client.configuration.settings.metrics_settings import MetricsSettings
425487
426- metrics_settings = MetricsSettings(http_port = 8000 )
488+ metrics_settings = MetricsSettings(
489+ directory = ' /tmp/conductor-metrics' , # Multiprocess coordination
490+ http_port = 8000 # HTTP metrics endpoint
491+ )
427492
428493task_handler = TaskHandler(
429494 configuration = api_config,
@@ -433,7 +498,7 @@ task_handler = TaskHandler(
433498# Metrics available at: http://localhost:8000/metrics
434499```
435500
436- For more details, see [ METRICS.md] ( METRICS.md ) and [ WORKER_DESIGN.md] ( WORKER_DESIGN.md ) .
501+ For more details, see [ METRICS.md] ( METRICS.md ) and [ docs/design/ WORKER_DESIGN.md] ( docs/design/ WORKER_DESIGN.md) .
437502
438503### Design Principles for Workers
439504
0 commit comments