mt-libuv 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +22 -0
 - data/.gitmodules +6 -0
 - data/.rspec +1 -0
 - data/.travis.yml +24 -0
 - data/Gemfile +9 -0
 - data/LICENSE +24 -0
 - data/README.md +195 -0
 - data/Rakefile +31 -0
 - data/ext/README.md +6 -0
 - data/ext/Rakefile +28 -0
 - data/lib/mt-libuv/async.rb +51 -0
 - data/lib/mt-libuv/check.rb +59 -0
 - data/lib/mt-libuv/coroutines.rb +79 -0
 - data/lib/mt-libuv/dns.rb +98 -0
 - data/lib/mt-libuv/error.rb +88 -0
 - data/lib/mt-libuv/ext/ext.rb +322 -0
 - data/lib/mt-libuv/ext/platform/darwin_x64.rb +61 -0
 - data/lib/mt-libuv/ext/platform/unix.rb +69 -0
 - data/lib/mt-libuv/ext/platform/windows.rb +83 -0
 - data/lib/mt-libuv/ext/tasks/mac.rb +24 -0
 - data/lib/mt-libuv/ext/tasks/unix.rb +42 -0
 - data/lib/mt-libuv/ext/tasks/win.rb +29 -0
 - data/lib/mt-libuv/ext/tasks.rb +27 -0
 - data/lib/mt-libuv/ext/types.rb +253 -0
 - data/lib/mt-libuv/fiber_pool.rb +83 -0
 - data/lib/mt-libuv/file.rb +309 -0
 - data/lib/mt-libuv/filesystem.rb +263 -0
 - data/lib/mt-libuv/fs_event.rb +37 -0
 - data/lib/mt-libuv/handle.rb +108 -0
 - data/lib/mt-libuv/idle.rb +59 -0
 - data/lib/mt-libuv/mixins/accessors.rb +41 -0
 - data/lib/mt-libuv/mixins/assertions.rb +25 -0
 - data/lib/mt-libuv/mixins/fs_checks.rb +96 -0
 - data/lib/mt-libuv/mixins/listener.rb +69 -0
 - data/lib/mt-libuv/mixins/net.rb +42 -0
 - data/lib/mt-libuv/mixins/resource.rb +30 -0
 - data/lib/mt-libuv/mixins/stream.rb +276 -0
 - data/lib/mt-libuv/pipe.rb +217 -0
 - data/lib/mt-libuv/prepare.rb +59 -0
 - data/lib/mt-libuv/q.rb +475 -0
 - data/lib/mt-libuv/reactor.rb +567 -0
 - data/lib/mt-libuv/signal.rb +62 -0
 - data/lib/mt-libuv/spawn.rb +113 -0
 - data/lib/mt-libuv/tcp.rb +465 -0
 - data/lib/mt-libuv/timer.rb +107 -0
 - data/lib/mt-libuv/tty.rb +42 -0
 - data/lib/mt-libuv/udp.rb +302 -0
 - data/lib/mt-libuv/version.rb +5 -0
 - data/lib/mt-libuv/work.rb +86 -0
 - data/lib/mt-libuv.rb +80 -0
 - data/mt-libuv.gemspec +62 -0
 - data/spec/async_spec.rb +67 -0
 - data/spec/coroutines_spec.rb +121 -0
 - data/spec/cpu_spec.rb +10 -0
 - data/spec/defer_spec.rb +906 -0
 - data/spec/dns_spec.rb +110 -0
 - data/spec/dsl_spec.rb +43 -0
 - data/spec/filesystem_spec.rb +270 -0
 - data/spec/idle_spec.rb +44 -0
 - data/spec/pipe_spec.rb +151 -0
 - data/spec/spawn_spec.rb +119 -0
 - data/spec/tcp_spec.rb +272 -0
 - data/spec/test.sh +4 -0
 - data/spec/test_fail.sh +3 -0
 - data/spec/test_read.sh +3 -0
 - data/spec/timer_spec.rb +14 -0
 - data/spec/udp_spec.rb +73 -0
 - data/spec/zen_spec.rb +34 -0
 - metadata +196 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 55ed231748185b35f9e88cb285439d40bc75172b4c0133badf659b6a70be6969
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 51622861571ac5be5a93e06ee86e64f5c92ed3b4bbd37236717999694c60b5cc
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 3e1d126ffe76a1eb330bdb3203293088d0826270151c7e15cd6db1c09874304a2d745f5ba5909ab48268d9775a909da75f920e799a2c291229a280c1463099da
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c30c8f7243fc969d1ae70b1e587a89f31ec49f552a085eccdf45ab031989f27731423373eb633a4e11f7def2d7ab4f2b3874ba2599d73f77c35a94a4f950494a
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/.gitmodules
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --format progress
         
     | 
    
        data/.travis.yml
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            language: ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            rvm:
         
     | 
| 
      
 3 
     | 
    
         
            +
              - ruby-2.3.5
         
     | 
| 
      
 4 
     | 
    
         
            +
              - ruby-2.4.2
         
     | 
