Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add multiruby example

  • Loading branch information...
commit e55869d5acad154cabcd0ad65a6ac2a4f5b99ce9 1 parent 4406401
Jordan Sissel authored April 03, 2012
65  ruby/sockets/multiruby-connect_nonblock.rb
... ...
@@ -0,0 +1,65 @@
  1
+require "socket"
  2
+require "cabin" # rubygem 'cabin'
  3
+
  4
+version = RUBY_VERSION
  5
+platform = case RUBY_PLATFORM
  6
+  when "java"; "jruby-#{JRUBY_VERSION}"
  7
+  else "ruby"
  8
+end
  9
+
  10
+environment = [version, platform].join(" @ ")
  11
+$logger = Cabin::Channel.get
  12
+$logger.subscribe(STDOUT)
  13
+$logger.level = $DEBUG ? :debug : :info
  14
+$logger[:platform] = environment
  15
+
  16
+def connect(host, port, options={})
  17
+  timeout = options[:timeout]
  18
+  socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
  19
+  sockaddr = Socket.sockaddr_in(port, host)
  20
+  tries = 10
  21
+  start = Time.now
  22
+  begin
  23
+    $logger.debug("trying to connect")
  24
+    socket.connect_nonblock(sockaddr)
  25
+  rescue Errno::EINPROGRESS
  26
+    # Block until the socket is ready, then try again
  27
+    reader, writer, error = IO.select([socket], [socket], [socket], timeout)
  28
+    $logger.debug("IO.select", :return => [reader, writer, error])
  29
+
  30
+    # JRuby (at least as of 1.6.7) returns [nil,nil,nil] on IO.select when the
  31
+    # socket is finished connecting *and* on timeout, so let's hack around this
  32
+    # and try to find out if we're really connected or not.
  33
+    # 
  34
+    # So let's just let another connect_nonblock attempt tell us
  35
+    # what is really going on.
  36
+  end
  37
+
  38
+  # Because IO.select behaves (return values are different) different on
  39
+  # different rubies, lets just try 'connect_nonblock' again. An exception
  40
+  # is raised to indicate the current state of the connection, and at this 
  41
+  # point, we are ready to decide if this is a success or a timeout.
  42
+  begin
  43
+    # Try to figure out if we're actually connected
  44
+    socket.connect_nonblock(sockaddr)
  45
+  rescue Errno::EISCONN
  46
+    # Good, we're connected
  47
+  rescue Errno::EINPROGRESS, Errno::EALREADY
  48
+    # Bad, we're still waiting to connect
  49
+    # JRuby raises EINPROGRESS, MRI raises EALREADY
  50
+    socket.close
  51
+    return nil
  52
+  end
  53
+  return socket
  54
+end
  55
+
  56
+if ARGV.size != 3
  57
+  $logger.error("Usage: #{$PROGRAM_NAME} host port timeout")
  58
+  exit 1
  59
+end
  60
+  
  61
+host, port, timeout = ARGV[0..2]
  62
+$logger.time("Connect") do
  63
+  socket = connect(host, port, :timeout => timeout.to_f)
  64
+  $logger.info("Socket?", :socket => socket)
  65
+end

0 notes on commit e55869d

Please sign in to comment.
Something went wrong with that request. Please try again.