[ruby-core:87483] Re: [Ruby trunk Feature#14736] Thread selector for flexible cooperative fiber based concurrency

From: Eric Wong <normalperson@...>
Date: 2018-06-13 00:58:26 UTC
List: ruby-core #87483
[email protected] wrote:
> I've been playing around with port scanners. Implemented in Go
> (goroutines), Python (asyncio) and Ruby (async).
>
> I wrote up the results here:
> https://github.com/socketry/async-await/tree/master/examples/port_scanner

Attached is the implementation for Threadlet/auto-fiber/wachamacallit
rebased against ruby trunk r63641:
   https://80x24.org/spew/[email protected]/raw

On a busy Linux VM, Threadlet was close to your Go implementation
in speed (timing results were unstable, however) and Ruby async
was around 3x slower behind (even with timing instabilities).

I kept on getting errors with the Python3 version
("Event loop is closed") so I never let it finish

I needed to deal with EPIPE because the system I tested on had RDS (16385)
enabled in the kernel which was triggering EPIPE (I don't know Go or Python):

```
diff --git a/examples/port_scanner/port_scanner.go b/examples/port_scanner/port_scanner.go
index 45f2d1c..ad0f049 100755
--- a/examples/port_scanner/port_scanner.go
+++ b/examples/port_scanner/port_scanner.go
@@ -55,7 +55,7 @@ func checkPortOpen(ip string, port int, timeout time.Duration) {
 		} else if strings.Contains(err.Error(), "refused") {
 			// fmt.Println(port, "closed", err.Error())
 		} else {
-			panic(err)
+			fmt.Println(port, "err", err.Error())
 		}
 		return
 	}
diff --git a/examples/port_scanner/port_scanner.py b/examples/port_scanner/port_scanner.py
index 372f0b3..ca9d41a 100755
--- a/examples/port_scanner/port_scanner.py
+++ b/examples/port_scanner/port_scanner.py
@@ -22,6 +22,8 @@ class PortScanner:
                 # print("{} closed".format(port))
             except asyncio.TimeoutError:
                 print("{} timeout".format(port))
+            except SystemError:
+                print("{} error".format(port))
 
     def start(self, timeout=1.0):
         self.loop.run_until_complete(asyncio.gather(
diff --git a/examples/port_scanner/port_scanner.rb b/examples/port_scanner/port_scanner.rb
index 0e4160e..3ac0109 100755
--- a/examples/port_scanner/port_scanner.rb
+++ b/examples/port_scanner/port_scanner.rb
@@ -25,6 +25,8 @@ class PortScanner
     # puts "#{port} closed"
   rescue Async::TimeoutError
     puts "#{port} timeout"
+  rescue SystemCallError => e
+    puts "#{port} #{e.message}"
   end
 
   async def start(timeout = 1.0)
```

Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

Attachments (1)

port_scanner_threadlet.rb (925 Bytes, application/x-sh)

In This Thread

Prev Next