Coder Social home page Coder Social logo

async-await's Introduction

Socketry

Gem Version Build Status Code Climate Coverage Status MIT licensed

High-level Ruby socket library with support for TCP, UDP, and SSL sockets.

Implements thread-safe timeouts using asynchronous I/O and high-precision monotonic timers.

Motivation

By default, Ruby sockets do not provide a built-in timeout mechanism. The only timeout mechanism provided by the language leverages timeout.rb, which uses unsafe multithreaded behaviors to implement timeouts.

While Socketry provides a synchronous, blocking API similar to Ruby's own TCPSocket and UDPSocket classes, behind the scenes it uses non-blocking I/O to implement thread-safe timeouts.

Installation

Add this line to your application's Gemfile:

gem "socketry"

And then execute:

$ bundle

Or install it yourself as:

$ gem install socketry

Basic Usage

Below is a basic example of how to use Socketry to make an HTTPS request:

require "socketry"

socket = Socketry::SSL::Socket.connect("github.com", 443)
socket.writepartial("GET / HTTP/1.0\r\nHost: github.com\r\n\r\n")
p socket.readpartial(1024)

TCP, SSL, and UDP servers and sockets also available.

Documentation

Please see the Socketry wiki for more detailed documentation and usage notes.

YARD API documentation is also available.

Supported Ruby Versions

This library aims to support and is tested against the following Ruby versions:

  • Ruby 2.2.6+
  • Ruby 2.3
  • Ruby 2.4
  • Ruby 2.5
  • JRuby 9.1.6.0+

If something doesn't work on one of these versions, it's a bug.

This library may inadvertently work (or seem to work) on other Ruby versions, however support will only be provided for the versions listed above.

If you would like this library to support another Ruby version or implementation, you may volunteer to be a maintainer. Being a maintainer entails making sure all tests run and pass on that implementation. When something breaks on your implementation, you will be responsible for providing patches in a timely fashion. If critical issues for a particular implementation exist at the time of a major release, support for that Ruby version may be dropped.

Contributing

  • Fork this repository on github
  • Make your changes and send us a pull request
  • If we like them we'll merge them
  • If we've accepted a patch, feel free to ask for commit access

License

Copyright (c) 2016 Tony Arcieri. Distributed under the MIT License. See LICENSE.txt for further details.

async-await's People

Contributors

ioquatix avatar olleolleolle avatar picatz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

yesalex picatz

async-await's Issues

No result from list of single item

Running the code below, adapted from your portscanner example.
When running on a list of several items, it appears to work well.
When running on a list with a single item, it returns with nil result.

  require 'async/io'
  require 'async/await'
  require 'async/semaphore'
  require 'ipaddr'

  class PortScanner
	include Async::Await
	include Async::IO

	def self.scan_cidr_port(cidr, port)
		new(cidr, port).start.result
	end

	def initialize(cidr="127.0.0.1/32", port=80)
		@cidr = IPAddr.new(cidr)
		@port = port.to_i
		batchSize = [512, (Process.getrlimit(Process::RLIMIT_NOFILE).first * 0.9).ceil].min
		@semaphore = Async::Semaphore.new(batchSize)
	end

	def scan_port(ip, port, timeout=0.5)
		with_timeout(timeout) do
			address = Async::IO::Address.tcp(ip, port)
			socket = Socket.connect(address)
			socket.close
			return("#{ip}:#{port}")
		end
	rescue Errno::ECONNREFUSED
	rescue Async::TimeoutError
	end

	async def start(timeout=0.5)
		result = @cidr.to_range.to_a.map { |ip|
			@semaphore.async do
				x = scan_port(ip.to_s, @port, timeout)
                                puts("we get a returned value #{x}")
			end
		}.collect(&:result).reject!{|x|x.nil?}
	end

  end

  PortScanner.scan_cidr_port("127.0.0.1/32",80)
  we get a returned value 127.0.0.1:80 #  but its not collected?
  #  ==> nil
  PortScanner.scan_cidr_port("127.0.0.1/31",80)
  we get a returned value 127.0.0.1:80
  #  ==> ["127.0.0.1:80"]

It does not appear to be the first or last item of a list that is missed (reversing the order in a list makes no difference). It appears to be only when the list is a single item that it is missed. The item is being processed and value is returned, but it looks like collect doesn't collect a single item.

Is it a defect or am I misusing your tool? which by the way is brilliant. I'm only starting to understand it all yet :-)

[edited] replaced @cidr.to_enum with @cidr.to_range.to_a

Asynchronous result blocks with wait

Hello. Congrats for the job with async await.
I don't know if i got it right, but i expect that wait dont block execution.
Is there a way to do this?

require 'async/await'

class AsyncFibonnaci
  include Async::Await

  async def fibonacci(num)
    return  num if num <= 1

    fibonacci(num - 1).wait + fibonacci(num - 2).wait
  end
end

class AsyncRunner
  include Async::Await

  async def run
    5.times do |i|
      puts "loop #{i}"
      fib
    end
  end

  async def fib
    instance = AsyncFibonnaci.new
    num = rand(30)
    puts "Number was #{num}"
    result = instance.fibonacci(num).wait
    puts "Fibonacci results #{result}"
  end
end

runner = AsyncRunner.new
runner.run

README spring cleaning

Hey Samuel! Thank you so much for dragging the conversation forward. I honestly believe that bringing the async/await pattern to Ruby should be the news of the year.

I am noticing a few confusing details that I would appreciate clarification on. The chicken counting example is just slightly different between https://github.com/socketry/async-await and https://www.codeotaku.com/journal/2018-06/asynchronous-ruby/index and while I tend to defer to Github, I want to make sure that I'm not missing something important.

First up: I noticed that you mark functions with async never actually call an await function. On your blog, you call .sum(:result) and puts find_all_chickens.result, while on Github there's no mention of the :result and you call a .wait method on the "tree".

It's just confusing that you say "use the await function" and then never call await. ;)

My other question is: which functions need to be marked with async for the magic to happen? Is it callees, callers or both? It doesn't seem to hurt anything to put it on both, but I'd love to understand what's actually required.

Final question for now: what's the deal with barrier!? I see it in the sleep_sort example, which I notice also uses the .result method.

I know that open source work can be thankless. I'm excited about what you've created and I'm hoping that you can do some spring cleaning on your README so that we can take this and run with it without having to bug you.

cc @pjforde1978

async-await timeout

running the example port scanner it says to use with_timeout

Async::Reactor#timeout(...) is deprecated, use Async::Reactor#with_timeout(...) instead.

How do you do async using #with_timeout ?

Thanks,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.