{"action":"closed","issue":{"url":"https://api.github.com/repos/zmwangx/pyonedrive/issues/20","labels_url":"https://api.github.com/repos/zmwangx/pyonedrive/issues/20/labels{/name}","comments_url":"https://api.github.com/repos/zmwangx/pyonedrive/issues/20/comments","events_url":"https://api.github.com/repos/zmwangx/pyonedrive/issues/20/events","html_url":"https://github.com/zmwangx/pyonedrive/issues/20","id":90871710,"number":20,"title":"Timeout","user":{"login":"zmwangx","id":4149852,"avatar_url":"https://avatars.githubusercontent.com/u/4149852?v=3","gravatar_id":"","url":"https://api.github.com/users/zmwangx","html_url":"https://github.com/zmwangx","followers_url":"https://api.github.com/users/zmwangx/followers","following_url":"https://api.github.com/users/zmwangx/following{/other_user}","gists_url":"https://api.github.com/users/zmwangx/gists{/gist_id}","starred_url":"https://api.github.com/users/zmwangx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmwangx/subscriptions","organizations_url":"https://api.github.com/users/zmwangx/orgs","repos_url":"https://api.github.com/users/zmwangx/repos","events_url":"https://api.github.com/users/zmwangx/events{/privacy}","received_events_url":"https://api.github.com/users/zmwangx/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/zmwangx/pyonedrive/labels/bug","name":"bug","color":"fc2929"}],"state":"closed","locked":false,"assignee":{"login":"zmwangx","id":4149852,"avatar_url":"https://avatars.githubusercontent.com/u/4149852?v=3","gravatar_id":"","url":"https://api.github.com/users/zmwangx","html_url":"https://github.com/zmwangx","followers_url":"https://api.github.com/users/zmwangx/followers","following_url":"https://api.github.com/users/zmwangx/following{/other_user}","gists_url":"https://api.github.com/users/zmwangx/gists{/gist_id}","starred_url":"https://api.github.com/users/zmwangx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zmwangx/subscriptions","organizations_url":"https://api.github.com/users/zmwangx/orgs","repos_url":"https://api.github.com/users/zmwangx/repos","events_url":"https://api.github.com/users/zmwangx/events{/privacy}","received_events_url":"https://api.github.com/users/zmwangx/received_events","type":"User","site_admin":false},"milestone":null,"comments":0,"created_at":"2015-06-25T06:41:53Z","updated_at":"2015-11-06T18:25:37Z","closed_at":"2015-11-06T18:25:37Z","body":"I just learned that [setting a timeout in `requests` doesn't guarantee a timeout](https://requests.readthedocs.org/en/latest/user/quickstart/#timeouts):\r\n\r\n> `timeout` is not a time limit on the entire response download; rather, an exception is raised if the server has not issued a response for `timeout` seconds (more precisely, if no bytes have been received on the underlying socket for `timeout` seconds).\r\n\r\nTherefore, the annoying hanging issue is explained: the timeout we set doesn't really protect us from the shitty API servers.\r\n\r\nWhat we can do:\r\n\r\n* Use something like `eventlet` (see [this SO answer](http://stackoverflow.com/a/22096841/1944784));\r\n* Run an upload `PUT` request asynchronously, and kill it after a certain timeout (this might be the best way to go).\r\n\r\nDeciding the timeout is hard, since 15 seconds for each 10MB chunk obviously won't work for everyone. I think I should change the default to 20s * number of jobs (that's definitely enough for a mediocre 10Mbps connection, which should be able to upload a 10MB chunk in 8 seconds). This way, for a standard 8 job setup, timeout will be 2m40s, which is bearable. Anyway, it is customizable. (And it should be put in a config file, so that one with bad connection don't need to specify a command line flag each time. See #21 for the config file proposal.)\r\n\r\nWhat we should do no matter what:\r\n\r\n* Set a `timeout` for all API requests using `requests.request`. That's certainly better than nothing."}}