{"action":"created","issue":{"url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/issues/353","repository_url":"https://api.github.com/repos/StackExchange/StackExchange.Redis","labels_url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/issues/353/labels{/name}","comments_url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/issues/353/comments","events_url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/issues/353/events","html_url":"https://github.com/StackExchange/StackExchange.Redis/pull/353","id":131222395,"number":353,"title":"Remove indirection to mitigate a presumed deadlock. Fixes StackExchange/StackExchange.Redis#42.","user":{"login":"rjmooney","id":4219,"avatar_url":"https://avatars.githubusercontent.com/u/4219?v=3","gravatar_id":"","url":"https://api.github.com/users/rjmooney","html_url":"https://github.com/rjmooney","followers_url":"https://api.github.com/users/rjmooney/followers","following_url":"https://api.github.com/users/rjmooney/following{/other_user}","gists_url":"https://api.github.com/users/rjmooney/gists{/gist_id}","starred_url":"https://api.github.com/users/rjmooney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rjmooney/subscriptions","organizations_url":"https://api.github.com/users/rjmooney/orgs","repos_url":"https://api.github.com/users/rjmooney/repos","events_url":"https://api.github.com/users/rjmooney/events{/privacy}","received_events_url":"https://api.github.com/users/rjmooney/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-02-04T02:42:19Z","updated_at":"2016-02-08T15:13:35Z","closed_at":"2016-02-08T14:02:06Z","pull_request":{"url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/pulls/353","html_url":"https://github.com/StackExchange/StackExchange.Redis/pull/353","diff_url":"https://github.com/StackExchange/StackExchange.Redis/pull/353.diff","patch_url":"https://github.com/StackExchange/StackExchange.Redis/pull/353.patch"},"body":"So I ran into this issue as well. After reading through some of the comments and taking a look at the code, I noticed an unnecessary indirection in `ConnectionMultiPlexer.ConnectImpl` which appears to be causing a deadlock:\r\n\r\n```\r\n// note that task has timeouts internally, so it might take *just over* the regular timeout\r\n// wrap into task to force async execution\r\nvar task = Factory.StartNew(() => muxer.ReconfigureAsync(true, false, log, null, \"connect\").Result);\r\n```\r\n\r\nWhat's happening here is the code is spawning an async task which waits _synchronously_ on an async task result. This is bad juju. What it appears is happening next is the code blocks the context thread waiting for the wrapper task created with `Factory.StartNew` to return:\r\n\r\n```\r\nif (!task.Wait(muxer.SyncConnectTimeout(true)))\r\n```\r\n\r\nWhen the continuation from `ReconfigureAsync` returns, it waits for the context thread to become available. Since the context thread is blocked waiting for the continuation, it results in deadlock. Stephen Cleary has an [excellent description](http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) of the pattern on his blog.\r\n\r\nThe fix, I believe, is simple: spawn the `ReconfigureAsync` method directly:\r\n\r\n```\r\n// note that task has timeouts internally, so it might take *just over* the regular timeout\r\nvar task = muxer.ReconfigureAsync(true, false, log, null, \"connect\");\r\n\r\nif (!task.Wait(muxer.SyncConnectTimeout(true)))\r\n```\r\n\r\nIf I had to guess, I'd say `ReconfigureAsync` was once a synchronous method that was converted to async without updating the `ConnectImpl` implementation to remove the async wrapping. \r\n\r\nThe above is conjecture at this point, however in my limited testing it appears to solve the problem."},"comment":{"url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/issues/comments/181418595","html_url":"https://github.com/StackExchange/StackExchange.Redis/pull/353#issuecomment-181418595","issue_url":"https://api.github.com/repos/StackExchange/StackExchange.Redis/issues/353","id":181418595,"user":{"login":"NickCraver","id":454813,"avatar_url":"https://avatars.githubusercontent.com/u/454813?v=3","gravatar_id":"","url":"https://api.github.com/users/NickCraver","html_url":"https://github.com/NickCraver","followers_url":"https://api.github.com/users/NickCraver/followers","following_url":"https://api.github.com/users/NickCraver/following{/other_user}","gists_url":"https://api.github.com/users/NickCraver/gists{/gist_id}","starred_url":"https://api.github.com/users/NickCraver/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NickCraver/subscriptions","organizations_url":"https://api.github.com/users/NickCraver/orgs","repos_url":"https://api.github.com/users/NickCraver/repos","events_url":"https://api.github.com/users/NickCraver/events{/privacy}","received_events_url":"https://api.github.com/users/NickCraver/received_events","type":"User","site_admin":false},"created_at":"2016-02-08T15:13:35Z","updated_at":"2016-02-08T15:13:35Z","body":"@rjmooney heads up, new package is on NuGet with this fix: https://www.nuget.org/packages/StackExchange.Redis/1.1.572-alpha"}}