{"action":"created","issue":{"url":"https://api.github.com/repos/bgrainger/MySqlConnector/issues/62","repository_url":"https://api.github.com/repos/bgrainger/MySqlConnector","labels_url":"https://api.github.com/repos/bgrainger/MySqlConnector/issues/62/labels{/name}","comments_url":"https://api.github.com/repos/bgrainger/MySqlConnector/issues/62/comments","events_url":"https://api.github.com/repos/bgrainger/MySqlConnector/issues/62/events","html_url":"https://github.com/bgrainger/MySqlConnector/issues/62","id":179050152,"number":62,"title":"Prevent Thread Pool Starvation in Synchronous Methods","user":{"login":"caleblloyd","id":2414837,"avatar_url":"https://avatars.githubusercontent.com/u/2414837?v=3","gravatar_id":"","url":"https://api.github.com/users/caleblloyd","html_url":"https://github.com/caleblloyd","followers_url":"https://api.github.com/users/caleblloyd/followers","following_url":"https://api.github.com/users/caleblloyd/following{/other_user}","gists_url":"https://api.github.com/users/caleblloyd/gists{/gist_id}","starred_url":"https://api.github.com/users/caleblloyd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caleblloyd/subscriptions","organizations_url":"https://api.github.com/users/caleblloyd/orgs","repos_url":"https://api.github.com/users/caleblloyd/repos","events_url":"https://api.github.com/users/caleblloyd/events{/privacy}","received_events_url":"https://api.github.com/users/caleblloyd/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":17,"created_at":"2016-09-24T20:28:56Z","updated_at":"2016-09-26T22:06:40Z","closed_at":null,"body":"Right now, synchronous methods are implement as:\r\n\r\n    Task.GetAwaiter().GetResult()\r\n\r\nThis causes the running thread to schedule a background thread to do the work, and block until the result is available.  This can lead to thread pool starvation, especially in the case of a web server.\r\n\r\nFor example, if the thread pool size is 25 and a web request comes in, there are 24 available threads.  Then `Connection.Open` gets synchronously called, and that calls `Connection.OpenAsync().GetAwaiter().GetResult()`.  The current thread blocks and starts a background thread to open the connection, so now there are 23 available threads.\r\n\r\nIf a flood of more requests come in, there can be a situation where there are no available threads to schedule the `Connection.OpenAsync().GetAwaiter().GetResult()` calls on.  The app completely locks up at this point.\r\n\r\nI think we should look for a way to run these synchronous tasks on the currently executing thread if possible.  Either that or schedule the Async work to run on a reserved background thread.  @bgrainger , what's your opinion of the best approach?\r\n\r\nYou can see the thread pool starvation happen if you run the performance stress test with synchronous targets.  I get lockups around 200+ Requests Per Second."},"comment":{"url":"https://api.github.com/repos/bgrainger/MySqlConnector/issues/comments/249711887","html_url":"https://github.com/bgrainger/MySqlConnector/issues/62#issuecomment-249711887","issue_url":"https://api.github.com/repos/bgrainger/MySqlConnector/issues/62","id":249711887,"user":{"login":"caleblloyd","id":2414837,"avatar_url":"https://avatars.githubusercontent.com/u/2414837?v=3","gravatar_id":"","url":"https://api.github.com/users/caleblloyd","html_url":"https://github.com/caleblloyd","followers_url":"https://api.github.com/users/caleblloyd/followers","following_url":"https://api.github.com/users/caleblloyd/following{/other_user}","gists_url":"https://api.github.com/users/caleblloyd/gists{/gist_id}","starred_url":"https://api.github.com/users/caleblloyd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caleblloyd/subscriptions","organizations_url":"https://api.github.com/users/caleblloyd/orgs","repos_url":"https://api.github.com/users/caleblloyd/repos","events_url":"https://api.github.com/users/caleblloyd/events{/privacy}","received_events_url":"https://api.github.com/users/caleblloyd/received_events","type":"User","site_admin":false},"created_at":"2016-09-26T22:06:40Z","updated_at":"2016-09-26T22:06:40Z","body":"@bgrainger I like it, the use of the enum makes things less confusing.  `ReadAsync(asyncIO)` was much more confusing due to the dual meanings of the word async.\r\n\r\nI am curious to know, will Synchronous IO requests that are in progress get interrupted by a CancellationToken?  I was trying to figure out how to interrupt a Synchronous `OpenSocket` function.\r\n\r\nWe should revert to the Connection Timeout Logic that you wrote in:\r\n\r\n- https://github.com/bgrainger/MySqlConnector/commit/db94248d39150133ca77dd25b771e7454f5283f9\r\n- https://github.com/bgrainger/MySqlConnector/commit/1567935cebff6306155c6433fb756f3d90eff048\r\n- https://github.com/bgrainger/MySqlConnector/commit/db94248d39150133ca77dd25b771e7454f5283f9"}}
{"actor":{"display_login":"caleblloyd"}}