Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django芹菜和asyncio-loop参数必须大约每3分钟与Future一致_Python_Django_Celery_Python Asyncio - Fatal编程技术网

Python django芹菜和asyncio-loop参数必须大约每3分钟与Future一致

Python django芹菜和asyncio-loop参数必须大约每3分钟与Future一致,python,django,celery,python-asyncio,Python,Django,Celery,Python Asyncio,我使用django芹菜和芹菜节拍来运行定期任务。我每一分钟运行一次任务,通过SNMP获取一些数据 我的函数使用asyncio,如下所示。我在代码中做了一个检查,检查循环是否闭合,并创建一个新的循环 但似乎每隔几次任务就会发生一次,我就会失败,在Django tasks results db中,我有下面的回溯。似乎每3分钟就有一次失败,但每分钟都有成功,没有失败 错误: Traceback (most recent call last): File "/usr/local/lib/python

我使用django芹菜和芹菜节拍来运行定期任务。我每一分钟运行一次任务,通过SNMP获取一些数据

我的函数使用asyncio,如下所示。我在代码中做了一个检查,检查循环是否闭合,并创建一个新的循环

但似乎每隔几次任务就会发生一次,我就会失败,在Django tasks results db中,我有下面的回溯。似乎每3分钟就有一次失败,但每分钟都有成功,没有失败

错误:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/celery/app/trace.py", line 374, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/celery/app/trace.py", line 629, in __protected_call__
    return self.run(*args, **kwargs)
  File "/itapp/itapp/monitoring/tasks.py", line 32, in link_data
    return get_link_data()
  File "/itapp/itapp/monitoring/jobs/link_monitoring.py", line 209, in get_link_data
    done, pending = loop.run_until_complete(asyncio.wait(tasks))
  File "/usr/local/lib/python3.6/asyncio/base_events.py", line 468, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 311, in wait
    fs = {ensure_future(f, loop=loop) for f in set(fs)}
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 311, in <setcomp>
    fs = {ensure_future(f, loop=loop) for f in set(fs)}
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 514, in ensure_future
    raise ValueError('loop argument must agree with Future')
ValueError: loop argument must agree with Future

从用户4815162342建议的这些URL

运行ascync函数时,除在内存中运行的函数外,任何输入输出操作都需要异步兼容。(在我的示例中是regex查询)

i、 e任何需要从另一个源(在我的示例中是django查询)收集数据的非异步兼容函数都必须在执行器中运行

我想我现在已经通过在executors中运行所有django DB调用修复了我的问题,从那以后,我再也没有遇到过运行临时脚本的问题


但是,我对芹菜和async有兼容性问题(因为芹菜与asyncio尚不兼容,这会引发一些错误,但不是我以前看到的错误)

这似乎与您之前提出的问题完全相同,然后被删除。设计似乎有缺陷,首先是您的协同程序不等待
asyncio.sleep()
之外的任何东西。抱歉,我删除了原始问题,因为脚本在经过一些调整后工作了,我认为在这一点上,它工作了2/3次,一切正常。我是Asyncio新手,所以我不太清楚你的意思?我需要该函数在snmp轮询之间等待60秒以收集数据我们已经在原始问题中进行了此对话,我回答说您应该等待任何可能阻塞的操作。我还向你介绍了更多的信息。这两本书我至少读了三遍,对于一个新手来说,这很让人困惑,但从我的理解来看,我认为我的脚本还可以,当它起作用时,我就这样认为了。我不确定我在那里有任何阻塞操作。阻塞操作需要50毫秒以上的时间吗?是这样吗?如果我有其中一个,它应该在执行器中运行?阻塞操作是任何可能等待任意时间的操作,例如,任何依赖于网络延迟或服务器响应的操作。如果您不使用与asyncio兼容的库,也不等待阻塞调用,那么使用asyncio不会给您带来任何好处。您得不到并行性,并且也得到了异常,可能是由于与某些库内部使用的另一个事件循环冲突。尝试使用普通的
def
而不是
async def
来检索数据
并将
wait asyncio.sleep()
替换为
time.sleep()
async def retrieve_data(link):
    poll_interval = 60
    results = []
    # credentials:
    link_mgmt_ip = link.mgmt_ip
    link_index = link.interface_index
    snmp_user = link.device_circuit_subnet.device.snmp_data.name
    snmp_auth = link.device_circuit_subnet.device.snmp_data.auth
    snmp_priv = link.device_circuit_subnet.device.snmp_data.priv
    hostname = link.device_circuit_subnet.device.hostname
    print('polling data for {} on {}'.format(hostname,link_mgmt_ip))

    # first poll for speeds
    download_speed_data_poll1 = snmp_get(link_mgmt_ip, down_speed_oid % link_index ,snmp_user, snmp_auth, snmp_priv)

    # check we were able to poll
    if 'timeout' in str(get_snmp_value(download_speed_data_poll1)).lower():
        return 'timeout trying to poll {} - {}'.format(hostname ,link_mgmt_ip)
    upload_speed_data_poll1 = snmp_get(link_mgmt_ip, up_speed_oid % link_index, snmp_user, snmp_auth, snmp_priv) 

    # wait for poll interval
    await asyncio.sleep(poll_interval)

    # second poll for speeds
    download_speed_data_poll2 = snmp_get(link_mgmt_ip, down_speed_oid % link_index, snmp_user, snmp_auth, snmp_priv)
    upload_speed_data_poll2 = snmp_get(link_mgmt_ip, up_speed_oid % link_index, snmp_user, snmp_auth, snmp_priv)    

    # create deltas for speed
    down_delta = int(get_snmp_value(download_speed_data_poll2)) - int(get_snmp_value(download_speed_data_poll1))
    up_delta = int(get_snmp_value(upload_speed_data_poll2)) - int(get_snmp_value(upload_speed_data_poll1))

    # set speed results
    download_speed = round((down_delta * 8 / poll_interval) / 1048576)
    upload_speed = round((up_delta * 8 / poll_interval) / 1048576)

    # get description and interface state
    int_desc = snmp_get(link_mgmt_ip, int_desc_oid % link_index, snmp_user, snmp_auth, snmp_priv)   
    int_state = snmp_get(link_mgmt_ip, int_state_oid % link_index, snmp_user, snmp_auth, snmp_priv)

    ...
    return results

def get_link_data():  
    mgmt_ip = Subquery(
        DeviceCircuitSubnets.objects.filter(device_id=OuterRef('device_circuit_subnet__device_id'),subnet__subnet_type__poll=True).values('subnet__subnet')[:1])
    link_data = LinkTargets.objects.all() \
                .select_related('device_circuit_subnet') \
                .select_related('device_circuit_subnet__device') \
                .select_related('device_circuit_subnet__device__snmp_data') \
                .select_related('device_circuit_subnet__subnet') \
                .select_related('device_circuit_subnet__circuit') \
                .annotate(mgmt_ip=mgmt_ip) 
    tasks = []
    loop = asyncio.get_event_loop()
    if asyncio.get_event_loop().is_closed():
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(asyncio.new_event_loop())

    for link in link_data:
        tasks.append(asyncio.ensure_future(retrieve_data(link)))

    if tasks:
        start = time.time()  
        done, pending = loop.run_until_complete(asyncio.wait(tasks))
        loop.close()  

        results = []
        for completed_task in done:
            results.append(completed_task.result()[0])

        end = time.time() 
        print("Poll time: {}".format(end - start))
        return 'Link data updated for {}'.format(' \n '.join(results))
    else:
        return 'no tasks defined'