重新运行函数以防"if"条件失败否则继续

Re-Running the function in case "if" condition fails or else continue

我正在尝试使用 boto3 获取我的多个 SQS 队列中所有可用消息的总和。它执行得很好,但有时只有少数队列而不是所有队列返回数据,并且程序返回空集。如何使用“IF”条件解决此问题,以便函数在其中一个集合为空时重新运行? PS: 我是编程新手 导入boto3 导入时间 从日期时间导入日期时间,timedelta

sqs = boto3.client('sqs')
cloudwatch = boto3.client('cloudwatch')
asg = boto3.client('autoscaling')

response = sqs.list_queues(QueueNamePrefix ='Queue')
queuelist = response["QueueUrls"]

soa = 0.0
noi = 0.0
ABPI = 100

def SumOfAverages(queuelist, soa, response, cloudwatch):
    for eachqueue in queuelist:
        step0 = eachqueue.split('/')
        step1 = step0[4]
        response1 = cloudwatch.get_metric_statistics(
        Namespace='AWS/SQS',
        MetricName='ApproximateNumberOfMessagesVisible',
        Dimensions=[
            {
                'Name': 'QueueName',
                'Value': step1
            },
        ],
        StartTime=datetime.utcnow() - timedelta(minutes=1),
        EndTime=datetime.utcnow(),
        Period=60,
        Statistics=[
            'Average',
        ],
        
        Unit='Count'
        )
        datapoints = response1['Datapoints']
        print(datapoints)
        #*Need If Condition*
        for values in datapoints:
            averages = values['Average']
            soa += averages
    return(soa)

result = SumOfAverages(queuelist, soa, response, cloudwatch)
print(result)

您可以尝试以下方法,

方法 1:

max_tries = 3
for _ in range(max_tries):
    response1 = cloudwatch.get_metric_statistics(
        Namespace='AWS/SQS',
        MetricName='ApproximateNumberOfMessagesVisible',
        Dimensions=[
            {
                'Name': 'QueueName',
                'Value': step1
            },
        ],
        StartTime=datetime.utcnow() - timedelta(minutes=1),
        EndTime=datetime.utcnow(),
        Period=60,
        Statistics=[
            'Average',
        ],
        
        Unit='Count'
    )
    if response1['Datapoints']:
        break
else:
    raise RuntimeError

datapoints = response1['Datapoints']

只有在没有 break 调用的情况下退出循环时,才会执行 else 块。

方法 2:

基本上和上面的想法一样,但是把那个代码放在一个专用的函数中,然后你可以在上面加上decorators来重试n次。

我用这个算法

#try 5 times?
for attempt in xrange(5):
    try:
        #do_your_stuff()
        result = SumOfAverages(queuelist, soa, response, cloudwatch)
        print(result)

    except Exception as e:
        #manage exception if you need
        print("*except* %s" %e)
    else:
        #If do_your_stuff() run and ends correctly then break for loop
        break