diff --git a/README.md b/README.md index f24d237..c75c2de 100644 --- a/README.md +++ b/README.md @@ -17,29 +17,46 @@ dependencies: ## Usage ```crystal -require "json" require "cocoon" require "http/client" alias Response = HTTP::Client::Response cocoon = Cocoon::Wrapper(Response).new -channel = cocoon.wrap do - headers = HTTP::Headers{ "Accept" => "application/vnd.github.v3+json" } - HTTP::Client.get "https://api.github.com/networks/crystal-lang/crystal/events", headers: headers -end - -if resp = channel.receive - if resp.is_a?(Response) - if resp.success? - pp Array(Hash(String, JSON::Any)).from_json(resp.body) +loop do + result = cocoon.wrap do + if Random.rand > 0.5 + HTTP::Client.get("https://github.com") else - Log.warn{ HTTP::Status.new(resp.status_code).description } + raise "Connection is lost" end - elsif resp.is_a?(Exception) - Log.warn exception: resp, &.emit("Hi dear! I missed you.") end + + # something in the &block raised Exception + if result.is_a?(Exception) + puts result.message + end + + # &block is done + if result.is_a?(Response) + puts "X-GitHub-Request-Id: #{result.headers["X-GitHub-Request-Id"]}" + end + + # &block has no result or task is not ended yet + if result.is_a?(Nil) + puts "Nothing..." + end + + sleep 1 end + +# => Nothing... +# => X-GitHub-Request-Id: EF51:10C35:3A33E0D:3BCCF8A:603C72E7 +# => Connection is lost +# => X-GitHub-Request-Id: EF52:0AF5:44114C4:45B5044:603C72E9 +# => X-GitHub-Request-Id: EF53:E298:B55ADC:B9B0DF:603C72EA +# => Connection is lost +# => Connection is lost ``` ## Contributing diff --git a/example/base.cr b/example/base.cr deleted file mode 100644 index 94cbfe9..0000000 --- a/example/base.cr +++ /dev/null @@ -1,24 +0,0 @@ -require "log" -require "json" -require "../src/cocoon" -require "http/client" - -alias Response = HTTP::Client::Response -cocoon = Cocoon::Wrapper(Response).new - -channel = cocoon.wrap do - headers = HTTP::Headers{ "Accept" => "application/vnd.github.v3+json" } - HTTP::Client.get "https://api.github.com/networks/crystal-lang/crystal/events", headers: headers -end - -if resp = channel.receive - if resp.is_a?(Response) - if resp.success? - pp Array(Hash(String, JSON::Any)).from_json(resp.body) - else - Log.warn{ HTTP::Status.new(resp.status_code).description } - end - elsif resp.is_a?(Exception) - Log.warn exception: resp, &.emit("Hi dear! I missed you.") - end -end \ No newline at end of file diff --git a/sample/base.cr b/sample/base.cr new file mode 100644 index 0000000..3ff1294 --- /dev/null +++ b/sample/base.cr @@ -0,0 +1,32 @@ +require "cocoon" +require "http/client" + +alias Response = HTTP::Client::Response +cocoon = Cocoon::Wrapper(Response).new + +loop do + result = cocoon.wrap do + if Random.rand > 0.5 + HTTP::Client.get("https://github.com") + else + raise "Connection is lost" + end + end + + # something in the &block raised Exception + if result.is_a?(Exception) + puts result.message + end + + # &block is done + if result.is_a?(Response) + puts "X-GitHub-Request-Id: #{result.headers["X-GitHub-Request-Id"]}" + end + + # &block has no result or task is not ended yet + if result.is_a?(Nil) + puts "Nothing..." + end + + sleep 1 +end \ No newline at end of file diff --git a/shard.yml b/shard.yml index 1f54ec3..aa317d8 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: cocoon -version: 0.1.3 +version: 0.2.3 authors: - Sergey Fedorov diff --git a/spec/cocoon_spec.cr b/spec/cocoon_spec.cr index e95d4cc..917e74c 100644 --- a/spec/cocoon_spec.cr +++ b/spec/cocoon_spec.cr @@ -5,7 +5,7 @@ describe Cocoon do cocoon = Cocoon::Wrapper(Int32).new it "should return sum of integers" do - if result = cocoon.wrap{ 1 + 3 }.receive + if result = cocoon.wrap { 1 + 3 } result.should eq(4) end end diff --git a/src/cocoon.cr b/src/cocoon.cr index d243a71..307c8cb 100644 --- a/src/cocoon.cr +++ b/src/cocoon.cr @@ -3,28 +3,30 @@ module Cocoon class Wrapper(T) def initialize( - @result = Channel(T | Exception).new, - @output = Channel(T | Exception).new + @result = Channel(T | Exception | Nil).new, + @output = Channel(T | Exception | Nil).new ) end def wrap(&block : -> T) forall T spawn(name: "executor") do - if data = block.call - @result.send data - end - rescue ex - @result.send ex + data = block.call + @result.send data + rescue ex + @result.send ex end Fiber.yield spawn(name: "receiver") do - if data = @result.receive + select + when data = @result.receive @output.send data + else + @output.send nil end end - @output + @output.receive end end end