{"action":"created","comment":{"url":"https://api.github.com/repos/Tribler/tribler/pulls/comments/62745315","id":62745315,"diff_hunk":"@@ -0,0 +1,72 @@\n+import os\n+\n+from Tribler.Core.SessionConfig import SessionStartupConfig\n+\n+\n+LOCK_FILE_NAME = 'tribler.lock'\n+\n+\n+class ProcessChecker(object):\n+    \"\"\"\n+    This class contains code to check whether a Tribler process is already running.\n+    \"\"\"\n+\n+    @staticmethod\n+    def is_pid_running(pid):\n+        \"\"\"\n+        Check whether a given process ID is currently running.\n+        \"\"\"\n+        try:\n+            os.kill(pid, 0)\n+        except OSError:\n+            return False\n+        else:\n+            return True\n+\n+    def create_lock_file(self):\n+        \"\"\"\n+        Create the lock file and write the PID in it. We also create the directory structure since the ProcessChecker\n+        might be called before the .Tribler directory has been created.\n+        \"\"\"\n+        if not os.path.exists(self.statedir):\n+            os.makedirs(self.statedir)\n+\n+        with open(self.lock_file_path, 'wb') as lock_file:\n+            lock_file.write(str(os.getpid()))\n+\n+    def remove_lock_file(self):\n+        \"\"\"\n+        Remove the lock file.\n+        \"\"\"\n+        os.unlink(self.lock_file_path)\n+\n+    def get_pid_from_lock_file(self):\n+        \"\"\"\n+        Returns the PID from the lock file.\n+        \"\"\"\n+        with open(self.lock_file_path, 'rb') as lock_file:\n+            return lock_file.read()\n+\n+    def __init__(self):\n+        \"\"\"\n+        Check whether a lock file exists in the Tribler directory. If not, create the file. If it exists,\n+        check the PID that is written inside the lock file.\n+        \"\"\"\n+        self.already_running = False\n+\n+        self.statedir = SessionStartupConfig().get_state_dir()\n+        self.lock_file_path = os.path.join(self.statedir, LOCK_FILE_NAME)\n+\n+        if os.path.exists(self.lock_file_path):\n+            file_pid = self.get_pid_from_lock_file()\n+            if file_pid == str(os.getpid()):","path":"Tribler/Core/Modules/process_checker.py","position":62,"original_position":62,"commit_id":"cd7f1814f05cb890680c8a38e899596ab182fafc","original_commit_id":"cd7f1814f05cb890680c8a38e899596ab182fafc","user":{"login":"devos50","id":1707075,"avatar_url":"https://avatars.githubusercontent.com/u/1707075?v=3","gravatar_id":"","url":"https://api.github.com/users/devos50","html_url":"https://github.com/devos50","followers_url":"https://api.github.com/users/devos50/followers","following_url":"https://api.github.com/users/devos50/following{/other_user}","gists_url":"https://api.github.com/users/devos50/gists{/gist_id}","starred_url":"https://api.github.com/users/devos50/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/devos50/subscriptions","organizations_url":"https://api.github.com/users/devos50/orgs","repos_url":"https://api.github.com/users/devos50/repos","events_url":"https://api.github.com/users/devos50/events{/privacy}","received_events_url":"https://api.github.com/users/devos50/received_events","type":"User","site_admin":false},"body":"In this case, we're checking for value equality and not object equality so I think it's safer to use `==`. See for instance the following example:\r\n\r\n```\r\n>>> p = ''.join(['a', 'b'])\r\n>>> p is 'ab'\r\nFalse\r\n>>> p == 'ab'\r\nTrue\r\n```","created_at":"2016-05-10T20:25:25Z","updated_at":"2016-05-10T20:25:25Z","html_url":"https://github.com/Tribler/tribler/pull/2173#discussion_r62745315","pull_request_url":"https://api.github.com/repos/Tribler/tribler/pulls/2173","_links":{"self":{"href":"https://api.github.com/repos/Tribler/tribler/pulls/comments/62745315"},"html":{"href":"https://github.com/Tribler/tribler/pull/2173#discussion_r62745315"},"pull_request":{"href":"https://api.github.com/repos/Tribler/tribler/pulls/2173"}}},"pull_request":{"url":"https://api.github.com/repos/Tribler/tribler/pulls/2173","id":69273421,"html_url":"https://github.com/Tribler/tribler/pull/2173","diff_url":"https://github.com/Tribler/tribler/pull/2173.diff","patch_url":"https://github.com/Tribler/tribler/pull/2173.patch","issue_url":"https://api.github.com/repos/Tribler/tribler/issues/2173","number":2173,"state":"open","locked":false,"title":"WIP: Created a new process checker","user":{"login":"devos50","id":1707075,"avatar_url":"https://avatars.githubusercontent.com/u/1707075?v=3","gravatar_id":"","url":"https://api.github.com/users/devos50","html_url":"https://github.com/devos50","followers_url":"https://api.github.com/users/devos50/followers","following_url":"https://api.github.com/users/devos50/following{/other_user}","gists_url":"https://api.github.com/users/devos50/gists{/gist_id}","starred_url":"https://api.github.com/users/devos50/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/devos50/subscriptions","organizations_url":"https://api.github.com/users/devos50/orgs","repos_url":"https://api.github.com/users/devos50/repos","events_url":"https://api.github.com/users/devos50/events{/privacy}","received_events_url":"https://api.github.com/users/devos50/received_events","type":"User","site_admin":false},"body":"I've implemented a new checker that checks whether a Tribler process is already running in the specific state dir. This means that it is now possible to run several Tribler instances besides each other (under the condition they are using a separate state dir).\r\n\r\nThe method I'm using makes use of a lock file. When Tribler is in use, a `.lock` file should be written away, containing the PID of the running Tribler process. Other Tribler processes that are starting, are checking for this file and the PID inside the file to determine whether we have another Tribler running. I removed the `SingleInstanceChecker` class since we are not using that file anymore.\r\n\r\nDuring the review, please check whether no inconsistent states can occur (i.e. the checker reporting that another instance is already running while there isn't and vice versa). I think this implementation works but maybe I forgot a specific case or something like that.\r\n\r\nFixes #2148 ","created_at":"2016-05-08T16:53:11Z","updated_at":"2016-05-10T20:25:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0db74ec07fcb7f7cf8f9fea78dce0e3e341c322f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Tribler/tribler/pulls/2173/commits","review_comments_url":"https://api.github.com/repos/Tribler/tribler/pulls/2173/comments","review_comment_url":"https://api.github.com/repos/Tribler/tribler/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Tribler/tribler/issues/2173/comments","statuses_url":"https://api.github.com/repos/Tribler/tribler/statuses/cd7f1814f05cb890680c8a38e899596ab182fafc","head":{"label":"devos50:procescheck_refactor","ref":"procescheck_refactor","sha":"cd7f1814f05cb890680c8a38e899596ab182fafc","user":{"login":"devos50","id":1707075,"avatar_url":"https://avatars.githubusercontent.com/u/1707075?v=3","gravatar_id":"","url":"https://api.github.com/users/devos50","html_url":"https://github.com/devos50","followers_url":"https://api.github.com/users/devos50/followers","following_url":"https://api.github.com/users/devos50/following{/other_user}","gists_url":"https://api.github.com/users/devos50/gists{/gist_id}","starred_url":"https://api.github.com/users/devos50/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/devos50/subscriptions","organizations_url":"https://api.github.com/users/devos50/orgs","repos_url":"https://api.github.com/users/devos50/repos","events_url":"https://api.github.com/users/devos50/events{/privacy}","received_events_url":"https://api.github.com/users/devos50/received_events","type":"User","site_admin":false},"repo":{"id":45194074,"name":"tribler","full_name":"devos50/tribler","owner":{"login":"devos50","id":1707075,"avatar_url":"https://avatars.githubusercontent.com/u/1707075?v=3","gravatar_id":"","url":"https://api.github.com/users/devos50","html_url":"https://github.com/devos50","followers_url":"https://api.github.com/users/devos50/followers","following_url":"https://api.github.com/users/devos50/following{/other_user}","gists_url":"https://api.github.com/users/devos50/gists{/gist_id}","starred_url":"https://api.github.com/users/devos50/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/devos50/subscriptions","organizations_url":"https://api.github.com/users/devos50/orgs","repos_url":"https://api.github.com/users/devos50/repos","events_url":"https://api.github.com/users/devos50/events{/privacy}","received_events_url":"https://api.github.com/users/devos50/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/devos50/tribler","description":"Privacy with BitTorrent and resilient to shut down","fork":true,"url":"https://api.github.com/repos/devos50/tribler","forks_url":"https://api.github.com/repos/devos50/tribler/forks","keys_url":"https://api.github.com/repos/devos50/tribler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/devos50/tribler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/devos50/tribler/teams","hooks_url":"https://api.github.com/repos/devos50/tribler/hooks","issue_events_url":"https://api.github.com/repos/devos50/tribler/issues/events{/number}","events_url":"https://api.github.com/repos/devos50/tribler/events","assignees_url":"https://api.github.com/repos/devos50/tribler/assignees{/user}","branches_url":"https://api.github.com/repos/devos50/tribler/branches{/branch}","tags_url":"https://api.github.com/repos/devos50/tribler/tags","blobs_url":"https://api.github.com/repos/devos50/tribler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/devos50/tribler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/devos50/tribler/git/refs{/sha}","trees_url":"https://api.github.com/repos/devos50/tribler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/devos50/tribler/statuses/{sha}","languages_url":"https://api.github.com/repos/devos50/tribler/languages","stargazers_url":"https://api.github.com/repos/devos50/tribler/stargazers","contributors_url":"https://api.github.com/repos/devos50/tribler/contributors","subscribers_url":"https://api.github.com/repos/devos50/tribler/subscribers","subscription_url":"https://api.github.com/repos/devos50/tribler/subscription","commits_url":"https://api.github.com/repos/devos50/tribler/commits{/sha}","git_commits_url":"https://api.github.com/repos/devos50/tribler/git/commits{/sha}","comments_url":"https://api.github.com/repos/devos50/tribler/comments{/number}","issue_comment_url":"https://api.github.com/repos/devos50/tribler/issues/comments{/number}","contents_url":"https://api.github.com/repos/devos50/tribler/contents/{+path}","compare_url":"https://api.github.com/repos/devos50/tribler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/devos50/tribler/merges","archive_url":"https://api.github.com/repos/devos50/tribler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/devos50/tribler/downloads","issues_url":"https://api.github.com/repos/devos50/tribler/issues{/number}","pulls_url":"https://api.github.com/repos/devos50/tribler/pulls{/number}","milestones_url":"https://api.github.com/repos/devos50/tribler/milestones{/number}","notifications_url":"https://api.github.com/repos/devos50/tribler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/devos50/tribler/labels{/name}","releases_url":"https://api.github.com/repos/devos50/tribler/releases{/id}","deployments_url":"https://api.github.com/repos/devos50/tribler/deployments","created_at":"2015-10-29T15:57:50Z","updated_at":"2015-11-20T16:00:03Z","pushed_at":"2016-05-10T20:14:41Z","git_url":"git://github.com/devos50/tribler.git","ssh_url":"git@github.com:devos50/tribler.git","clone_url":"https://github.com/devos50/tribler.git","svn_url":"https://github.com/devos50/tribler","homepage":"http://www.tribler.org","size":114096,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"devel"}},"base":{"label":"Tribler:devel","ref":"devel","sha":"09f046f52fa13093fb87bb5b9db13a1a7be445ab","user":{"login":"Tribler","id":2913489,"avatar_url":"https://avatars.githubusercontent.com/u/2913489?v=3","gravatar_id":"","url":"https://api.github.com/users/Tribler","html_url":"https://github.com/Tribler","followers_url":"https://api.github.com/users/Tribler/followers","following_url":"https://api.github.com/users/Tribler/following{/other_user}","gists_url":"https://api.github.com/users/Tribler/gists{/gist_id}","starred_url":"https://api.github.com/users/Tribler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tribler/subscriptions","organizations_url":"https://api.github.com/users/Tribler/orgs","repos_url":"https://api.github.com/users/Tribler/repos","events_url":"https://api.github.com/users/Tribler/events{/privacy}","received_events_url":"https://api.github.com/users/Tribler/received_events","type":"Organization","site_admin":false},"repo":{"id":8411137,"name":"tribler","full_name":"Tribler/tribler","owner":{"login":"Tribler","id":2913489,"avatar_url":"https://avatars.githubusercontent.com/u/2913489?v=3","gravatar_id":"","url":"https://api.github.com/users/Tribler","html_url":"https://github.com/Tribler","followers_url":"https://api.github.com/users/Tribler/followers","following_url":"https://api.github.com/users/Tribler/following{/other_user}","gists_url":"https://api.github.com/users/Tribler/gists{/gist_id}","starred_url":"https://api.github.com/users/Tribler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tribler/subscriptions","organizations_url":"https://api.github.com/users/Tribler/orgs","repos_url":"https://api.github.com/users/Tribler/repos","events_url":"https://api.github.com/users/Tribler/events{/privacy}","received_events_url":"https://api.github.com/users/Tribler/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Tribler/tribler","description":"Privacy with BitTorrent and resilient to shut down","fork":false,"url":"https://api.github.com/repos/Tribler/tribler","forks_url":"https://api.github.com/repos/Tribler/tribler/forks","keys_url":"https://api.github.com/repos/Tribler/tribler/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Tribler/tribler/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Tribler/tribler/teams","hooks_url":"https://api.github.com/repos/Tribler/tribler/hooks","issue_events_url":"https://api.github.com/repos/Tribler/tribler/issues/events{/number}","events_url":"https://api.github.com/repos/Tribler/tribler/events","assignees_url":"https://api.github.com/repos/Tribler/tribler/assignees{/user}","branches_url":"https://api.github.com/repos/Tribler/tribler/branches{/branch}","tags_url":"https://api.github.com/repos/Tribler/tribler/tags","blobs_url":"https://api.github.com/repos/Tribler/tribler/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Tribler/tribler/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Tribler/tribler/git/refs{/sha}","trees_url":"https://api.github.com/repos/Tribler/tribler/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Tribler/tribler/statuses/{sha}","languages_url":"https://api.github.com/repos/Tribler/tribler/languages","stargazers_url":"https://api.github.com/repos/Tribler/tribler/stargazers","contributors_url":"https://api.github.com/repos/Tribler/tribler/contributors","subscribers_url":"https://api.github.com/repos/Tribler/tribler/subscribers","subscription_url":"https://api.github.com/repos/Tribler/tribler/subscription","commits_url":"https://api.github.com/repos/Tribler/tribler/commits{/sha}","git_commits_url":"https://api.github.com/repos/Tribler/tribler/git/commits{/sha}","comments_url":"https://api.github.com/repos/Tribler/tribler/comments{/number}","issue_comment_url":"https://api.github.com/repos/Tribler/tribler/issues/comments{/number}","contents_url":"https://api.github.com/repos/Tribler/tribler/contents/{+path}","compare_url":"https://api.github.com/repos/Tribler/tribler/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Tribler/tribler/merges","archive_url":"https://api.github.com/repos/Tribler/tribler/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Tribler/tribler/downloads","issues_url":"https://api.github.com/repos/Tribler/tribler/issues{/number}","pulls_url":"https://api.github.com/repos/Tribler/tribler/pulls{/number}","milestones_url":"https://api.github.com/repos/Tribler/tribler/milestones{/number}","notifications_url":"https://api.github.com/repos/Tribler/tribler/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Tribler/tribler/labels{/name}","releases_url":"https://api.github.com/repos/Tribler/tribler/releases{/id}","deployments_url":"https://api.github.com/repos/Tribler/tribler/deployments","created_at":"2013-02-25T14:51:58Z","updated_at":"2016-05-09T15:23:06Z","pushed_at":"2016-05-10T20:14:41Z","git_url":"git://github.com/Tribler/tribler.git","ssh_url":"git@github.com:Tribler/tribler.git","clone_url":"https://github.com/Tribler/tribler.git","svn_url":"https://github.com/Tribler/tribler","homepage":"http://www.tribler.org","size":132230,"stargazers_count":1869,"watchers_count":1869,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":201,"mirror_url":null,"open_issues_count":257,"forks":201,"open_issues":257,"watchers":1869,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/Tribler/tribler/pulls/2173"},"html":{"href":"https://github.com/Tribler/tribler/pull/2173"},"issue":{"href":"https://api.github.com/repos/Tribler/tribler/issues/2173"},"comments":{"href":"https://api.github.com/repos/Tribler/tribler/issues/2173/comments"},"review_comments":{"href":"https://api.github.com/repos/Tribler/tribler/pulls/2173/comments"},"review_comment":{"href":"https://api.github.com/repos/Tribler/tribler/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Tribler/tribler/pulls/2173/commits"},"statuses":{"href":"https://api.github.com/repos/Tribler/tribler/statuses/cd7f1814f05cb890680c8a38e899596ab182fafc"}}}}