Skip to content

Commit 5758df0

Browse files
committed
Add playground start markdown
1 parent 44df3d9 commit 5758df0

File tree

2 files changed

+228
-0
lines changed

2 files changed

+228
-0
lines changed

docs/playground-start.md

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
# Getting Started with Ceylon Playground
2+
3+
Ceylon is a distributed task processing framework that enables building scalable agent-based systems. This guide will walk you through creating your first Ceylon application using the Playground system.
4+
5+
## Core Concepts
6+
7+
- **Playground**: A central coordinator that manages workers and task distribution
8+
- **ProcessWorker**: Handles specific types of tasks
9+
- **Task**: A unit of work with optional dependencies
10+
- **ProcessRequest/Response**: Communication protocol between playground and workers
11+
12+
## Basic Example: Text Processing System
13+
14+
Let's create a simple system that processes text. We'll build:
15+
1. A text processor that multiplies input
16+
2. An aggregator that combines results
17+
3. A playground to coordinate them
18+
19+
```python
20+
import asyncio
21+
from ceylon.processor.agent import ProcessWorker, ProcessRequest
22+
from ceylon.task.manager import Task
23+
from ceylon.task.playground import TaskProcessingPlayground
24+
25+
class TextProcessor(ProcessWorker):
26+
"""Processes text-based tasks."""
27+
28+
async def _processor(self, request: ProcessRequest, time: int):
29+
data = request.data
30+
return data * 5
31+
32+
class AggregateProcessor(ProcessWorker):
33+
"""Aggregates results from multiple tasks."""
34+
35+
async def _processor(self, request: ProcessRequest, time: int):
36+
data = request.data or 0
37+
for d in request.dependency_data.values():
38+
data += d.output
39+
return data
40+
41+
async def main():
42+
# Initialize playground and workers
43+
playground = TaskProcessingPlayground()
44+
worker = TextProcessor("text_worker", role="multiply")
45+
aggregate_worker = AggregateProcessor("aggregate_worker", role="aggregate")
46+
47+
async with playground.play(workers=[worker, aggregate_worker]) as active_playground:
48+
# Create tasks
49+
task1 = Task(
50+
name="Process Data 1",
51+
processor="multiply",
52+
input_data={'data': 5}
53+
)
54+
55+
task2 = Task(
56+
name="Process Data 2",
57+
processor="multiply",
58+
input_data={'data': 10}
59+
)
60+
61+
task3 = Task(
62+
name="Aggregate Results",
63+
processor="aggregate",
64+
dependencies={task1.id, task2.id}
65+
)
66+
67+
# Execute tasks
68+
for task in [task1, task2, task3]:
69+
result = await active_playground.add_and_execute_task(
70+
task=task,
71+
wait_for_completion=True
72+
)
73+
print(f"Task: {task.name}, Result: {result.output}")
74+
75+
if __name__ == "__main__":
76+
asyncio.run(main())
77+
```
78+
79+
## Key Components Explained
80+
81+
### 1. ProcessWorker
82+
- Base class for task processors
83+
- Implements `_processor` method to handle specific task types
84+
- Can access request data and metadata
85+
86+
```python
87+
class CustomWorker(ProcessWorker):
88+
async def _processor(self, request: ProcessRequest, time: int) -> tuple[Any, dict]:
89+
result = process_data(request.data)
90+
metadata = {"processed_at": time}
91+
return result, metadata
92+
```
93+
94+
### 2. TaskProcessingPlayground
95+
- Manages worker connections
96+
- Coordinates task execution
97+
- Handles dependencies between tasks
98+
99+
```python
100+
playground = TaskProcessingPlayground(name="my_playground", port=8888)
101+
async with playground.play(workers=[worker1, worker2]) as active_playground:
102+
# Execute tasks here
103+
```
104+
105+
### 3. Task
106+
- Represents a unit of work
107+
- Can specify dependencies on other tasks
108+
- Contains input data and processor type
109+
110+
```python
111+
task = Task(
112+
name="MyTask",
113+
processor="worker_role", # Must match worker's role
114+
input_data={'key': 'value'},
115+
dependencies={other_task.id} # Optional dependencies
116+
)
117+
```
118+
119+
## Advanced Features
120+
121+
### 1. Task Dependencies
122+
Ceylon supports complex task dependencies:
123+
124+
```python
125+
task_a = Task(name="A", processor="role_1", input_data={'data': 1})
126+
task_b = Task(name="B", processor="role_2", input_data={'data': 2})
127+
task_c = Task(
128+
name="C",
129+
processor="role_3",
130+
dependencies={task_a.id, task_b.id}
131+
)
132+
```
133+
134+
### 2. Error Handling
135+
Workers can handle errors gracefully:
136+
137+
```python
138+
async def _processor(self, request: ProcessRequest, time: int):
139+
try:
140+
result = process_data(request.data)
141+
return result, {"status": "success"}
142+
except Exception as e:
143+
raise Exception(f"Processing failed: {str(e)}")
144+
```
145+
146+
### 3. Custom Metadata
147+
Add metadata to track processing details:
148+
149+
```python
150+
async def _processor(self, request: ProcessRequest, time: int):
151+
result = process_data(request.data)
152+
metadata = {
153+
"processing_time": time,
154+
"data_size": len(request.data),
155+
"processor_version": "1.0"
156+
}
157+
return result, metadata
158+
```
159+
160+
## Best Practices
161+
162+
1. **Worker Design**
163+
- Keep workers focused on single responsibilities
164+
- Use meaningful role names
165+
- Include proper error handling
166+
167+
2. **Task Management**
168+
- Break complex operations into smaller tasks
169+
- Use clear naming conventions
170+
- Carefully manage dependencies
171+
172+
3. **Resource Handling**
173+
- Use async context managers for cleanup
174+
- Implement proper shutdown procedures
175+
- Monitor worker health
176+
177+
## Common Patterns
178+
179+
### 1. Pipeline Processing
180+
```python
181+
async def create_pipeline():
182+
task1 = Task(name="Extract", processor="extractor")
183+
task2 = Task(name="Transform", processor="transformer",
184+
dependencies={task1.id})
185+
task3 = Task(name="Load", processor="loader",
186+
dependencies={task2.id})
187+
return [task1, task2, task3]
188+
```
189+
190+
### 2. Parallel Processing
191+
```python
192+
tasks = [
193+
Task(name=f"Process_{i}", processor="worker")
194+
for i in range(5)
195+
]
196+
results = await playground.execute_task_group(tasks)
197+
```
198+
199+
## Debugging Tips
200+
201+
1. Enable detailed logging:
202+
```python
203+
from loguru import logger
204+
logger.add("debug.log", level="DEBUG")
205+
```
206+
207+
2. Monitor task states:
208+
```python
209+
task_status = playground.task_manager.get_task(task_id).status
210+
print(f"Task {task_id} status: {task_status}")
211+
```
212+
213+
3. Check worker connections:
214+
```python
215+
connected_workers = playground.llm_agents
216+
print(f"Connected workers: {connected_workers}")
217+
```
218+
219+
## Next Steps
220+
221+
- Explore more complex task dependencies
222+
- Implement custom error handling strategies
223+
- Add monitoring and metrics collection
224+
- Scale your system with additional workers
225+
- Implement custom task scheduling logic
226+
227+
For more information, visit the Ceylon documentation at https://ceylon.ai

mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ nav:
9393
- Getting started:
9494
- Quickstart: quickstart.md
9595
- 5 minutes to Ceylon: 5-minutes-to-ceylon.md
96+
- Start with a Playground: playground-start.md
9697
- Technology: technology.md
9798
- Core Concepts: core-concepts.md
9899
- How to:

0 commit comments

Comments
 (0)