0
# Asynchronous Operations
1
2
Functions for managing asynchronous execution and non-blocking operations within the Gevent event loop used by Eel.
3
4
## Capabilities
5
6
### Non-blocking Sleep
7
8
Sleep function compatible with Gevent event loop that doesn't block other operations.
9
10
```python { .api }
11
def sleep(seconds: Union[int, float]) -> None:
12
"""
13
Non-blocking sleep compatible with Gevent event loop.
14
15
Parameters:
16
- seconds: Union[int, float] - Number of seconds to sleep
17
18
Returns:
19
None
20
"""
21
```
22
23
**Usage Example:**
24
25
```python
26
import eel
27
28
@eel.expose
29
def long_running_task():
30
print("Starting task...")
31
eel.sleep(2) # Non-blocking 2-second sleep
32
print("Task completed!")
33
return "Done"
34
35
# In JavaScript, this won't block the UI
36
# eel.long_running_task()(function(result) {
37
# console.log(result); // "Done" after 2 seconds
38
# });
39
```
40
41
### Greenlet Spawning
42
43
Spawn new Greenlets for concurrent execution of functions without blocking the main thread.
44
45
```python { .api }
46
def spawn(function: Callable[..., Any], *args: Any, **kwargs: Any) -> Greenlet:
47
"""
48
Spawn a new Greenlet for asynchronous execution.
49
50
Parameters:
51
- function: Callable - Function to execute asynchronously
52
- *args: Any - Positional arguments for the function
53
- **kwargs: Any - Keyword arguments for the function
54
55
Returns:
56
gvt.Greenlet - Greenlet object for the spawned task
57
"""
58
```
59
60
**Usage Examples:**
61
62
```python
63
import eel
64
65
def background_task(name, duration):
66
print(f"Background task {name} starting...")
67
eel.sleep(duration)
68
print(f"Background task {name} completed!")
69
70
@eel.expose
71
def start_background_tasks():
72
# Spawn multiple concurrent tasks
73
task1 = eel.spawn(background_task, "Task1", 3)
74
task2 = eel.spawn(background_task, "Task2", 2)
75
task3 = eel.spawn(background_task, "Task3", 1)
76
77
return "Background tasks started"
78
79
# Example with cleanup
80
@eel.expose
81
def managed_background_task():
82
def worker():
83
try:
84
# Long-running work
85
for i in range(10):
86
print(f"Working... {i}")
87
eel.sleep(1)
88
except Exception as e:
89
print(f"Task failed: {e}")
90
91
greenlet = eel.spawn(worker)
92
return "Task spawned"
93
94
# Proper cleanup for spawned greenlets
95
import atexit
96
97
spawned_greenlets = []
98
99
def cleanup_greenlets():
100
for greenlet in spawned_greenlets:
101
if not greenlet.dead:
102
greenlet.kill()
103
104
atexit.register(cleanup_greenlets)
105
106
@eel.expose
107
def spawn_with_tracking():
108
def worker():
109
# Your work here
110
pass
111
112
greenlet = eel.spawn(worker)
113
spawned_greenlets.append(greenlet)
114
return "Task started with cleanup tracking"
115
```
116
117
## Gevent Integration
118
119
Eel uses Gevent for asynchronous operations. Understanding this is important for proper usage:
120
121
- **Event Loop**: All Eel operations run in a Gevent event loop
122
- **Greenlets**: Lightweight threads that yield control cooperatively
123
- **Non-blocking**: Use `eel.sleep()` instead of `time.sleep()` to avoid blocking
124
- **Concurrency**: Multiple operations can run concurrently using `eel.spawn()`
125
126
## Best Practices
127
128
### Avoiding Blocking Operations
129
130
```python
131
# BAD: Blocks the entire application
132
import time
133
134
@eel.expose
135
def bad_long_task():
136
time.sleep(5) # Blocks everything!
137
return "Done"
138
139
# GOOD: Non-blocking
140
@eel.expose
141
def good_long_task():
142
eel.sleep(5) # Allows other operations
143
return "Done"
144
```
145
146
### Managing Spawned Tasks
147
148
```python
149
# Keep track of spawned greenlets for proper cleanup
150
active_tasks = []
151
152
@eel.expose
153
def start_managed_task():
154
def worker():
155
try:
156
# Your task logic
157
for i in range(100):
158
# Do work
159
eel.sleep(0.1) # Yield control
160
finally:
161
# Clean up from active_tasks list
162
pass
163
164
greenlet = eel.spawn(worker)
165
active_tasks.append(greenlet)
166
return "Task started"
167
168
@eel.expose
169
def stop_all_tasks():
170
for task in active_tasks:
171
if not task.dead:
172
task.kill()
173
active_tasks.clear()
174
return "All tasks stopped"
175
```