{"action":"created","comment":{"url":"https://api.github.com/repos/ceph/ceph/pulls/comments/174460061","pull_request_review_id":103817146,"id":174460061,"diff_hunk":"@@ -508,3 +508,160 @@ The settings management implementation will make sure that if you change a\n setting value from the Python code you will see that change when accessing\n that setting from the CLI and vice-versa.\n \n+\n+How to run a controller read-write operation asynchronously?\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Some controllers might need to execute operations that alter the state of the\n+Ceph cluster. These operations might take some time to execute and to maintain\n+a good user experience in the Web UI, we need to run those operations\n+asynchronously and return immediatly to frontend some information that the\n+operations are running in the background.\n+\n+To help in the development of the above scenario we added the support for\n+asynchronous tasks. To trigger the execution of an asynchronous task we must\n+use the follwoing class method of the ``TaskManager`` class::\n+\n+  import ..tools import TaskManager\n+  # ...\n+  TaskManager.run(namespace, metadata, func, args, kwargs)\n+\n+* ``namespace`` is a string that can be used to group tasks. For instance\n+  for RBD image creation tasks we could specify ``\"rbd/create\"`` as the\n+  namespace, or conversly ``\"rbd/remove\"`` for RBD image removal tasks.\n+\n+* ``metadata`` is a dictionary where we can store key-value pairs that\n+  characterize the task. For instance, when creating a task for creating\n+  RBD images we can specify the metadata argument as\n+  ``{'pool_name': \"rbd\", image_name': \"test-img\"}``.\n+\n+* ``func`` is the python function that implements the operation code, which\n+  will be executed asynchronously.\n+\n+* ``args`` and ``kwargs`` are the positional and named argguments that will be\n+  passed to ``func`` when the task manager starts its execution.\n+\n+The ``TaskManager.run`` method triggers the asynchronous execution of function\n+``func`` and returns an ``AsyncTask`` object.\n+The ``AsyncTask`` provides the public method ``AsyncTask.wait(timeout)``, which\n+can be used to wait for the task to complete up to a timeout defined in seconds\n+and provided as an argument. If not argument is provided the ``wait`` method\n+blocks until the task is finished.\n+\n+The ``AsyncTask.wait`` is very useful for tasks that usually are fast\n+to execute but that sometimes may take a long time to run.\n+The return value of the ``AsyncTask.wait`` method is a pair ``(state, value)``\n+where ``state`` is an integer with following possible values:\n+\n+* ``VALUE_DONE = 0``\n+* ``VALUE_EXECUTING = 1``\n+* ``VALUE_EXCEPTION = 2``\n+\n+The ``value`` will store the result of the execution of function ``func`` if\n+``state == VALUE_DONE``. If ``state == VALUE_EXECUTING`` then\n+``value == None``, and if ``state == VALUE_EXCEPTION`` then ``value`` stores\n+the exception object raised by the execution of function ``func``.\n+\n+The pair ``(namespace, metadata)`` should univocally identify the task being\n+run, which means that if you try to trigger a new task that matches the same\n+``(namespace, metadata)`` pair of the currently running task, then the new task\n+is not created and you get the task object of the current running task.","path":"src/pybind/mgr/dashboard_v2/HACKING.rst","position":61,"original_position":61,"commit_id":"7a21c3a7057a5435082dcd878193ab05a240ff2d","original_commit_id":"7a21c3a7057a5435082dcd878193ab05a240ff2d","user":{"login":"jecluis","id":506918,"avatar_url":"https://avatars3.githubusercontent.com/u/506918?v=4","gravatar_id":"","url":"https://api.github.com/users/jecluis","html_url":"https://github.com/jecluis","followers_url":"https://api.github.com/users/jecluis/followers","following_url":"https://api.github.com/users/jecluis/following{/other_user}","gists_url":"https://api.github.com/users/jecluis/gists{/gist_id}","starred_url":"https://api.github.com/users/jecluis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jecluis/subscriptions","organizations_url":"https://api.github.com/users/jecluis/orgs","repos_url":"https://api.github.com/users/jecluis/repos","events_url":"https://api.github.com/users/jecluis/events{/privacy}","received_events_url":"https://api.github.com/users/jecluis/received_events","type":"User","site_admin":false},"body":"I would also mention the idempotent nature of running two calls to `run()` with the same namespace and metadata, with an example.","created_at":"2018-03-14T13:36:06Z","updated_at":"2018-03-14T13:45:33Z","html_url":"https://github.com/ceph/ceph/pull/20870#discussion_r174460061","pull_request_url":"https://api.github.com/repos/ceph/ceph/pulls/20870","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/ceph/ceph/pulls/comments/174460061"},"html":{"href":"https://github.com/ceph/ceph/pull/20870#discussion_r174460061"},"pull_request":{"href":"https://api.github.com/repos/ceph/ceph/pulls/20870"}}},"pull_request":{"url":"https://api.github.com/repos/ceph/ceph/pulls/20870","id":174678329,"html_url":"https://github.com/ceph/ceph/pull/20870","diff_url":"https://github.com/ceph/ceph/pull/20870.diff","patch_url":"https://github.com/ceph/ceph/pull/20870.patch","issue_url":"https://api.github.com/repos/ceph/ceph/issues/20870","number":20870,"state":"open","locked":false,"title":"mgr/dashboard_v2: asynchronous task support","user":{"login":"rjfd","id":17119885,"avatar_url":"https://avatars0.githubusercontent.com/u/17119885?v=4","gravatar_id":"","url":"https://api.github.com/users/rjfd","html_url":"https://github.com/rjfd","followers_url":"https://api.github.com/users/rjfd/followers","following_url":"https://api.github.com/users/rjfd/following{/other_user}","gists_url":"https://api.github.com/users/rjfd/gists{/gist_id}","starred_url":"https://api.github.com/users/rjfd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rjfd/subscriptions","organizations_url":"https://api.github.com/users/rjfd/orgs","repos_url":"https://api.github.com/users/rjfd/repos","events_url":"https://api.github.com/users/rjfd/events{/privacy}","received_events_url":"https://api.github.com/users/rjfd/received_events","type":"User","site_admin":false},"body":"This PR introduces the support for executing long-running tasks by dashboard backend controllers.\r\nThe tasks are executed asynchronously and can be queried for their respecting executing status.\r\n\r\nFor detailed information please read the changes made to `HACKING.rst` file.\r\n\r\nSigned-off-by: Ricardo Dias <rdias@suse.com>","created_at":"2018-03-13T14:31:45Z","updated_at":"2018-03-14T13:45:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bc1f6b9481e13142ec764f04813422b833b7c6c7","assignee":null,"assignees":[],"requested_reviewers":[{"login":"LenzGr","id":263427,"avatar_url":"https://avatars3.githubusercontent.com/u/263427?v=4","gravatar_id":"","url":"https://api.github.com/users/LenzGr","html_url":"https://github.com/LenzGr","followers_url":"https://api.github.com/users/LenzGr/followers","following_url":"https://api.github.com/users/LenzGr/following{/other_user}","gists_url":"https://api.github.com/users/LenzGr/gists{/gist_id}","starred_url":"https://api.github.com/users/LenzGr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LenzGr/subscriptions","organizations_url":"https://api.github.com/users/LenzGr/orgs","repos_url":"https://api.github.com/users/LenzGr/repos","events_url":"https://api.github.com/users/LenzGr/events{/privacy}","received_events_url":"https://api.github.com/users/LenzGr/received_events","type":"User","site_admin":false},{"login":"jcsp","id":944640,"avatar_url":"https://avatars3.githubusercontent.com/u/944640?v=4","gravatar_id":"","url":"https://api.github.com/users/jcsp","html_url":"https://github.com/jcsp","followers_url":"https://api.github.com/users/jcsp/followers","following_url":"https://api.github.com/users/jcsp/following{/other_user}","gists_url":"https://api.github.com/users/jcsp/gists{/gist_id}","starred_url":"https://api.github.com/users/jcsp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jcsp/subscriptions","organizations_url":"https://api.github.com/users/jcsp/orgs","repos_url":"https://api.github.com/users/jcsp/repos","events_url":"https://api.github.com/users/jcsp/events{/privacy}","received_events_url":"https://api.github.com/users/jcsp/received_events","type":"User","site_admin":false},{"login":"s0nea","id":8761082,"avatar_url":"https://avatars2.githubusercontent.com/u/8761082?v=4","gravatar_id":"","url":"https://api.github.com/users/s0nea","html_url":"https://github.com/s0nea","followers_url":"https://api.github.com/users/s0nea/followers","following_url":"https://api.github.com/users/s0nea/following{/other_user}","gists_url":"https://api.github.com/users/s0nea/gists{/gist_id}","starred_url":"https://api.github.com/users/s0nea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s0nea/subscriptions","organizations_url":"https://api.github.com/users/s0nea/orgs","repos_url":"https://api.github.com/users/s0nea/repos","events_url":"https://api.github.com/users/s0nea/events{/privacy}","received_events_url":"https://api.github.com/users/s0nea/received_events","type":"User","site_admin":false},{"login":"p-na","id":9606095,"avatar_url":"https://avatars2.githubusercontent.com/u/9606095?v=4","gravatar_id":"","url":"https://api.github.com/users/p-na","html_url":"https://github.com/p-na","followers_url":"https://api.github.com/users/p-na/followers","following_url":"https://api.github.com/users/p-na/following{/other_user}","gists_url":"https://api.github.com/users/p-na/gists{/gist_id}","starred_url":"https://api.github.com/users/p-na/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/p-na/subscriptions","organizations_url":"https://api.github.com/users/p-na/orgs","repos_url":"https://api.github.com/users/p-na/repos","events_url":"https://api.github.com/users/p-na/events{/privacy}","received_events_url":"https://api.github.com/users/p-na/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":850326757,"url":"https://api.github.com/repos/ceph/ceph/labels/dashboard","name":"dashboard","color":"68a2c1","default":false},{"id":134774006,"url":"https://api.github.com/repos/ceph/ceph/labels/feature","name":"feature","color":"00ff24","default":false},{"id":454906768,"url":"https://api.github.com/repos/ceph/ceph/labels/mgr","name":"mgr","color":"c2e0c6","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/ceph/ceph/pulls/20870/commits","review_comments_url":"https://api.github.com/repos/ceph/ceph/pulls/20870/comments","review_comment_url":"https://api.github.com/repos/ceph/ceph/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ceph/ceph/issues/20870/comments","statuses_url":"https://api.github.com/repos/ceph/ceph/statuses/7a21c3a7057a5435082dcd878193ab05a240ff2d","head":{"label":"rjfd:wip-dashboard-tasks","ref":"wip-dashboard-tasks","sha":"7a21c3a7057a5435082dcd878193ab05a240ff2d","user":{"login":"rjfd","id":17119885,"avatar_url":"https://avatars0.githubusercontent.com/u/17119885?v=4","gravatar_id":"","url":"https://api.github.com/users/rjfd","html_url":"https://github.com/rjfd","followers_url":"https://api.github.com/users/rjfd/followers","following_url":"https://api.github.com/users/rjfd/following{/other_user}","gists_url":"https://api.github.com/users/rjfd/gists{/gist_id}","starred_url":"https://api.github.com/users/rjfd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rjfd/subscriptions","organizations_url":"https://api.github.com/users/rjfd/orgs","repos_url":"https://api.github.com/users/rjfd/repos","events_url":"https://api.github.com/users/rjfd/events{/privacy}","received_events_url":"https://api.github.com/users/rjfd/received_events","type":"User","site_admin":false},"repo":{"id":51286925,"name":"ceph","full_name":"rjfd/ceph","owner":{"login":"rjfd","id":17119885,"avatar_url":"https://avatars0.githubusercontent.com/u/17119885?v=4","gravatar_id":"","url":"https://api.github.com/users/rjfd","html_url":"https://github.com/rjfd","followers_url":"https://api.github.com/users/rjfd/followers","following_url":"https://api.github.com/users/rjfd/following{/other_user}","gists_url":"https://api.github.com/users/rjfd/gists{/gist_id}","starred_url":"https://api.github.com/users/rjfd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rjfd/subscriptions","organizations_url":"https://api.github.com/users/rjfd/orgs","repos_url":"https://api.github.com/users/rjfd/repos","events_url":"https://api.github.com/users/rjfd/events{/privacy}","received_events_url":"https://api.github.com/users/rjfd/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/rjfd/ceph","description":"Ceph is a distributed object, block, and file storage platform ","fork":true,"url":"https://api.github.com/repos/rjfd/ceph","forks_url":"https://api.github.com/repos/rjfd/ceph/forks","keys_url":"https://api.github.com/repos/rjfd/ceph/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rjfd/ceph/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rjfd/ceph/teams","hooks_url":"https://api.github.com/repos/rjfd/ceph/hooks","issue_events_url":"https://api.github.com/repos/rjfd/ceph/issues/events{/number}","events_url":"https://api.github.com/repos/rjfd/ceph/events","assignees_url":"https://api.github.com/repos/rjfd/ceph/assignees{/user}","branches_url":"https://api.github.com/repos/rjfd/ceph/branches{/branch}","tags_url":"https://api.github.com/repos/rjfd/ceph/tags","blobs_url":"https://api.github.com/repos/rjfd/ceph/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rjfd/ceph/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rjfd/ceph/git/refs{/sha}","trees_url":"https://api.github.com/repos/rjfd/ceph/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rjfd/ceph/statuses/{sha}","languages_url":"https://api.github.com/repos/rjfd/ceph/languages","stargazers_url":"https://api.github.com/repos/rjfd/ceph/stargazers","contributors_url":"https://api.github.com/repos/rjfd/ceph/contributors","subscribers_url":"https://api.github.com/repos/rjfd/ceph/subscribers","subscription_url":"https://api.github.com/repos/rjfd/ceph/subscription","commits_url":"https://api.github.com/repos/rjfd/ceph/commits{/sha}","git_commits_url":"https://api.github.com/repos/rjfd/ceph/git/commits{/sha}","comments_url":"https://api.github.com/repos/rjfd/ceph/comments{/number}","issue_comment_url":"https://api.github.com/repos/rjfd/ceph/issues/comments{/number}","contents_url":"https://api.github.com/repos/rjfd/ceph/contents/{+path}","compare_url":"https://api.github.com/repos/rjfd/ceph/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rjfd/ceph/merges","archive_url":"https://api.github.com/repos/rjfd/ceph/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rjfd/ceph/downloads","issues_url":"https://api.github.com/repos/rjfd/ceph/issues{/number}","pulls_url":"https://api.github.com/repos/rjfd/ceph/pulls{/number}","milestones_url":"https://api.github.com/repos/rjfd/ceph/milestones{/number}","notifications_url":"https://api.github.com/repos/rjfd/ceph/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rjfd/ceph/labels{/name}","releases_url":"https://api.github.com/repos/rjfd/ceph/releases{/id}","deployments_url":"https://api.github.com/repos/rjfd/ceph/deployments","created_at":"2016-02-08T08:44:21Z","updated_at":"2016-02-08T08:44:38Z","pushed_at":"2018-03-13T15:20:02Z","git_url":"git://github.com/rjfd/ceph.git","ssh_url":"git@github.com:rjfd/ceph.git","clone_url":"https://github.com/rjfd/ceph.git","svn_url":"https://github.com/rjfd/ceph","homepage":"http://ceph.com","size":357939,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ceph:master","ref":"master","sha":"6aaa4a9bc4595cbad5c7d72a5d55ff8f691a03f9","user":{"login":"ceph","id":1015767,"avatar_url":"https://avatars3.githubusercontent.com/u/1015767?v=4","gravatar_id":"","url":"https://api.github.com/users/ceph","html_url":"https://github.com/ceph","followers_url":"https://api.github.com/users/ceph/followers","following_url":"https://api.github.com/users/ceph/following{/other_user}","gists_url":"https://api.github.com/users/ceph/gists{/gist_id}","starred_url":"https://api.github.com/users/ceph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ceph/subscriptions","organizations_url":"https://api.github.com/users/ceph/orgs","repos_url":"https://api.github.com/users/ceph/repos","events_url":"https://api.github.com/users/ceph/events{/privacy}","received_events_url":"https://api.github.com/users/ceph/received_events","type":"Organization","site_admin":false},"repo":{"id":2310495,"name":"ceph","full_name":"ceph/ceph","owner":{"login":"ceph","id":1015767,"avatar_url":"https://avatars3.githubusercontent.com/u/1015767?v=4","gravatar_id":"","url":"https://api.github.com/users/ceph","html_url":"https://github.com/ceph","followers_url":"https://api.github.com/users/ceph/followers","following_url":"https://api.github.com/users/ceph/following{/other_user}","gists_url":"https://api.github.com/users/ceph/gists{/gist_id}","starred_url":"https://api.github.com/users/ceph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ceph/subscriptions","organizations_url":"https://api.github.com/users/ceph/orgs","repos_url":"https://api.github.com/users/ceph/repos","events_url":"https://api.github.com/users/ceph/events{/privacy}","received_events_url":"https://api.github.com/users/ceph/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ceph/ceph","description":"Ceph is a distributed object, block, and file storage platform ","fork":false,"url":"https://api.github.com/repos/ceph/ceph","forks_url":"https://api.github.com/repos/ceph/ceph/forks","keys_url":"https://api.github.com/repos/ceph/ceph/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ceph/ceph/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ceph/ceph/teams","hooks_url":"https://api.github.com/repos/ceph/ceph/hooks","issue_events_url":"https://api.github.com/repos/ceph/ceph/issues/events{/number}","events_url":"https://api.github.com/repos/ceph/ceph/events","assignees_url":"https://api.github.com/repos/ceph/ceph/assignees{/user}","branches_url":"https://api.github.com/repos/ceph/ceph/branches{/branch}","tags_url":"https://api.github.com/repos/ceph/ceph/tags","blobs_url":"https://api.github.com/repos/ceph/ceph/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ceph/ceph/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ceph/ceph/git/refs{/sha}","trees_url":"https://api.github.com/repos/ceph/ceph/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ceph/ceph/statuses/{sha}","languages_url":"https://api.github.com/repos/ceph/ceph/languages","stargazers_url":"https://api.github.com/repos/ceph/ceph/stargazers","contributors_url":"https://api.github.com/repos/ceph/ceph/contributors","subscribers_url":"https://api.github.com/repos/ceph/ceph/subscribers","subscription_url":"https://api.github.com/repos/ceph/ceph/subscription","commits_url":"https://api.github.com/repos/ceph/ceph/commits{/sha}","git_commits_url":"https://api.github.com/repos/ceph/ceph/git/commits{/sha}","comments_url":"https://api.github.com/repos/ceph/ceph/comments{/number}","issue_comment_url":"https://api.github.com/repos/ceph/ceph/issues/comments{/number}","contents_url":"https://api.github.com/repos/ceph/ceph/contents/{+path}","compare_url":"https://api.github.com/repos/ceph/ceph/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ceph/ceph/merges","archive_url":"https://api.github.com/repos/ceph/ceph/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ceph/ceph/downloads","issues_url":"https://api.github.com/repos/ceph/ceph/issues{/number}","pulls_url":"https://api.github.com/repos/ceph/ceph/pulls{/number}","milestones_url":"https://api.github.com/repos/ceph/ceph/milestones{/number}","notifications_url":"https://api.github.com/repos/ceph/ceph/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ceph/ceph/labels{/name}","releases_url":"https://api.github.com/repos/ceph/ceph/releases{/id}","deployments_url":"https://api.github.com/repos/ceph/ceph/deployments","created_at":"2011-09-01T21:41:26Z","updated_at":"2018-03-14T12:14:17Z","pushed_at":"2018-03-14T13:26:17Z","git_url":"git://github.com/ceph/ceph.git","ssh_url":"git@github.com:ceph/ceph.git","clone_url":"https://github.com/ceph/ceph.git","svn_url":"https://github.com/ceph/ceph","homepage":"http://ceph.com","size":273405,"stargazers_count":4208,"watchers_count":4208,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2341,"mirror_url":null,"archived":false,"open_issues_count":695,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":2341,"open_issues":695,"watchers":4208,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ceph/ceph/pulls/20870"},"html":{"href":"https://github.com/ceph/ceph/pull/20870"},"issue":{"href":"https://api.github.com/repos/ceph/ceph/issues/20870"},"comments":{"href":"https://api.github.com/repos/ceph/ceph/issues/20870/comments"},"review_comments":{"href":"https://api.github.com/repos/ceph/ceph/pulls/20870/comments"},"review_comment":{"href":"https://api.github.com/repos/ceph/ceph/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ceph/ceph/pulls/20870/commits"},"statuses":{"href":"https://api.github.com/repos/ceph/ceph/statuses/7a21c3a7057a5435082dcd878193ab05a240ff2d"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"jecluis"}}