我做了一个快速的谷歌搜索,并没有找到任何明确的陈述。基本上,我正在尝试从 SQS 读取事件并处理它们,而 asio 预计将由 greenlets 处理。
那么可以在greenlet中使用boto3的粒度是多少?我需要每个greenlet的会话/客户端吗?我需要额外的互斥锁吗?
Boto3 不,但你可以猴子修补 botocore。
在模块的顶部,您总是需要先进行猴子补丁,然后使用 botocore 会话,例如:
from gevent import monkey
monkey.patch_all()
import botocore.session
def fetch_file(bucket, key):
session = botocore.session.get_session()
client = session.create_client('S3')
return client.get_object(
Bucket=bucket,
Key=key
)
result = gevent.spawn(fetch_file('mybucket', 'sd.txt'))
更新 03.04.2021
我刚刚检查并验证了 gevent monkey_patch 方法适用于 boto3:
from gevent import monkey, spawn, joinall
monkey.patch_all()
import boto3 # make sure you import after doing the monkey patch
def ec2_region(region_name):
instances = 0
result = 'succeeded'
ec2 = boto3.Session().resource('ec2', region_name=region_name)
try:
result_instances = sum(1 for _ in ec2.instances.all())
except:
result = 'failed'
return f'{region_name:20}\t{result:10}\t{instances}'
regions = boto3.session.Session().get_available_regions('ec2')
jobs = [spawn(ec2_region, region_name) for region_name in regions]
joinall(jobs)
print(*[job.value for job in jobs], sep='\n')
大约需要2-3秒。
没有 gevent,例如:
import boto3
def ec2_region(region_name):
instances = 0
result = 'succeeded'
ec2 = boto3.Session().resource('ec2', region_name=region_name)
try:
result_instances = sum(1 for _ in ec2.instances.all())
except:
result = 'failed'
return f'{region_name:20}\t{result:10}\t{instances}'
regions = boto3.session.Session().get_available_regions('ec2')
jobs = [ec2_region(region_name) for region_name in regions]
print(*jobs, sep='\n')
大约需要 17 秒。
只要 botocore 使用这些套接字调用,gevent 猴子补丁就会自动修补下面的所有套接字调用。boto3 确实使用了 botocore。