socketry/cloudflare

No async task available

meanphil opened this issue · 7 comments

Am I doing something wrong with this example? Do I need to initialize Async somehow?

irb(main):001:0> c = Rails.application.credentials.cloudflare
=> {:key=>"xxxx", :email=>"bob@example.org"}
irb(main):002:0>
irb(main):003:0> connection = Cloudflare.connect(
irb(main):004:1*   key:   c[:key],
irb(main):005:1*   email: c[:email]
irb(main):006:1> )
=> #<Cloudflare::Connection #<Async::REST::Resource #<HTTP::Protocol::Reference:0x0000000810a5cf68 @path="/client/v4", @query_string=nil, @fragment=nil, @parameters=nil> #<HTTP::Protocol::Headers:0x0000000810a5cf18 @fields=[["X-Auth-Key", "xxxx"], ["X-Auth-Email", "bob@example.org"]], @indexed={"x-auth-key"=>["1a7494de7ab1e0fa6fe7ea7aabbdd3e051fd0"], "x-auth-email"=>["bob@example.org"]}>>: value=nil>
irb(main):007:0>
irb(main):008:0> connection.accounts.first
Traceback (most recent call last):
        2: from (irb):8
        1: from (irb):8:in `first'
RuntimeError (No async task available!)
irb(main):009:0>

Ruby 2.5.3, Rails 5.2.2, Cloudflare 4.0.0, FreeBSD 11

If I try using rails runner test.rb, I get a backtrace:

23: from /usr/home/bob/cloudflare-test-site/test.rb:8:in `first'
22: from /usr/home/bob/.gem/ruby/2.5.3/gems/cloudflare-4.0.0/lib/cloudflare/paginate.rb:37:in `each'
21: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-rest-0.6.0/lib/async/rest/resource.rb:78:in `get'
20: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-rest-0.6.0/lib/async/rest/resource.rb:78:in `tap'
19: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-rest-0.6.0/lib/async/rest/representation.rb:94:in `value'
18: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-rest-0.6.0/lib/async/rest/representation.rb:83:in `value!'
17: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-rest-0.6.0/lib/async/rest/representation.rb:74:in `block (2 levels) in <class:Representation>'
16: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/middleware.rb:57:in `call'
15: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/accept_encoding.rb:48:in `call'
14: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/middleware.rb:57:in `call'
13: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/client.rb:80:in `call'
12: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/pool.rb:71:in `acquire'
11: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/pool.rb:131:in `wait_for_resource'
10: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/pool.rb:169:in `available_resource'
9: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/pool.rb:142:in `create'
8: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/client.rb:117:in `block in make_pool'
7: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-http-0.37.13/lib/async/http/url_endpoint.rb:176:in `connect'
6: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-io-1.18.2/lib/async/io/ssl_endpoint.rb:86:in `connect'
5: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-io-1.18.2/lib/async/io/host_endpoint.rb:49:in `connect'
4: from /usr/home/bob/.rubies/ruby-2.5.3/lib/ruby/2.5.0/socket.rb:227:in `foreach'
3: from /usr/home/bob/.rubies/ruby-2.5.3/lib/ruby/2.5.0/socket.rb:227:in `each'
2: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-io-1.18.2/lib/async/io/host_endpoint.rb:51:in `block in connect'
1: from /usr/home/bob/.gem/ruby/2.5.3/gems/async-io-1.18.2/lib/async/io/socket.rb:162:in `connect'
/usr/home/bob/.gem/ruby/2.5.3/gems/async-1.15.1/lib/async/task.rb:143:in `current': No async task available! (RuntimeError)

Either:

Async do
  connection.accounts.first
ensure
  connection.close
end

or:

Cloudflare.connect(key: c[:key], email: c[:email]) do |connection|
  connection.accounts.first
end

If you want the result of that block, append .result, or do everything you want inside the block, i.e.

Cloudflare.connect(key: c[:key], email: c[:email]) do |connection|
  account = connection.accounts.first
  # do something with account
end

Ah ha - thank you. I guess the README is lagging behind slightly?

Yeah do you have time to submit a PR to update the README?

Sure, but maybe in a few weeks...

Out of interest, why make this change? What was wrong with the simple rest-client before?

In no particular order:

  • Better performance through persistent HTTP/2 connections.
  • Significantly simplified interface through use of async-rest. No longer have to dump your own JSON or parse the response.
  • More straight forward implementation.
  • Better on-demand pagination transparently handled under #each.

If you want to use 3.x nothing is stopping you, and if you want to maintain 3.x I will happily help with that.