{"action":"created","issue":{"url":"https://api.github.com/repos/manastech/crystal/issues/998","labels_url":"https://api.github.com/repos/manastech/crystal/issues/998/labels{/name}","comments_url":"https://api.github.com/repos/manastech/crystal/issues/998/comments","events_url":"https://api.github.com/repos/manastech/crystal/issues/998/events","html_url":"https://github.com/manastech/crystal/issues/998","id":95713914,"number":998,"title":"Timeout","user":{"login":"benoist","id":7202,"avatar_url":"https://avatars.githubusercontent.com/u/7202?v=3","gravatar_id":"","url":"https://api.github.com/users/benoist","html_url":"https://github.com/benoist","followers_url":"https://api.github.com/users/benoist/followers","following_url":"https://api.github.com/users/benoist/following{/other_user}","gists_url":"https://api.github.com/users/benoist/gists{/gist_id}","starred_url":"https://api.github.com/users/benoist/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benoist/subscriptions","organizations_url":"https://api.github.com/users/benoist/orgs","repos_url":"https://api.github.com/users/benoist/repos","events_url":"https://api.github.com/users/benoist/events{/privacy}","received_events_url":"https://api.github.com/users/benoist/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-07-17T18:19:27Z","updated_at":"2015-07-17T19:58:49Z","closed_at":null,"body":"Hi,\r\n\r\nI'm using the http client to perform some requests, but there is no option yet to make the request timeout after a certain amount of seconds.\r\nI was looking at ruby's timeout function as a more general timeout mechanism but that implementation is done with threads and probably doesn't fit the crystal way.\r\n\r\nI came up with something like this using channels\r\n\r\n```crystal\r\nclass Timeout(T)\r\n  class TimeoutException < Exception\r\n  end\r\n\r\n  def self.timeout(sec, &block: -> T)\r\n    timeout = Channel(Bool).new\r\n    result :: T\r\n    spawn do\r\n      sleep sec\r\n      timeout.send true\r\n    end\r\n\r\n    spawn do\r\n      result = block.call\r\n      timeout.send false\r\n    end\r\n\r\n    if timeout.receive\r\n      raise TimeoutException.new(\"Timeout after #{sec} seconds\")\r\n    else\r\n      result\r\n    end\r\n  end\r\nend\r\n```\r\n\r\nWhich enables something like\r\n\r\n```crystal\r\nresult = Timeout(Int32).timeout(5) do\r\n  count = 0\r\n  10.times do\r\n    count += 1\r\n    puts count\r\n    sleep 1\r\n  end\r\n  count\r\nend\r\nputs result\r\n```\r\n\r\nHowever this doesn't work for jobs that are stuck doing calculations for example:\r\n\r\n```crystal\r\nresult = Timeout(Int32).timeout(5) do\r\n  count = 0\r\n  loop do\r\n    count += 1\r\n  end\r\n  count\r\nend\r\nputs result\r\n```\r\n\r\nIs there a way to make that case timeout as well or do we have to wait for the multiple event loops?\r\n"},"comment":{"url":"https://api.github.com/repos/manastech/crystal/issues/comments/122395771","html_url":"https://github.com/manastech/crystal/issues/998#issuecomment-122395771","issue_url":"https://api.github.com/repos/manastech/crystal/issues/998","id":122395771,"user":{"login":"waj","id":22697,"avatar_url":"https://avatars.githubusercontent.com/u/22697?v=3","gravatar_id":"","url":"https://api.github.com/users/waj","html_url":"https://github.com/waj","followers_url":"https://api.github.com/users/waj/followers","following_url":"https://api.github.com/users/waj/following{/other_user}","gists_url":"https://api.github.com/users/waj/gists{/gist_id}","starred_url":"https://api.github.com/users/waj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/waj/subscriptions","organizations_url":"https://api.github.com/users/waj/orgs","repos_url":"https://api.github.com/users/waj/repos","events_url":"https://api.github.com/users/waj/events{/privacy}","received_events_url":"https://api.github.com/users/waj/received_events","type":"User","site_admin":false},"created_at":"2015-07-17T19:58:49Z","updated_at":"2015-07-17T19:58:49Z","body":"Every IO operation should have a timeout. We could do this either by call (adding a timeout parameter to IO#read and IO#write) or by IO instance."}}