| 
      
 5 
     | 
    
         
            +
              - ruby-head
         
     | 
| 
      
 6 
     | 
    
         
            +
              - rubinius
         
     | 
| 
      
 7 
     | 
    
         
            +
              - jruby-9.1.13.0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - jruby-head
         
     | 
| 
      
 9 
     | 
    
         
            +
            branches:
         
     | 
| 
      
 10 
     | 
    
         
            +
              only:
         
     | 
| 
      
 11 
     | 
    
         
            +
                - master
         
     | 
| 
      
 12 
     | 
    
         
            +
            before_install:
         
     | 
| 
      
 13 
     | 
    
         
            +
              - git submodule update --init --recursive
         
     | 
| 
      
 14 
     | 
    
         
            +
              - gem install ffi
         
     | 
| 
      
 15 
     | 
    
         
            +
            before_script:
         
     | 
| 
      
 16 
     | 
    
         
            +
              - rake compile
         
     | 
| 
      
 17 
     | 
    
         
            +
            sudo: false
         
     | 
| 
      
 18 
     | 
    
         
            +
            matrix:
         
     | 
| 
      
 19 
     | 
    
         
            +
              allow_failures:
         
     | 
| 
      
 20 
     | 
    
         
            +
                - rvm: jruby-head
         
     | 
| 
      
 21 
     | 
    
         
            +
                - rvm: ruby-head
         
     | 
| 
      
 22 
     | 
    
         
            +
                - rvm: rubinius
         
     | 
| 
      
 23 
     | 
    
         
            +
            sudo: required
         
     | 
| 
      
 24 
     | 
    
         
            +
            dist: trusty
         
     | 
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2004-2013 Cotag Media
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 4 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 5 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 6 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 7 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is furnished
         
     | 
| 
      
 8 
     | 
    
         
            +
            to do so, subject to the following conditions:
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in all
         
     | 
| 
      
 11 
     | 
    
         
            +
            copies or substantial portions of the Software.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 14 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 15 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 16 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 17 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 18 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 19 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ===
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            This license applies to all parts of uvrb (Ruby FFI bindings for libuv only)
         
     | 
