{"action":"created","comment":{"url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments/78321357","id":78321357,"diff_hunk":"@@ -247,62 +324,110 @@ def __eq__(self, other):\n class EventBus(object):\n     \"\"\"Allows firing of and listening for events.\"\"\"\n \n-    def __init__(self, pool: util.ThreadPool) -> None:\n+    def __init__(self, pool: util.ThreadPool,\n+                 loop: asyncio.AbstractEventLoop) -> None:\n         \"\"\"Initialize a new event bus.\"\"\"\n         self._listeners = {}\n-        self._lock = threading.Lock()\n         self._pool = pool\n+        self._loop = loop\n+\n+    def async_listeners(self):\n+        \"\"\"Dict with events and the number of listeners.\n+\n+        This method must be run in the event loop.\n+        \"\"\"\n+        return {key: len(self._listeners[key])\n+                for key in self._listeners}\n \n     @property\n     def listeners(self):\n         \"\"\"Dict with events and the number of listeners.\"\"\"\n-        with self._lock:\n-            return {key: len(self._listeners[key])\n-                    for key in self._listeners}\n+        return run_callback_threadsafe(\n+            self._loop, self.async_listeners\n+        ).result()\n \n     def fire(self, event_type: str, event_data=None, origin=EventOrigin.local):\n         \"\"\"Fire an event.\"\"\"\n         if not self._pool.running:\n             raise HomeAssistantError('Home Assistant has shut down.')\n \n-        with self._lock:\n-            # Copy the list of the current listeners because some listeners\n-            # remove themselves as a listener while being executed which\n-            # causes the iterator to be confused.\n-            get = self._listeners.get\n-            listeners = get(MATCH_ALL, []) + get(event_type, [])\n+        self._loop.call_soon_threadsafe(self.async_fire, event_type,\n+                                        event_data, origin)\n+        return\n \n-            event = Event(event_type, event_data, origin)\n+    def async_fire(self, event_type: str, event_data=None,\n+                   origin=EventOrigin.local, wait=False):\n+        \"\"\"Fire an event.\n \n-            if event_type != EVENT_TIME_CHANGED:\n-                _LOGGER.info(\"Bus:Handling %s\", event)\n+        This method must be run in the event loop.\n+        \"\"\"\n+        # Copy the list of the current listeners because some listeners\n+        # remove themselves as a listener while being executed which\n+        # causes the iterator to be confused.\n+        get = self._listeners.get\n+        listeners = get(MATCH_ALL, []) + get(event_type, [])\n \n-            if not listeners:\n-                return\n+        event = Event(event_type, event_data, origin)\n+\n+        if event_type != EVENT_TIME_CHANGED:\n+            _LOGGER.info(\"Bus:Handling %s\", event)\n+\n+        if not listeners:\n+            return\n \n-            job_priority = JobPriority.from_event_type(event_type)\n+        job_priority = JobPriority.from_event_type(event_type)\n \n-            for func in listeners:\n-                self._pool.add_job(job_priority, (func, event))\n+        sync_jobs = []\n+        for func in listeners:\n+            if asyncio.iscoroutinefunction(func):\n+                self._loop.create_task(func(event))\n+            else:\n+                sync_jobs.append((job_priority, (func, event)))\n+\n+        # Send all the sync jobs at once, since there's a lock involved we\n+        # fire this off to a thread as well\n+        if sync_jobs:\n+            try:\n+                self._pool.add_many_jobs(sync_jobs)\n+            except:\n+                _LOGGER.info(\"Unable to queue: %s\", sync_jobs)","path":"homeassistant/core.py","position":319,"original_position":319,"commit_id":"04041989ee4bf71553fb3b8aa7436462dcfaa821","original_commit_id":"05f8f57da8c5e643a3c60e3522626aaf9949d9a0","user":{"login":"balloob","id":1444314,"avatar_url":"https://avatars.githubusercontent.com/u/1444314?v=3","gravatar_id":"","url":"https://api.github.com/users/balloob","html_url":"https://github.com/balloob","followers_url":"https://api.github.com/users/balloob/followers","following_url":"https://api.github.com/users/balloob/following{/other_user}","gists_url":"https://api.github.com/users/balloob/gists{/gist_id}","starred_url":"https://api.github.com/users/balloob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/balloob/subscriptions","organizations_url":"https://api.github.com/users/balloob/orgs","repos_url":"https://api.github.com/users/balloob/repos","events_url":"https://api.github.com/users/balloob/events{/privacy}","received_events_url":"https://api.github.com/users/balloob/received_events","type":"User","site_admin":false},"body":"Should be `_LOGGER.warning`.\r\n\r\nActually, what could be a reason that this will raise? ","created_at":"2016-09-12T06:46:58Z","updated_at":"2016-09-12T06:46:58Z","html_url":"https://github.com/home-assistant/home-assistant/pull/3248#discussion_r78321357","pull_request_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248","_links":{"self":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments/78321357"},"html":{"href":"https://github.com/home-assistant/home-assistant/pull/3248#discussion_r78321357"},"pull_request":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248"}}},"pull_request":{"url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248","id":84230374,"html_url":"https://github.com/home-assistant/home-assistant/pull/3248","diff_url":"https://github.com/home-assistant/home-assistant/pull/3248.diff","patch_url":"https://github.com/home-assistant/home-assistant/pull/3248.patch","issue_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/3248","number":3248,"state":"open","locked":false,"title":"Migrate core from threads to async awesomeness","user":{"login":"balloob","id":1444314,"avatar_url":"https://avatars.githubusercontent.com/u/1444314?v=3","gravatar_id":"","url":"https://api.github.com/users/balloob","html_url":"https://github.com/balloob","followers_url":"https://api.github.com/users/balloob/followers","following_url":"https://api.github.com/users/balloob/following{/other_user}","gists_url":"https://api.github.com/users/balloob/gists{/gist_id}","starred_url":"https://api.github.com/users/balloob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/balloob/subscriptions","organizations_url":"https://api.github.com/users/balloob/orgs","repos_url":"https://api.github.com/users/balloob/repos","events_url":"https://api.github.com/users/balloob/events{/privacy}","received_events_url":"https://api.github.com/users/balloob/received_events","type":"User","site_admin":false},"body":"Original PR #3190 by @bbangert, moved to branch on main repo to be able to collaborate easier.\r\n\r\n**Description:**\r\n\r\nThis replaces the primary mechanism by which HASS runs. \r\n\r\nThe existing architecture exposes 3 core.py API objects, EventBus, StateMachine, and ServiceRegistry. These are called from a variety of threads and are all blocking calls that attempt to acquire per-object locks to fully execute.\r\n\r\nThis change retains the existing thread-safe blocking API for use by all components, as well as the blocking nature of component setup. However, it starts up an asyncio event loop on start, which is where the actual work is done. The thread-safe API calls schedule the async API variant version into the event loop, then blocks waiting until it has run to completion.\r\n\r\nEventBus registrations that are marked as coroutines run on the event loop and may directly run async versions of the appropriate API's. To retain similar call characteristics as before, EventBus's async_fire schedules coroutines to run later on the event loop while sending non-coroutines to the thread-pool as before. This does mean that coroutine listeners are guaranteed to run *after* all listeners were located, while non-coroutines may start executing immediately in the other thread.\r\n\r\nThis WIP uses Python 3.4.4 functionality as a proving ground for the approach, using earlier 3.4 should be fine with a backported function or two for asyncio features needed (such as run_coroutine_threadsafe).","created_at":"2016-09-07T03:15:16Z","updated_at":"2016-09-12T06:46:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3f85ca4fecd94b878216766ccbaa54529df19f6e","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248/commits","review_comments_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248/comments","review_comment_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments{/number}","comments_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/3248/comments","statuses_url":"https://api.github.com/repos/home-assistant/home-assistant/statuses/04041989ee4bf71553fb3b8aa7436462dcfaa821","head":{"label":"home-assistant:feat/async-core","ref":"feat/async-core","sha":"04041989ee4bf71553fb3b8aa7436462dcfaa821","user":{"login":"home-assistant","id":13844975,"avatar_url":"https://avatars.githubusercontent.com/u/13844975?v=3","gravatar_id":"","url":"https://api.github.com/users/home-assistant","html_url":"https://github.com/home-assistant","followers_url":"https://api.github.com/users/home-assistant/followers","following_url":"https://api.github.com/users/home-assistant/following{/other_user}","gists_url":"https://api.github.com/users/home-assistant/gists{/gist_id}","starred_url":"https://api.github.com/users/home-assistant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/home-assistant/subscriptions","organizations_url":"https://api.github.com/users/home-assistant/orgs","repos_url":"https://api.github.com/users/home-assistant/repos","events_url":"https://api.github.com/users/home-assistant/events{/privacy}","received_events_url":"https://api.github.com/users/home-assistant/received_events","type":"Organization","site_admin":false},"repo":{"id":12888993,"name":"home-assistant","full_name":"home-assistant/home-assistant","owner":{"login":"home-assistant","id":13844975,"avatar_url":"https://avatars.githubusercontent.com/u/13844975?v=3","gravatar_id":"","url":"https://api.github.com/users/home-assistant","html_url":"https://github.com/home-assistant","followers_url":"https://api.github.com/users/home-assistant/followers","following_url":"https://api.github.com/users/home-assistant/following{/other_user}","gists_url":"https://api.github.com/users/home-assistant/gists{/gist_id}","starred_url":"https://api.github.com/users/home-assistant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/home-assistant/subscriptions","organizations_url":"https://api.github.com/users/home-assistant/orgs","repos_url":"https://api.github.com/users/home-assistant/repos","events_url":"https://api.github.com/users/home-assistant/events{/privacy}","received_events_url":"https://api.github.com/users/home-assistant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/home-assistant/home-assistant","description":":house_with_garden: Open-source home automation platform running on Python 3","fork":false,"url":"https://api.github.com/repos/home-assistant/home-assistant","forks_url":"https://api.github.com/repos/home-assistant/home-assistant/forks","keys_url":"https://api.github.com/repos/home-assistant/home-assistant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/home-assistant/home-assistant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/home-assistant/home-assistant/teams","hooks_url":"https://api.github.com/repos/home-assistant/home-assistant/hooks","issue_events_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/events{/number}","events_url":"https://api.github.com/repos/home-assistant/home-assistant/events","assignees_url":"https://api.github.com/repos/home-assistant/home-assistant/assignees{/user}","branches_url":"https://api.github.com/repos/home-assistant/home-assistant/branches{/branch}","tags_url":"https://api.github.com/repos/home-assistant/home-assistant/tags","blobs_url":"https://api.github.com/repos/home-assistant/home-assistant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/home-assistant/home-assistant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/home-assistant/home-assistant/git/refs{/sha}","trees_url":"https://api.github.com/repos/home-assistant/home-assistant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/home-assistant/home-assistant/statuses/{sha}","languages_url":"https://api.github.com/repos/home-assistant/home-assistant/languages","stargazers_url":"https://api.github.com/repos/home-assistant/home-assistant/stargazers","contributors_url":"https://api.github.com/repos/home-assistant/home-assistant/contributors","subscribers_url":"https://api.github.com/repos/home-assistant/home-assistant/subscribers","subscription_url":"https://api.github.com/repos/home-assistant/home-assistant/subscription","commits_url":"https://api.github.com/repos/home-assistant/home-assistant/commits{/sha}","git_commits_url":"https://api.github.com/repos/home-assistant/home-assistant/git/commits{/sha}","comments_url":"https://api.github.com/repos/home-assistant/home-assistant/comments{/number}","issue_comment_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/comments{/number}","contents_url":"https://api.github.com/repos/home-assistant/home-assistant/contents/{+path}","compare_url":"https://api.github.com/repos/home-assistant/home-assistant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/home-assistant/home-assistant/merges","archive_url":"https://api.github.com/repos/home-assistant/home-assistant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/home-assistant/home-assistant/downloads","issues_url":"https://api.github.com/repos/home-assistant/home-assistant/issues{/number}","pulls_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls{/number}","milestones_url":"https://api.github.com/repos/home-assistant/home-assistant/milestones{/number}","notifications_url":"https://api.github.com/repos/home-assistant/home-assistant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/home-assistant/home-assistant/labels{/name}","releases_url":"https://api.github.com/repos/home-assistant/home-assistant/releases{/id}","deployments_url":"https://api.github.com/repos/home-assistant/home-assistant/deployments","created_at":"2013-09-17T07:29:48Z","updated_at":"2016-09-12T00:47:57Z","pushed_at":"2016-09-12T06:34:06Z","git_url":"git://github.com/home-assistant/home-assistant.git","ssh_url":"git@github.com:home-assistant/home-assistant.git","clone_url":"https://github.com/home-assistant/home-assistant.git","svn_url":"https://github.com/home-assistant/home-assistant","homepage":"https://home-assistant.io","size":79590,"stargazers_count":4050,"watchers_count":4050,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":973,"mirror_url":null,"open_issues_count":233,"forks":973,"open_issues":233,"watchers":4050,"default_branch":"dev"}},"base":{"label":"home-assistant:dev","ref":"dev","sha":"dba78b02daa5674769cccf56b867f5266d6ec0f1","user":{"login":"home-assistant","id":13844975,"avatar_url":"https://avatars.githubusercontent.com/u/13844975?v=3","gravatar_id":"","url":"https://api.github.com/users/home-assistant","html_url":"https://github.com/home-assistant","followers_url":"https://api.github.com/users/home-assistant/followers","following_url":"https://api.github.com/users/home-assistant/following{/other_user}","gists_url":"https://api.github.com/users/home-assistant/gists{/gist_id}","starred_url":"https://api.github.com/users/home-assistant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/home-assistant/subscriptions","organizations_url":"https://api.github.com/users/home-assistant/orgs","repos_url":"https://api.github.com/users/home-assistant/repos","events_url":"https://api.github.com/users/home-assistant/events{/privacy}","received_events_url":"https://api.github.com/users/home-assistant/received_events","type":"Organization","site_admin":false},"repo":{"id":12888993,"name":"home-assistant","full_name":"home-assistant/home-assistant","owner":{"login":"home-assistant","id":13844975,"avatar_url":"https://avatars.githubusercontent.com/u/13844975?v=3","gravatar_id":"","url":"https://api.github.com/users/home-assistant","html_url":"https://github.com/home-assistant","followers_url":"https://api.github.com/users/home-assistant/followers","following_url":"https://api.github.com/users/home-assistant/following{/other_user}","gists_url":"https://api.github.com/users/home-assistant/gists{/gist_id}","starred_url":"https://api.github.com/users/home-assistant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/home-assistant/subscriptions","organizations_url":"https://api.github.com/users/home-assistant/orgs","repos_url":"https://api.github.com/users/home-assistant/repos","events_url":"https://api.github.com/users/home-assistant/events{/privacy}","received_events_url":"https://api.github.com/users/home-assistant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/home-assistant/home-assistant","description":":house_with_garden: Open-source home automation platform running on Python 3","fork":false,"url":"https://api.github.com/repos/home-assistant/home-assistant","forks_url":"https://api.github.com/repos/home-assistant/home-assistant/forks","keys_url":"https://api.github.com/repos/home-assistant/home-assistant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/home-assistant/home-assistant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/home-assistant/home-assistant/teams","hooks_url":"https://api.github.com/repos/home-assistant/home-assistant/hooks","issue_events_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/events{/number}","events_url":"https://api.github.com/repos/home-assistant/home-assistant/events","assignees_url":"https://api.github.com/repos/home-assistant/home-assistant/assignees{/user}","branches_url":"https://api.github.com/repos/home-assistant/home-assistant/branches{/branch}","tags_url":"https://api.github.com/repos/home-assistant/home-assistant/tags","blobs_url":"https://api.github.com/repos/home-assistant/home-assistant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/home-assistant/home-assistant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/home-assistant/home-assistant/git/refs{/sha}","trees_url":"https://api.github.com/repos/home-assistant/home-assistant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/home-assistant/home-assistant/statuses/{sha}","languages_url":"https://api.github.com/repos/home-assistant/home-assistant/languages","stargazers_url":"https://api.github.com/repos/home-assistant/home-assistant/stargazers","contributors_url":"https://api.github.com/repos/home-assistant/home-assistant/contributors","subscribers_url":"https://api.github.com/repos/home-assistant/home-assistant/subscribers","subscription_url":"https://api.github.com/repos/home-assistant/home-assistant/subscription","commits_url":"https://api.github.com/repos/home-assistant/home-assistant/commits{/sha}","git_commits_url":"https://api.github.com/repos/home-assistant/home-assistant/git/commits{/sha}","comments_url":"https://api.github.com/repos/home-assistant/home-assistant/comments{/number}","issue_comment_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/comments{/number}","contents_url":"https://api.github.com/repos/home-assistant/home-assistant/contents/{+path}","compare_url":"https://api.github.com/repos/home-assistant/home-assistant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/home-assistant/home-assistant/merges","archive_url":"https://api.github.com/repos/home-assistant/home-assistant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/home-assistant/home-assistant/downloads","issues_url":"https://api.github.com/repos/home-assistant/home-assistant/issues{/number}","pulls_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls{/number}","milestones_url":"https://api.github.com/repos/home-assistant/home-assistant/milestones{/number}","notifications_url":"https://api.github.com/repos/home-assistant/home-assistant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/home-assistant/home-assistant/labels{/name}","releases_url":"https://api.github.com/repos/home-assistant/home-assistant/releases{/id}","deployments_url":"https://api.github.com/repos/home-assistant/home-assistant/deployments","created_at":"2013-09-17T07:29:48Z","updated_at":"2016-09-12T00:47:57Z","pushed_at":"2016-09-12T06:34:06Z","git_url":"git://github.com/home-assistant/home-assistant.git","ssh_url":"git@github.com:home-assistant/home-assistant.git","clone_url":"https://github.com/home-assistant/home-assistant.git","svn_url":"https://github.com/home-assistant/home-assistant","homepage":"https://home-assistant.io","size":79590,"stargazers_count":4050,"watchers_count":4050,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":973,"mirror_url":null,"open_issues_count":233,"forks":973,"open_issues":233,"watchers":4050,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248"},"html":{"href":"https://github.com/home-assistant/home-assistant/pull/3248"},"issue":{"href":"https://api.github.com/repos/home-assistant/home-assistant/issues/3248"},"comments":{"href":"https://api.github.com/repos/home-assistant/home-assistant/issues/3248/comments"},"review_comments":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248/comments"},"review_comment":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3248/commits"},"statuses":{"href":"https://api.github.com/repos/home-assistant/home-assistant/statuses/04041989ee4bf71553fb3b8aa7436462dcfaa821"}}}}
{"actor":{"display_login":"balloob"}}