0
# Result Management
1
2
Comprehensive result handling including result storage, retrieval, blocking operations, timeouts, and result groups for batch operations. These features enable robust result tracking and retrieval patterns for asynchronous task execution.
3
4
## Capabilities
5
6
### Result Retrieval
7
8
Get task results with various retrieval strategies and timing controls.
9
10
```python { .api }
11
class Result:
12
def get(self, blocking=False, timeout=None, backoff=1.15, max_delay=1.0,
13
revoke_on_timeout=False, preserve=False):
14
"""
15
Retrieve the task result.
16
17
Parameters:
18
- blocking (bool): Block until result is available (default: False)
19
- timeout (int/float): Maximum time to wait in seconds (optional)
20
- backoff (float): Exponential backoff multiplier (default: 1.15)
21
- max_delay (float): Maximum delay between checks (default: 1.0)
22
- revoke_on_timeout (bool): Revoke task if timeout occurs (default: False)
23
- preserve (bool): Don't consume result, allow multiple reads (default: False)
24
25
Returns:
26
Task result value
27
28
Raises:
29
ResultTimeout: If timeout is reached
30
TaskException: If task failed with an exception
31
"""
32
33
def __call__(self, *args, **kwargs):
34
"""
35
Shortcut for get() method.
36
37
Returns:
38
Task result value
39
"""
40
41
def get_raw_result(self, blocking=False, timeout=None, backoff=1.15,
42
max_delay=1.0, revoke_on_timeout=False, preserve=False):
43
"""
44
Get raw result without exception unwrapping.
45
46
Parameters:
47
- blocking (bool): Block until result is available (default: False)
48
- timeout (int/float): Maximum time to wait in seconds (optional)
49
- backoff (float): Exponential backoff multiplier (default: 1.15)
50
- max_delay (float): Maximum delay between checks (default: 1.0)
51
- revoke_on_timeout (bool): Revoke task on timeout (default: False)
52
- preserve (bool): Don't consume result (default: False)
53
54
Returns:
55
Raw result value or Error instance for failed tasks
56
"""
57
```
58
59
### Result Status and Control
60
61
Check and control result task execution status.
62
63
```python { .api }
64
def is_revoked(self):
65
"""
66
Check if the result's task is revoked.
67
68
Returns:
69
bool: True if task is revoked
70
"""
71
72
def revoke(self, revoke_once=True):
73
"""
74
Revoke the result's task.
75
76
Parameters:
77
- revoke_once (bool): Revoke only one execution (default: True)
78
79
Returns:
80
None
81
"""
82
83
def restore(self):
84
"""
85
Restore a revoked task.
86
87
Returns:
88
bool: True if task was revoked and restored
89
"""
90
91
def reset(self):
92
"""
93
Reset result state to allow re-reading.
94
95
Returns:
96
None
97
"""
98
```
99
100
### Bulk Task Revocation and Restoration
101
102
Bulk operations for revoking and restoring multiple tasks by class or ID.
103
104
```python { .api }
105
def revoke_all(self, task_class, revoke_until=None, revoke_once=False):
106
"""
107
Revoke all tasks of a specific task class.
108
109
Parameters:
110
- task_class (TaskWrapper): Task class to revoke
111
- revoke_until (datetime): Revoke tasks until this time (optional)
112
- revoke_once (bool): Revoke only one execution per task (default: False)
113
114
Returns:
115
int: Number of tasks revoked
116
"""
117
118
def restore_all(self, task_class):
119
"""
120
Restore all revoked tasks of a specific task class.
121
122
Parameters:
123
- task_class (TaskWrapper): Task class to restore
124
125
Returns:
126
int: Number of tasks restored
127
"""
128
129
def revoke_by_id(self, id, revoke_until=None, revoke_once=False):
130
"""
131
Revoke a task by its ID.
132
133
Parameters:
134
- id (str): Task ID to revoke
135
- revoke_until (datetime): Revoke task until this time (optional)
136
- revoke_once (bool): Revoke only one execution (default: False)
137
138
Returns:
139
bool: True if task was found and revoked
140
"""
141
142
def restore_by_id(self, id):
143
"""
144
Restore a revoked task by its ID.
145
146
Parameters:
147
- id (str): Task ID to restore
148
149
Returns:
150
bool: True if task was found and restored
151
"""
152
```
153
154
### Result Rescheduling
155
156
Reschedule tasks associated with results for different execution times.
157
158
```python { .api }
159
def reschedule(self, eta=None, delay=None, expires=None, priority=None,
160
preserve_pipeline=True):
161
"""
162
Reschedule the result's task for different execution.
163
164
Parameters:
165
- eta (datetime): New execution time (optional)
166
- delay (int/float/timedelta): Delay before execution (optional)
167
- expires (datetime/int): New expiration time (optional)
168
- priority (int): New priority level (optional)
169
- preserve_pipeline (bool): Keep task pipeline (default: True)
170
171
Returns:
172
Result: New result instance for rescheduled task
173
"""
174
```
175
176
### Result Groups
177
178
Handle multiple results as a single unit for batch operations.
179
180
```python { .api }
181
class ResultGroup:
182
def get(self, *args, **kwargs):
183
"""
184
Get all results in the group.
185
186
Parameters:
187
- *args, **kwargs: Passed to individual Result.get() calls
188
189
Returns:
190
List of result values in same order as tasks
191
"""
192
193
def __call__(self, *args, **kwargs):
194
"""
195
Shortcut for get() method.
196
197
Returns:
198
List of result values
199
"""
200
201
def __getitem__(self, idx):
202
"""
203
Get result by index with blocking.
204
205
Parameters:
206
- idx (int): Result index
207
208
Returns:
209
Individual result value
210
"""
211
212
def __iter__(self):
213
"""
214
Iterate over Result instances.
215
216
Returns:
217
Iterator of Result instances
218
"""
219
220
def __len__(self):
221
"""
222
Get number of results in group.
223
224
Returns:
225
int: Number of results
226
"""
227
228
def as_completed(self, backoff=1.15, max_delay=1.0):
229
"""
230
Iterate over results as they complete.
231
232
Parameters:
233
- backoff (float): Exponential backoff multiplier (default: 1.15)
234
- max_delay (float): Maximum delay between checks (default: 1.0)
235
236
Yields:
237
Result values as they become available
238
"""
239
```
240
241
### Huey Result Methods
242
243
Result-related methods on the main Huey instance.
244
245
```python { .api }
246
def result(self, id, blocking=False, timeout=None, backoff=1.15,
247
max_delay=1.0, revoke_on_timeout=False, preserve=False):
248
"""
249
Get result by task ID.
250
251
Parameters:
252
- id (str): Task ID
253
- blocking (bool): Block until result available (default: False)
254
- timeout (int/float): Maximum wait time (optional)
255
- backoff (float): Exponential backoff multiplier (default: 1.15)
256
- max_delay (float): Maximum delay between checks (default: 1.0)
257
- revoke_on_timeout (bool): Revoke on timeout (default: False)
258
- preserve (bool): Don't consume result (default: False)
259
260
Returns:
261
Task result value
262
"""
263
264
def all_results(self):
265
"""
266
Get all stored results.
267
268
Returns:
269
List of all result data
270
"""
271
272
def result_count(self):
273
"""
274
Get total number of stored results.
275
276
Returns:
277
int: Number of results in storage
278
"""
279
```
280
281
## Usage Examples
282
283
### Basic Result Handling
284
285
```python
286
from huey import RedisHuey
287
import time
288
289
huey = RedisHuey('results-app')
290
291
@huey.task()
292
def calculate_fibonacci(n):
293
if n <= 1:
294
return n
295
return calculate_fibonacci(n-1) + calculate_fibonacci(n-2)
296
297
# Enqueue task and get result handle
298
result = calculate_fibonacci(10)
299
300
# Non-blocking check
301
try:
302
value = result(blocking=False)
303
print(f"Result ready: {value}")
304
except:
305
print("Result not ready yet")
306
307
# Blocking retrieval with timeout
308
try:
309
value = result(blocking=True, timeout=30)
310
print(f"Fibonacci(10) = {value}")
311
except ResultTimeout:
312
print("Task took too long")
313
```
314
315
### Advanced Result Patterns
316
317
```python
318
@huey.task()
319
def process_data(data_chunk):
320
# Simulate processing time
321
time.sleep(2)
322
return len(data_chunk)
323
324
# Process multiple chunks
325
data_chunks = [
326
[1, 2, 3], [4, 5, 6], [7, 8, 9]
327
]
328
329
results = []
330
for chunk in data_chunks:
331
result = process_data(chunk)
332
results.append(result)
333
334
# Wait for all results with timeout
335
try:
336
values = [r.get(blocking=True, timeout=10) for r in results]
337
print(f"Processed chunks: {values}")
338
except ResultTimeout:
339
print("Some tasks timed out")
340
```
341
342
### Result Groups and Batch Operations
343
344
```python
345
# Using map for batch processing
346
@huey.task()
347
def square_number(x):
348
return x * x
349
350
numbers = [1, 2, 3, 4, 5]
351
result_group = square_number.map(numbers)
352
353
# Get all results at once
354
squared = result_group.get(blocking=True, timeout=30)
355
print(f"Squared numbers: {squared}")
356
357
# Process results as they complete
358
print("Processing results as completed:")
359
for value in result_group.as_completed():
360
print(f"Got result: {value}")
361
```
362
363
### Result State Management
364
365
```python
366
@huey.task(retries=2)
367
def unreliable_task(data):
368
# Simulate unreliable operation
369
import random
370
if random.random() < 0.3:
371
raise Exception("Random failure")
372
return f"Processed: {data}"
373
374
result = unreliable_task("important_data")
375
376
# Check if task was revoked
377
if result.is_revoked():
378
print("Task was revoked")
379
result.restore() # Restore if needed
380
381
# Reschedule for later if needed
382
if some_condition:
383
new_result = result.reschedule(delay=3600) # Reschedule for 1 hour later
384
print(f"Rescheduled task: {new_result.id}")
385
```
386
387
### Result Preservation and Reuse
388
389
```python
390
@huey.task()
391
def expensive_computation(params):
392
# Simulate expensive computation
393
time.sleep(10)
394
return f"Result for {params}"
395
396
result = expensive_computation("dataset_1")
397
398
# Get result but preserve it for later use
399
value1 = result.get(preserve=True)
400
print(f"First read: {value1}")
401
402
# Can read again because preserve=True
403
value2 = result.get(preserve=True)
404
print(f"Second read: {value2}")
405
406
# Reset and read again
407
result.reset()
408
value3 = result.get()
409
print(f"After reset: {value3}")
410
```
411
412
### Monitoring Results
413
414
```python
415
# Check result store status
416
total_results = huey.result_count()
417
print(f"Total stored results: {total_results}")
418
419
# Get specific result by task ID
420
task_id = "some-task-id"
421
try:
422
value = huey.result(task_id, blocking=True, timeout=5)
423
print(f"Task {task_id} result: {value}")
424
except ResultTimeout:
425
print(f"Task {task_id} timed out")
426
427
# Get all results (be careful with large result stores)
428
if total_results < 100: # Only if reasonable number
429
all_results = huey.all_results()
430
print(f"All results: {len(all_results)} items")
431
```