| 
      
 24 
     | 
    
         
            +
            Libuv itself [is using Node license](https://github.com/joyent/libuv/blob/master/LICENSE)
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,195 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Libuv FFI bindings for Ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            [](https://travis-ci.org/cotag/libuv)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            [Libuv](https://github.com/libuv/libuv) is a cross platform asynchronous IO implementation that powers NodeJS. It supports sockets, both UDP and TCP, filesystem watch, TTY, Pipes and other asynchronous primitives like timer, check, prepare and idle.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            The Libuv gem contains Libuv and a Ruby wrapper that implements [pipelined promises](http://en.wikipedia.org/wiki/Futures_and_promises#Promise_pipelining) for asynchronous flow control and [coroutines](http://en.wikipedia.org/wiki/Coroutine) / [futures](https://en.wikipedia.org/wiki/Futures_and_promises) for untangling evented code
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Libuv supports multiple reactors that can run on different threads.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            For convenience the thread local or default reactor can be accessed via the `reactor` method
         
     | 
| 
      
 14 
     | 
    
         
            +
            You can pass a block to be executed on the reactor and the reactor will run until there is nothing left to do.
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 17 
     | 
    
         
            +
              require 'libuv'
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              reactor do |reactor|
         
     | 
| 
      
 20 
     | 
    
         
            +
                reactor.timer {
         
     | 
| 
      
 21 
     | 
    
         
            +
                  puts "5 seconds passed"
         
     | 
| 
      
 22 
     | 
    
         
            +
                }.start(5000)
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              puts "reactor stopped. No more IO to process"
         
     | 
| 
      
 26 
     | 
    
         
            +
            ```
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            Promises are used to simplify code flow.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 31 
     | 
    
         
            +
              require 'libuv'
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              reactor do |reactor|
         
     | 
| 
      
 34 
     | 
    
         
            +
                reactor.tcp { |data, socket|
         
     | 
| 
      
 35 
     | 
    
         
            +
                  puts "received: #{data}"
         
     | 
| 
      
 36 
     | 
    
         
            +
                  socket.close
         
     | 
| 
      
 37 
     | 
    
         
            +
                }
         
     | 
| 
      
 38 
     | 
    
         
            +
                .connect('127.0.0.1', 3000) { |socket|
         
     | 
| 
      
 39 
     | 
    
         
            +
                  socket.start_read
         
     | 
| 
      
 40 
     | 
    
         
            +
                        .write("GET / HTTP/1.1\r\n\r\n")
         
     | 
| 
      
 41 
     | 
    
         
            +
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                .catch { |error|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  puts "error: #{error}"
         
     | 
| 
      
 44 
     | 
    
         
            +
                }
         
     | 
| 
      
 45 
     | 
    
         
            +
                .finally {
         
     | 
| 
      
 46 
     | 
    
         
            +
                  puts "socket closed"
         
     | 
| 
      
 47 
     | 
    
         
            +
                }
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            ```
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            Continuations are used if callbacks are not defined
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 54 
     | 
    
         
            +
              require 'libuv'
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              reactor do |reactor|
         
     | 
| 
      
 57 
     | 
    
         
            +
                begin
         
     | 
| 
      
 58 
     | 
    
         
            +
                  reactor.tcp { |data, socket|
         
     | 
| 
      
 59 
     | 
    
         
            +
                    puts "received: #{data}"
         
     | 
| 
      
 60 
     | 
    
         
            +
                    socket.close
         
     | 
| 
      
 61 
     | 
    
         
            +
                  }
         
     | 
| 
      
 62 
     | 
    
         
            +
                  .connect('127.0.0.1', 3000)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  .start_read
         
     | 
| 
      
 64 
     | 
    
         
            +
                  .write("GET / HTTP/1.1\r\n\r\n")
         
     | 
| 
      
 65 
     | 
    
         
            +
                rescue => error
         
     | 
| 
      
 66 
     | 
    
         
            +
                  puts "error: #{error}"
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
            ```
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            Any promise can be converted into a continuation
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 74 
     | 
    
         
            +
              require 'libuv'
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              reactor do |reactor|
         
     | 
| 
      
 77 
     | 
    
         
            +
                # Perform work on the thread pool with promises
         
     | 
| 
      
 78 
     | 
    
         
            +
                reactor.work {
         
     | 
| 
      
 79 
     | 
    
         
            +
                  10 * 2
         
     | 
| 
      
 80 
     | 
    
         
            +
                }.then { |result|
         
     | 
| 
      
 81 
     | 
    
         
            +
                  puts "result using a promise #{result}"
         
     | 
| 
      
 82 
     | 
    
         
            +
                }
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                # Use the coroutine helper to obtain the result without a callback
         
     | 
| 
      
 85 
     | 
    
         
            +
                result = reactor.work {
         
     | 
| 
      
 86 
     | 
    
         
            +
                  10 * 3
         
     | 
| 
      
 87 
     | 
    
         
            +
                }.value
         
     | 
| 
      
 88 
     | 
    
         
            +
                puts "no additional callbacks here #{result}"
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
            ```
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            Check out the [yard documentation](http://rubydoc.info/gems/libuv/Libuv/Reactor)
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            ```shell
         
     | 
| 
      
 99 
     | 
    
         
            +
              gem install libuv
         
     | 
| 
      
 100 
     | 
    
         
            +
            ```
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            or
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            ```shell
         
     | 
| 
      
 105 
     | 
    
         
            +
              git clone https://github.com/cotag/libuv.git
         
     | 
| 
      
 106 
     | 
    
         
            +
              cd libuv
         
     | 
| 
      
 107 
     | 
    
         
            +
              bundle install
         
     | 
| 
      
 108 
     | 
    
         
            +
              rake compile
         
     | 
| 
      
 109 
     | 
    
         
            +
            ```
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            ### Prerequisites
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            * The installation on BSD/Linux requires [python 2.x](http://www.python.org/getit/) to be installed and available on the PATH
         
     | 
| 
      
 114 
     | 
    
         
            +
            * setting the environmental variable `USE_GLOBAL_LIBUV` will prevent compiling the packaged version.
         
     | 
| 
      
 115 
     | 
    
         
            +
              * if you have a compatible `libuv.(so | dylib | dll)` on the PATH already
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            On Windows the GEM ships with a pre-compiled binary. If you would like to build yourself:
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            - A copy of Visual Studio 2017. [Visual Studio Build Tools](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017) works fine.
         
     | 
| 
      
 120 
     | 
    
         
            +
              - Windows 10 SDK
         
     | 
| 
      
 121 
     | 
    
         
            +
              - C++/CLI Support
         
     | 
| 
      
 122 
     | 
    
         
            +
              - C++ tools for CMake
         
     | 
| 
      
 123 
     | 
    
         
            +
            - A copy of [OpenSSL](http://slproweb.com/products/Win32OpenSSL.html) x64 - ~30MB installs
         
     | 
| 
      
 124 
     | 
    
         
            +
              - ruby 2.4+ x64 with MSYS2 is preferred
         
     | 
| 
      
 125 
     | 
    
         
            +
            - Add the env var `set GYP_MSVS_VERSION=2017`
         
     | 
| 
      
 126 
     | 
    
         
            +
            - If using jRuby then [GCC](http://win-builds.org/stable/) is also required
         
     | 
| 
      
 127 
     | 
    
         
            +
              - Setup the paths as described on the gcc page
         
     | 
| 
      
 128 
     | 
    
         
            +
              - Add required environmental variable `set LIBRARY_PATH=X:\win-builds-64\lib;X:\win-builds-64\x86_64-w64-mingw32\lib`
         
     | 
| 
      
 129 
     | 
    
         
            +
            - `rake compile`
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            ## Features
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
            * TCP (with TLS support)
         
     | 
| 
      
 136 
     | 
    
         
            +
            * UDP
         
     | 
| 
      
 137 
     | 
    
         
            +
            * TTY
         
     | 
| 
      
 138 
     | 
    
         
            +
            * Pipes
         
     | 
| 
      
 139 
     | 
    
         
            +
            * Timer
         
     | 
| 
      
 140 
     | 
    
         
            +
            * Prepare
         
     | 
| 
      
 141 
     | 
    
         
            +
            * Check
         
     | 
| 
      
 142 
     | 
    
         
            +
            * Idle
         
     | 
| 
      
 143 
     | 
    
         
            +
            * Signals
         
     | 
| 
      
 144 
     | 
    
         
            +
            * Async callbacks
         
     | 
| 
      
 145 
     | 
    
         
            +
            * Async DNS Resolution
         
     | 
| 
      
 146 
     | 
    
         
            +
            * Filesystem Events
         
     | 
| 
      
 147 
     | 
    
         
            +
            * Filesystem manipulation
         
     | 
| 
      
 148 
     | 
    
         
            +
            * File manipulation
         
     | 
| 
      
 149 
     | 
    
         
            +
            * Errors (with a catch-all fallback for anything unhandled on the event reactor)
         
     | 
| 
      
 150 
     | 
    
         
            +
            * Work queue (thread pool)
         
     | 
| 
      
 151 
     | 
    
         
            +
            * Coroutines / futures (makes use of Fibers)
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            ### Server Name Indication
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            You can host a TLS enabled server with multiple hostnames using SNI.
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 158 
     | 
    
         
            +
            server = reactor.tcp
         
     | 
| 
      
 159 
     | 
    
         
            +
            server.bind('0.0.0.0', 3000, **{
         
     | 
| 
      
 160 
     | 
    
         
            +
                hosts: [{
         
     | 
| 
      
 161 
     | 
    
         
            +
                    private_key: '/blah.key',
         
     | 
| 
      
 162 
     | 
    
         
            +
                    cert_chain: '/blah.crt',
         
     | 
| 
      
 163 
     | 
    
         
            +
                    host_name: 'somehost.com',
         
     | 
| 
      
 164 
     | 
    
         
            +
                },
         
     | 
| 
      
 165 
     | 
    
         
            +
                {
         
     | 
| 
      
 166 
     | 
    
         
            +
                    private_key: '/blah2.key',
         
     | 
| 
      
 167 
     | 
    
         
            +
                    cert_chain: '/blah2.crt',
         
     | 
| 
      
 168 
     | 
    
         
            +
                    host_name: 'somehost2.com'
         
     | 
| 
      
 169 
     | 
    
         
            +
                },
         
     | 
| 
      
 170 
     | 
    
         
            +
                {
         
     | 
| 
      
 171 
     | 
    
         
            +
                    private_key: '/blah3.key',
         
     | 
| 
      
 172 
     | 
    
         
            +
                    cert_chain: '/blah3.crt',
         
     | 
| 
      
 173 
     | 
    
         
            +
                    host_name: 'somehost3.com'
         
     | 
| 
      
 174 
     | 
    
         
            +
                }]
         
     | 
| 
      
 175 
     | 
    
         
            +
            }) do |client|
         
     | 
| 
      
 176 
     | 
    
         
            +
                client.start_tls
         
     | 
| 
      
 177 
     | 
    
         
            +
                client.start_read
         
     | 
| 
      
 178 
     | 
    
         
            +
            end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            # at some point later
         
     | 
| 
      
 181 
     | 
    
         
            +
            server.add_host(private_key: '/blah4.key', cert_chain: '/blah4.crt', host_name: 'somehost4.com')
         
     | 
| 
      
 182 
     | 
    
         
            +
            server.remove_host('somehost2.com')
         
     | 
| 
      
 183 
     | 
    
         
            +
            ```
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            You don't have to specify any hosts at binding time.
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
            ## Protocols and 3rd party plugins
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
            * [HTTP](https://github.com/cotag/uv-rays - with SNI [server name indication] support)
         
     | 
| 
      
 191 
     | 
    
         
            +
              * [Faraday plugin](https://github.com/cotag/uv-rays/blob/master/lib/faraday/adapter/libuv.rb)
         
     | 
| 
      
 192 
     | 
    
         
            +
              * [HTTPI plugin](https://github.com/cotag/uv-rays/blob/master/lib/httpi/adapter/libuv.rb)
         
     | 
| 
      
 193 
     | 
    
         
            +
              * [HTTP2](https://github.com/igrigorik/http-2)
         
     | 
| 
      
 194 
     | 
    
         
            +
              * [SOAP](https://github.com/savonrb/savon) (using HTTPI plugin)
         
     | 
| 
      
 195 
     | 
    
         
            +
            * [SNMP](https://github.com/acaprojects/ruby-engine/blob/master/lib/protocols/snmp.rb)
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rspec/core/rake_task'  # testing framework
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'yard'                  # yard documentation
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ffi'                   # loads the extension
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rake/clean'            # for the :clobber rake task
         
     | 
| 
      
 6 
     | 
    
         
            +
            require File.expand_path('../lib/mt-libuv/ext/tasks', __FILE__)    # platform specific rake tasks used by compile
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            # By default we don't run network tests
         
     | 
| 
      
 11 
     | 
    
         
            +
            task :default => :limited_spec
         
     | 
| 
      
 12 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:limited_spec) do |t|
         
     | 
| 
      
 13 
     | 
    
         
            +
                # Exclude network tests
         
     | 
| 
      
 14 
     | 
    
         
            +
                t.rspec_opts = "--tag ~network" 
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            desc "Run all tests"
         
     | 
| 
      
 20 
     | 
    
         
            +
            task :test => [:spec]
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            YARD::Rake::YardocTask.new do |t|
         
     | 
| 
      
 24 
     | 
    
         
            +
                t.files   = ['lib/**/*.rb', '-', 'ext/README.md', 'README.md']
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            desc "Compile libuv from submodule"
         
     | 
| 
      
 29 
     | 
    
         
            +
            task :compile => ["ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}"]
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            CLOBBER.include("ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}")
         
     | 
    
        data/ext/README.md
    ADDED
    
    
    
        data/ext/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            if ENV.has_key?('USE_GLOBAL_LIBUV')
         
     | 
| 
      
 5 
     | 
    
         
            +
                exit(0)
         
     | 
| 
      
 6 
     | 
    
         
            +
            else
         
     | 
| 
      
 7 
     | 
    
         
            +
                require 'rubygems'
         
     | 
| 
      
 8 
     | 
    
         
            +
                require 'ffi'
         
     | 
| 
      
 9 
     | 
    
         
            +
                require 'rake/clean'
         
     | 
| 
      
 10 
     | 
    
         
            +
                require '../lib/libuv/ext/tasks'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                Dir.chdir File.expand_path("../", __FILE__)
         
     | 
| 
      
 13 
     | 
    
         
            +
                Dir.chdir '..'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                task :default => :libuv
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                if FFI::Platform.windows?
         
     | 
| 
      
 18 
     | 
    
         
            +
                    task :libuv do
         
     | 
| 
      
 19 
     | 
    
         
            +
                        FileUtils.mkdir('ext/libuv/lib')
         
     | 
| 
      
 20 
     | 
    
         
            +
                        FileUtils.cp 'ext/libuv.dll', 'ext/libuv/lib/libuv.dll'
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                else
         
     | 
| 
      
 23 
     | 
    
         
            +
                    desc "Compile libuv from submodule"
         
     | 
| 
      
 24 
     | 
    
         
            +
                    task :libuv => ["ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}"]
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    CLOBBER.include("ext/libuv/lib/libuv.#{FFI::Platform::LIBSUFFIX}")
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module MTLibuv
         
     | 
| 
      
 4 
     | 
    
         
            +
                class Async < Handle
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                    define_callback function: :on_async
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    # @param reactor [::MTLibuv::Reactor] reactor this async callback will be associated
         
     | 
| 
      
 11 
     | 
    
         
            +
                    def initialize(reactor)
         
     | 
| 
      
 12 
     | 
    
         
            +
                        @reactor = reactor
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                        async_ptr = ::MTLibuv::Ext.allocate_handle_async
         
     | 
| 
      
 15 
     | 
    
         
            +
                        on_async = callback(:on_async, async_ptr.address)
         
     | 
| 
      
 16 
     | 
    
         
            +
                        error = check_result(::MTLibuv::Ext.async_init(reactor.handle, async_ptr, on_async))
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                        super(async_ptr, error)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    # Triggers a notify event, calling everything in the notify chain
         
     | 
| 
      
 22 
     | 
    
         
            +
                    def call
         
     | 
| 
      
 23 
     | 
    
         
            +
                        return if @closed
         
     | 
| 
      
 24 
     | 
    
         
            +
                        error = check_result ::MTLibuv::Ext.async_send(handle)
         
     | 
| 
      
 25 
     | 
    
         
            +
                        reject(error) if error
         
     | 
| 
      
 26 
     | 
    
         
            +
                        self
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    # Used to update the callback that will be triggered when async is called
         
     | 
| 
      
 30 
     | 
    
         
            +
                    #
         
     | 
| 
      
 31 
     | 
    
         
            +
                    # @param callback [Proc] the callback to be called on reactor prepare
         
     | 
| 
      
 32 
     | 
    
         
            +
                    def progress(&callback)
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @callback = callback
         
     | 
| 
      
 34 
     | 
    
         
            +
                        self
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    private
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    def on_async(handle)
         
     | 
| 
      
 42 
     | 
    
         
            +
                        @reactor.exec do
         
     | 
| 
      
 43 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 44 
     | 
    
         
            +
                                @callback.call
         
     | 
| 
      
 45 
     | 
    
         
            +
                            rescue Exception => e
         
     | 
| 
      
 46 
     | 
    
         
            +
                                @reactor.log e, 'performing async callback'
         
     | 
| 
      
 47 
     | 
    
         
            +
                            end
         
     | 
| 
      
 48 
     | 
    
         
            +
                        end
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module MTLibuv
         
     | 
| 
      
 4 
     | 
    
         
            +
                class Check < Handle
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                    define_callback function: :on_check
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    # @param reactor [::MTLibuv::Reactor] reactor this check will be associated
         
     | 
| 
      
 11 
     | 
    
         
            +
                    # @param callback [Proc] callback to be called on reactor check
         
     | 
| 
      
 12 
     | 
    
         
            +
                    def initialize(reactor)
         
     | 
| 
      
 13 
     | 
    
         
            +
                        @reactor = reactor
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                        check_ptr = ::MTLibuv::Ext.allocate_handle_check
         
     | 
| 
      
 16 
     | 
    
         
            +
                        error = check_result(::MTLibuv::Ext.check_init(reactor.handle, check_ptr))
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                        super(check_ptr, error)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    # Enables the check handler.
         
     | 
| 
      
 22 
     | 
    
         
            +
                    def start
         
     | 
| 
      
 23 
     | 
    
         
            +
                        return if @closed
         
     | 
| 
      
 24 
     | 
    
         
            +
                        error = check_result ::MTLibuv::Ext.check_start(handle, callback(:on_check))
         
     | 
| 
      
 25 
     | 
    
         
            +
                        reject(error) if error
         
     | 
| 
      
 26 
     | 
    
         
            +
                        self
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    # Disables the check handler.
         
     | 
| 
      
 30 
     | 
    
         
            +
                    def stop
         
     | 
| 
      
 31 
     | 
    
         
            +
                        return if @closed
         
     | 
| 
      
 32 
     | 
    
         
            +
                        error = check_result ::MTLibuv::Ext.check_stop(handle)
         
     | 
| 
      
 33 
     | 
    
         
            +
                        reject(error) if error
         
     | 
| 
      
 34 
     | 
    
         
            +
                        self
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    # Used to update the callback that will be triggered on reactor check
         
     | 
| 
      
 38 
     | 
    
         
            +
                    #
         
     | 
| 
      
 39 
     | 
    
         
            +
                    # @param callback [Proc] the callback to be called on reactor check
         
     | 
| 
      
 40 
     | 
    
         
            +
                    def progress(&callback)
         
     | 
| 
      
 41 
     | 
    
         
            +
                        @callback = callback
         
     | 
| 
      
 42 
     | 
    
         
            +
                        self
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    private
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def on_check(handle)
         
     | 
| 
      
 50 
     | 
    
         
            +
                        @reactor.exec do
         
     | 
| 
      
 51 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 52 
     | 
    
         
            +
                                @callback.call
         
     | 
| 
      
 53 
     | 
    
         
            +
                            rescue Exception => e
         
     | 
| 
      
 54 
     | 
    
         
            +
                                @reactor.log e, 'performing check callback'
         
     | 
| 
      
 55 
     | 
    
         
            +
                            end
         
     | 
| 
      
 56 
     | 
    
         
            +
                        end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'fiber'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class CoroutineRejection < RuntimeError
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :value
         
     | 
| 
      
 7 
     | 
    
         
            +
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module MTLibuv
         
     | 
| 
      
 10 
     | 
    
         
            +
                # Takes a Promise response and turns it into a co-routine
         
     | 
| 
      
 11 
     | 
    
         
            +
                # for code execution without using callbacks
         
     | 
| 
      
 12 
     | 
    
         
            +
                #
         
     | 
| 
      
 13 
     | 
    
         
            +
                # @param *promises [::MTLibuv::Q::Promise] a number of promises that will be combined into a single promise
         
     | 
| 
      
 14 
     | 
    
         
            +
                # @return [Object] Returns the result of a single promise or an array of results if provided multiple promises
         
     | 
| 
      
 15 
     | 
    
         
            +
                # @raise [Exception] if the promise is rejected
         
     | 
| 
      
 16 
     | 
    
         
            +
                def co(*yieldable)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    on_reactor = MTLibuv::Reactor.current
         
     | 
| 
      
 18 
     | 
    
         
            +
                    raise 'must be running on a reactor thread to use coroutines' unless on_reactor
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    f = Fiber.current
         
     | 
| 
      
 21 
     | 
    
         
            +
                    wasError = false
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    # Convert the input into a promise on the current reactor
         
     | 
| 
      
 24 
     | 
    
         
            +
                    if yieldable.length == 1
         
     | 
| 
      
 25 
     | 
    
         
            +
                        promise = yieldable[0]
         
     | 
| 
      
 26 
     | 
    
         
            +
                        # Passed independently as this is often overwritten for performance
         
     | 
| 
      
 27 
     | 
    
         
            +
                        promise.progress &Proc.new if block_given?
         
     | 
| 
      
 28 
     | 
    
         
            +
                    else
         
     | 
| 
      
 29 
     | 
    
         
            +
                        promise = on_reactor.all(*yieldable)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    # Use the promise to resume the Fiber
         
     | 
| 
      
 33 
     | 
    
         
            +
                    promise.then(proc { |res|
         
     | 
| 
      
 34 
     | 
    
         
            +
                        if MTLibuv::Reactor.current == on_reactor
         
     | 
| 
      
 35 
     | 
    
         
            +
                            f.resume res
         
     | 
| 
      
 36 
     | 
    
         
            +
                        else
         
     | 
| 
      
 37 
     | 
    
         
            +
                            on_reactor.schedule { f.resume(res) }
         
     | 
| 
      
 38 
     | 
    
         
            +
                        end
         
     | 
| 
      
 39 
     | 
    
         
            +
                    }, proc { |err|
         
     | 
| 
      
 40 
     | 
    
         
            +
                        wasError = true
         
     | 
| 
      
 41 
     | 
    
         
            +
                        if MTLibuv::Reactor.current == on_reactor
         
     | 
| 
      
 42 
     | 
    
         
            +
                            f.resume err
         
     | 
| 
      
 43 
     | 
    
         
            +
                        else
         
     | 
| 
      
 44 
     | 
    
         
            +
                            on_reactor.schedule { f.resume(err) }
         
     | 
| 
      
 45 
     | 
    
         
            +
                        end
         
     | 
| 
      
 46 
     | 
    
         
            +
                    })
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    # We want to prevent the reactor from stopping while we are waiting on a response
         
     | 
| 
      
 49 
     | 
    
         
            +
                    on_reactor.ref
         
     | 
| 
      
 50 
     | 
    
         
            +
                    result = Fiber.yield # Assign the result from the resume
         
     | 
| 
      
 51 
     | 
    
         
            +
                    on_reactor.unref
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    # Either return the result or raise an error
         
     | 
| 
      
 54 
     | 
    
         
            +
                    if wasError
         
     | 
| 
      
 55 
     | 
    
         
            +
                        if result.is_a?(Exception)
         
     | 
| 
      
 56 
     | 
    
         
            +
                            backtrace = caller
         
     | 
| 
      
 57 
     | 
    
         
            +
                            backtrace.shift
         
     | 
| 
      
 58 
     | 
    
         
            +
                            if result.respond_to?(:backtrace) && result.backtrace
         
     | 
| 
      
 59 
     | 
    
         
            +
                                backtrace << '---- continuation ----'
         
     | 
| 
      
 60 
     | 
    
         
            +
                                backtrace.concat(result.backtrace)
         
     | 
| 
      
 61 
     | 
    
         
            +
                            end
         
     | 
| 
      
 62 
     | 
    
         
            +
                            result.set_backtrace(backtrace)
         
     | 
| 
      
 63 
     | 
    
         
            +
                            raise result
         
     | 
| 
      
 64 
     | 
    
         
            +
                        else
         
     | 
| 
      
 65 
     | 
    
         
            +
                            e = case result
         
     | 
| 
      
 66 
     | 
    
         
            +
                            when String, Symbol
         
     | 
| 
      
 67 
     | 
    
         
            +
                                CoroutineRejection.new(result.to_s)
         
     | 
| 
      
 68 
     | 
    
         
            +
                            else
         
     | 
| 
      
 69 
     | 
    
         
            +
                                CoroutineRejection.new
         
     | 
| 
      
 70 
     | 
    
         
            +
                            end
         
     | 
| 
      
 71 
     | 
    
         
            +
                            e.value = result
         
     | 
| 
      
 72 
     | 
    
         
            +
                            raise e
         
     | 
| 
      
 73 
     | 
    
         
            +
                        end
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                    result
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                module_function :co
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/mt-libuv/dns.rb
    ADDED
    
    | 
         @@ -0,0 +1,98 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module MTLibuv
         
     | 
| 
      
 4 
     | 
    
         
            +
                class Dns < Q::DeferredPromise
         
     | 
| 
      
 5 
     | 
    
         
            +
                    include Resource, Listener, Net
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    define_callback function: :on_complete, params: [:pointer, :int, Ext::UvAddrinfo.by_ref]
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                    attr_reader :results
         
     | 
| 
      
 12 
     | 
    
         
            +
                    attr_reader :domain
         
     | 
| 
      
 13 
     | 
    
         
            +
                    attr_reader :port
         
     | 
| 
      
 14 
     | 
    
         
            +
                    attr_reader :hint
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    HINTS = {
         
     | 
| 
      
 18 
     | 
    
         
            +
                        :IPv4 => ::MTLibuv::Ext::UvAddrinfo.new,
         
     | 
| 
      
 19 
     | 
    
         
            +
                        :IPv6 => ::MTLibuv::Ext::UvAddrinfo.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                    }
         
     | 
| 
      
 21 
     | 
    
         
            +
                    HINTS[:IPv4].tap do |hint|
         
     | 
| 
      
 22 
     | 
    
         
            +
                        hint[:family] = FFI::Platform.windows? ? 2 : Socket::Constants::AF_INET
         
     | 
| 
      
 23 
     | 
    
         
            +
                        hint[:socktype] = Socket::Constants::SOCK_STREAM
         
     | 
| 
      
 24 
     | 
    
         
            +
                        hint[:protocol] = Socket::Constants::IPPROTO_TCP
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                    HINTS[:IPv6].tap do |hint|
         
     | 
| 
      
 27 
     | 
    
         
            +
                        hint[:family] = FFI::Platform.windows? ? 23 : Socket::Constants::AF_INET6
         
     | 
| 
      
 28 
     | 
    
         
            +
                        hint[:socktype] = Socket::Constants::SOCK_STREAM
         
     | 
| 
      
 29 
     | 
    
         
            +
                        hint[:protocol] = Socket::Constants::IPPROTO_TCP
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    # @param reactor [::MTLibuv::Reactor] reactor this work request will be associated
         
     | 
| 
      
 34 
     | 
    
         
            +
                    # @param domain [String] the domain name to resolve
         
     | 
| 
      
 35 
     | 
    
         
            +
                    # @param port [Integer, String] the port we wish to use
         
     | 
| 
      
 36 
     | 
    
         
            +
                    def initialize(reactor, domain, port, hint = :IPv4, wait: true)
         
     | 
| 
      
 37 
     | 
    
         
            +
                        super(reactor, reactor.defer)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                        @domain = domain
         
     | 
| 
      
 40 
     | 
    
         
            +
                        @port = port
         
     | 
| 
      
 41 
     | 
    
         
            +
                        @hint = hint
         
     | 
| 
      
 42 
     | 
    
         
            +
                        @complete = false
         
     | 
| 
      
 43 
     | 
    
         
            +
                        @pointer = ::MTLibuv::Ext.allocate_request_getaddrinfo
         
     | 
| 
      
 44 
     | 
    
         
            +
                        @error = nil    # error in callback
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                        @instance_id = @pointer.address
         
     | 
| 
      
 47 
     | 
    
         
            +
                        error = check_result ::MTLibuv::Ext.getaddrinfo(@reactor, @pointer, callback(:on_complete), domain, port.to_s, HINTS[hint])
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                        if error
         
     | 
| 
      
 50 
     | 
    
         
            +
                            ::MTLibuv::Ext.free(@pointer)
         
     | 
| 
      
 51 
     | 
    
         
            +
                            @complete = true
         
     | 
| 
      
 52 
     | 
    
         
            +
                            @defer.reject(error)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                        @defer.promise.value if wait
         
     | 
| 
      
 56 
     | 
    
         
            +
                    end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    # Indicates if the lookup has completed yet or not.
         
     | 
| 
      
 59 
     | 
    
         
            +
                    #
         
     | 
| 
      
 60 
     | 
    
         
            +
                    # @return [true, false]
         
     | 
| 
      
 61 
     | 
    
         
            +
                    def completed?
         
     | 
| 
      
 62 
     | 
    
         
            +
                        return @complete
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    private
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    def on_complete(req, status, addrinfo)
         
     | 
| 
      
 70 
     | 
    
         
            +
                        @complete = true
         
     | 
| 
      
 71 
     | 
    
         
            +
                        ::MTLibuv::Ext.free(req)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                        e = check_result(status)
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                        @reactor.exec do
         
     | 
| 
      
 76 
     | 
    
         
            +
                            if e
         
     | 
| 
      
 77 
     | 
    
         
            +
                                @defer.reject(e)
         
     | 
| 
      
 78 
     | 
    
         
            +
                            else
         
     | 
| 
      
 79 
     | 
    
         
            +
                                begin
         
     | 
| 
      
 80 
     | 
    
         
            +
                                    current = addrinfo
         
     | 
| 
      
 81 
     | 
    
         
            +
                                    @results = []
         
     | 
| 
      
 82 
     | 
    
         
            +
                                    while !current.null?
         
     | 
| 
      
 83 
     | 
    
         
            +
                                        @results << get_ip_and_port(current[:addr])
         
     | 
| 
      
 84 
     | 
    
         
            +
                                        current = current[:next]
         
     | 
| 
      
 85 
     | 
    
         
            +
                                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                                    @defer.resolve(@results)
         
     | 
| 
      
 87 
     | 
    
         
            +
                                rescue Exception => e
         
     | 
| 
      
 88 
     | 
    
         
            +
                                    @defer.reject(e)
         
     | 
| 
      
 89 
     | 
    
         
            +
                                end
         
     | 
| 
      
 90 
     | 
    
         
            +
                                ::MTLibuv::Ext.freeaddrinfo(addrinfo)
         
     | 
| 
      
 91 
     | 
    
         
            +
                            end
         
     | 
| 
      
 92 
     | 
    
         
            +
                        end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                        # Clean up references
         
     | 
| 
      
 95 
     | 
    
         
            +
                        cleanup_callbacks
         
     | 
| 
      
 96 
     | 
    
         
            +
                    end
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
            end
         
     |