A coroutine-based Python networking library that uses greenlet to provide a high-level synchronous API on top of libev event loop
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Timeout management and control flow utilities including context managers for timeouts and cooperative equivalents of standard library functions. Timeouts in gevent work cooperatively with the event loop.
Context manager and object for managing timeouts.
class Timeout:
"""
Timeout context manager and exception for cooperative timeout handling.
"""
def __init__(self, seconds=None, exception=None, ref=True, priority=-1):
"""
Create a timeout.
Parameters:
- seconds: float, timeout duration in seconds (None for no timeout)
- exception: exception to raise on timeout (Timeout by default)
- ref: bool, whether timeout should keep event loop alive
- priority: int, priority for timeout callback
"""
def start(self):
"""
Start the timeout timer.
Returns:
None
"""
def cancel(self):
"""
Cancel the timeout.
Returns:
None
"""
def close(self):
"""
Close and cleanup timeout.
Returns:
None
"""
@property
def pending(self) -> bool:
"""Whether timeout is active and pending."""
@property
def seconds(self) -> float:
"""Timeout duration in seconds."""
def __enter__(self):
"""
Enter timeout context.
Returns:
self
"""
def __exit__(self, exc_type, exc_val, exc_tb):
"""
Exit timeout context and cleanup.
Parameters:
- exc_type: exception type
- exc_val: exception value
- exc_tb: exception traceback
Returns:
None
"""Utility functions for timeout operations.
def with_timeout(seconds, function, *args, **kwargs) -> any:
"""
Run function with timeout.
Parameters:
- seconds: float, timeout in seconds
- function: callable to execute
- *args: positional arguments for function
- **kwargs: keyword arguments for function
Returns:
Function result
Raises:
Timeout: if function doesn't complete within timeout
"""import gevent
from gevent import timeout
def slow_function():
print("Starting slow operation...")
gevent.sleep(5) # Simulate 5-second operation
print("Slow operation completed!")
return "Success"
# Using timeout as context manager
try:
with timeout.Timeout(2): # 2-second timeout
result = slow_function()
print(f"Result: {result}")
except timeout.Timeout:
print("Operation timed out!")import gevent
from gevent import timeout
class CustomTimeoutError(Exception):
pass
def risky_operation():
gevent.sleep(3)
return "Completed"
try:
with timeout.Timeout(1, CustomTimeoutError("Custom timeout message")):
result = risky_operation()
print(result)
except CustomTimeoutError as e:
print(f"Custom timeout: {e}")import gevent
from gevent import timeout
def network_operation():
# Simulate network operation
gevent.sleep(2)
return "Network data received"
def fallback_operation():
return "Fallback data"
# Try network operation with timeout, use fallback if it times out
try:
result = timeout.with_timeout(1, network_operation)
print(f"Success: {result}")
except timeout.Timeout:
print("Network operation timed out, using fallback")
result = fallback_operation()
print(f"Fallback: {result}")import gevent
from gevent import timeout
def quick_task():
gevent.sleep(0.5)
return "Quick task done"
def medium_task():
gevent.sleep(2)
return "Medium task done"
def slow_task():
gevent.sleep(5)
return "Slow task done"
tasks = [
(quick_task, 1, "Quick"),
(medium_task, 3, "Medium"),
(slow_task, 4, "Slow")
]
results = []
for task_func, task_timeout, task_name in tasks:
try:
result = timeout.with_timeout(task_timeout, task_func)
results.append((task_name, result))
print(f"{task_name}: {result}")
except timeout.Timeout:
results.append((task_name, "TIMEOUT"))
print(f"{task_name}: Timed out")
print(f"\nFinal results: {results}")import gevent
from gevent import timeout
class Resource:
def __init__(self, name):
self.name = name
self.is_open = False
def open(self):
print(f"Opening resource {self.name}")
self.is_open = True
gevent.sleep(0.1) # Simulate opening time
def work(self):
if not self.is_open:
raise RuntimeError("Resource not open")
print(f"Working with resource {self.name}")
gevent.sleep(3) # Long operation
return f"Work completed with {self.name}"
def close(self):
if self.is_open:
print(f"Closing resource {self.name}")
self.is_open = False
def work_with_resource():
resource = Resource("Database")
try:
resource.open()
# Use timeout for the work operation
with timeout.Timeout(2):
result = resource.work()
return result
except timeout.Timeout:
print("Work operation timed out")
return None
finally:
# Always cleanup
resource.close()
result = work_with_resource()
print(f"Final result: {result}")import gevent
from gevent import timeout
def level3_operation():
print("Level 3: Starting")
gevent.sleep(1)
print("Level 3: Completed")
return "Level 3 result"
def level2_operation():
print("Level 2: Starting")
# Inner timeout (2 seconds)
try:
with timeout.Timeout(2):
result = level3_operation()
print("Level 2: Got result from level 3")
gevent.sleep(0.5)
return f"Level 2 processed: {result}"
except timeout.Timeout:
print("Level 2: Inner timeout occurred")
return "Level 2: Inner timeout result"
def level1_operation():
print("Level 1: Starting")
# Outer timeout (5 seconds)
try:
with timeout.Timeout(5):
result = level2_operation()
print("Level 1: Got result from level 2")
return f"Level 1 final: {result}"
except timeout.Timeout:
print("Level 1: Outer timeout occurred")
return "Level 1: Outer timeout result"
final_result = level1_operation()
print(f"Final: {final_result}")import gevent
from gevent import timeout
def worker(worker_id, work_time):
print(f"Worker {worker_id} starting ({work_time}s of work)")
gevent.sleep(work_time)
print(f"Worker {worker_id} completed")
return f"Result from worker {worker_id}"
def coordinate_workers():
workers = [
gevent.spawn(worker, 1, 1),
gevent.spawn(worker, 2, 3), # This will timeout
gevent.spawn(worker, 3, 0.5),
]
results = []
# Wait for each worker with individual timeouts
for i, w in enumerate(workers, 1):
try:
with timeout.Timeout(2):
result = w.get()
results.append(result)
except timeout.Timeout:
print(f"Worker {i} timed out, killing it")
w.kill()
results.append(f"Worker {i} timeout")
return results
results = coordinate_workers()
print(f"All results: {results}")Install with Tessl CLI
npx tessl i tessl/pypi-gevent