pyscript icon indicating copy to clipboard operation
pyscript copied to clipboard

[ISSUE] Detected blocking call to sleep inside the event loop

Open nemiro-TECH opened this issue 2 years ago • 2 comments

Logger: homeassistant.util.async_ Source: util/async_.py:150 First occurred: 16:29:35 (14 occurrences) Last logged: 16:30:33

Detected blocking call to sleep inside the event loop. This is causing stability issues. Please report issue to the custom component author for pyscript doing blocking calls at custom_components/pyscript/eval.py, line 1906: return func(*args, **kwargs)

nemiro-TECH avatar Apr 06 '22 19:04 nemiro-TECH

This is likely due to code you are running inside pyscript. You are likely calling some function that is blocking. Please look through your code for calls to sleep or calls to packages that call sleep or do blocking I/O.

craigbarratt avatar Apr 06 '22 19:04 craigbarratt

The script seams to work but the error keeps happening. I will read through it .Thanks.

Em qua., 6 de abr. de 2022 às 16:44, Craig Barratt @.***> escreveu:

This is likely due to code you are running inside pyscript. You are likely calling some function that is blocking. Please look through your code for calls to sleep or calls to packages that call sleep or do blocking I/O.

— Reply to this email directly, view it on GitHub https://github.com/custom-components/pyscript/issues/338#issuecomment-1090696419, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQSDR24422QRSTGWIHXVOETVDXSS5ANCNFSM5SXDBOQA . You are receiving this because you authored the thread.Message ID: @.***>

nemiro-TECH avatar Apr 06 '22 19:04 nemiro-TECH

I have the same error, did you found the solution?

Emilef22 avatar Dec 05 '22 20:12 Emilef22

My same answer applies: it's almost certainly due to code you are running or functions you are calling that are blocking. You have to be sure that all code you run or call in pyscript doesn't do blocking I/O or call sleep.

craigbarratt avatar Dec 05 '22 20:12 craigbarratt

This is likely due to code you are running inside pyscript. You are likely calling some function that is blocking. Please look through your code for calls to sleep or calls to packages that call sleep or do blocking I/O.

So the sync your alexa/todoist to shopping list script can't work because it has those sleep calls?

import requests
import sys
import time
from importlib import reload
if "/config/pyscript_modules" not in sys.path:
    sys.path.append("/config/pyscript_modules")

import write_file

write_file = reload(write_file)

TODOIST_TOKEN = "11111"
TODOIST_PROJECT_ID = 22222

def get_tasks():
    get_tasks_url =f"https://api.todoist.com/rest/v1/tasks?project_id={TODOIST_PROJECT_ID}"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}"}

    status_code = 500

    while status_code is not 200:
        response = task.executor(requests.get, get_tasks_url, headers = headers)
        status_code = response.status_code
        time.sleep(1)
    json = response.json()
    return json

def add_task(item):
    url = "https://api.todoist.com/rest/v1/tasks"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}", "Content-Type" : "application/json"}
    body = {"content" : item, "project_id" : TODOIST_PROJECT_ID}
    status_code = 500

    while status_code is not 200:
        response = task.executor(requests.post, url, headers = headers, json=body)
        status_code = response.status_code
        time.sleep(1)
    if status_code == 200:
        return True
    else:
        return False

def update_task(id, content):
    url = f"https://api.todoist.com/rest/v1/tasks/{id}"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}", "Content-Type" : "application/json"}
    body = {"content" : content}
    status_code = 500

    counter = 0
    while status_code is not 204 and counter < 10:
        response = task.executor(requests.post, url, headers = headers, json=body)
        status_code = response.status_code
        time.sleep(1)
        counter += 1
    if status_code == 204:
        return True
    else:
        return False

def complete_task(id):
    url = f"https://api.todoist.com/rest/v1/tasks/{id}/close"
    headers = {"Authorization" : f"Bearer {TODOIST_TOKEN}"}
    status_code = 500

    counter = 0
    while status_code is not 204 and counter < 10:
        response = task.executor(requests.post, url, headers = headers)
        status_code = response.status_code
        time.sleep(1)
        counter += 1
    if status_code == 204:
        return True
    else:
        return False

@service
def sync_shopping_list():
    tasks = []
    json = get_tasks()
    for item in json:
        tasks.append({"name" : item["content"], "id" : str(item["id"]), "complete" : item["completed"]})

    task.executor(write_file.write_json, filename = "/config/.shopping_list.json", content=tasks)
    hass.data["shopping_list"].async_load()

@event_trigger('shopping_list_updated')
def update_shopping_list(action=None, item=None):
    if action == "add":
        add_task(item["name"])
        sync_shopping_list()
    if action == "update" and item["complete"] == False:
        update_task(item["id"],item["name"])
        sync_shopping_list()
    if action == "update" and item["complete"] == True:
        complete_task(item["id"])
        sync_shopping_list()

kmccb avatar Jul 13 '23 15:07 kmccb

Yes, doing time.sleep() in a pyscript function is really bad since it will block all HA processing. You should use task.sleep(seconds) instead.

You are calling task.executor for the url fetching, which is the correct way to avoid blocking the main event loop (you could alternatively use aiohttp - see the docs - but either way is fine). So by using task.sleep and task.executor you should be able to avoid all blocking of the main HA event loop.

craigbarratt avatar Jul 13 '23 21:07 craigbarratt