{"action":"created","issue":{"url":"https://api.github.com/repos/andymccurdy/redis-py/issues/743","repository_url":"https://api.github.com/repos/andymccurdy/redis-py","labels_url":"https://api.github.com/repos/andymccurdy/redis-py/issues/743/labels{/name}","comments_url":"https://api.github.com/repos/andymccurdy/redis-py/issues/743/comments","events_url":"https://api.github.com/repos/andymccurdy/redis-py/issues/743/events","html_url":"https://github.com/andymccurdy/redis-py/pull/743","id":156632532,"number":743,"title":"Automatically retry EINTR for Python < 3.5 to prevent duplicate command execution","user":{"login":"thomasst","id":68381,"avatar_url":"https://avatars.githubusercontent.com/u/68381?v=3","gravatar_id":"","url":"https://api.github.com/users/thomasst","html_url":"https://github.com/thomasst","followers_url":"https://api.github.com/users/thomasst/followers","following_url":"https://api.github.com/users/thomasst/following{/other_user}","gists_url":"https://api.github.com/users/thomasst/gists{/gist_id}","starred_url":"https://api.github.com/users/thomasst/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thomasst/subscriptions","organizations_url":"https://api.github.com/users/thomasst/orgs","repos_url":"https://api.github.com/users/thomasst/repos","events_url":"https://api.github.com/users/thomasst/events{/privacy}","received_events_url":"https://api.github.com/users/thomasst/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-05-24T23:34:09Z","updated_at":"2016-05-26T19:21:28Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/andymccurdy/redis-py/pulls/743","html_url":"https://github.com/andymccurdy/redis-py/pull/743","diff_url":"https://github.com/andymccurdy/redis-py/pull/743.diff","patch_url":"https://github.com/andymccurdy/redis-py/pull/743.patch"},"body":"### The problem\r\n\r\nRedis-py's `execute` commands (`StrictRedis.execute_command` and `BasePipeline.execute`) perform poor exception handling, and simply retry the entire command or pipeline in case there is a `ConnectionError`). Similarly, `SocketBuffer._read_from_socket` (and similar) perform poor exception handling, and don't check for errors like `EINTR` that may happen at any time during a system call if the process has signal handlers set up. The proper handling of `EINTR` is to retry the system call, which Python 3.5 already does (https://www.python.org/dev/peps/pep-0475/), but we need to do this in client code for older versions of Python.\r\n\r\n### How to reproduce\r\n\r\nRun the following script:\r\n\r\n```\r\nimport redis\r\nimport os\r\nimport signal\r\n\r\nprint 'PID', os.getpid()\r\n\r\nconn = redis.Redis()\r\n\r\ndef h(*args, **kwargs):\r\n    print 'signal handler', args, kwargs\r\n\r\nsignal.signal(signal.SIGINT, h)\r\nsignal.signal(signal.SIGTERM, h)\r\n\r\nconn.delete('x')\r\nfor x in range(1000000):\r\n    conn.lpush('x', x)\r\n```\r\n\r\nIn a separate shell, execute `kill PID` several times, where PID is the PID of the script above. Then, execute `kill -9 PID` to kill the script. When you verify the length of 'x', you will see that it most likely won't match up with the number that was pushed since the list now contains duplicate items."},"comment":{"url":"https://api.github.com/repos/andymccurdy/redis-py/issues/comments/221968449","html_url":"https://github.com/andymccurdy/redis-py/pull/743#issuecomment-221968449","issue_url":"https://api.github.com/repos/andymccurdy/redis-py/issues/743","id":221968449,"user":{"login":"carltongibson","id":64686,"avatar_url":"https://avatars.githubusercontent.com/u/64686?v=3","gravatar_id":"","url":"https://api.github.com/users/carltongibson","html_url":"https://github.com/carltongibson","followers_url":"https://api.github.com/users/carltongibson/followers","following_url":"https://api.github.com/users/carltongibson/following{/other_user}","gists_url":"https://api.github.com/users/carltongibson/gists{/gist_id}","starred_url":"https://api.github.com/users/carltongibson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/carltongibson/subscriptions","organizations_url":"https://api.github.com/users/carltongibson/orgs","repos_url":"https://api.github.com/users/carltongibson/repos","events_url":"https://api.github.com/users/carltongibson/events{/privacy}","received_events_url":"https://api.github.com/users/carltongibson/received_events","type":"User","site_admin":false},"created_at":"2016-05-26T19:21:27Z","updated_at":"2016-05-26T19:21:27Z","body":"@thomasst This looks great. What's you thought on adding some kind of test harness around it? (I like PRs with tests.)\r\n\r\nThe change proposed here is very clean. Having read the PEP and looked at #565 I think, yeah, why not? — If redis-py can handle this so neatly then it seems like a good addition. "}}
{"actor":{"display_login":"carltongibson"}}