Rainbows! Rack HTTP server user/dev discussion
 help / color / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
						download: 
* [PATCH 0/3] final round of changes for unicorn 5 compatibility
@ 2015-11-18  3:58 Eric Wong
  2015-11-18  3:58 ` [PATCH 3/3] bump to unicorn 5.0.1, use monotonic clock Eric Wong
  0 siblings, 1 reply; 3+ results
From: Eric Wong @ 2015-11-18  3:58 UTC (permalink / raw)
  To: rainbows-public

* http_server: add master_pid attribute
* stream_response_epoll: remove hijack_prepare call
* bump to unicorn 5.0.1, use monotonic clock

There'll probably be another round of small changes since we
can drop Ruby 1.8 support and debloat our code a little.

 lib/rainbows.rb                            | 19 ++++++++++++++++---
 lib/rainbows/coolio/client.rb              |  2 +-
 lib/rainbows/coolio/heartbeat.rb           |  2 +-
 lib/rainbows/epoll/client.rb               |  4 ++--
 lib/rainbows/fiber.rb                      |  2 +-
 lib/rainbows/fiber/base.rb                 |  4 ++--
 lib/rainbows/fiber/coolio/heartbeat.rb     |  2 +-
 lib/rainbows/fiber/io.rb                   |  2 +-
 lib/rainbows/http_server.rb                |  1 +
 lib/rainbows/join_threads.rb               |  4 ++--
 lib/rainbows/process_client.rb             |  4 ++--
 lib/rainbows/stream_response_epoll.rb      |  2 +-
 lib/rainbows/thread_timeout.rb             |  8 ++++----
 lib/rainbows/xepoll_thread_pool/client.rb  |  4 ++--
 lib/rainbows/xepoll_thread_spawn/client.rb |  4 ++--
 rainbows.gemspec                           |  2 +-
 t/test_isolate.rb                          |  2 +-
 17 files changed, 41 insertions(+), 27 deletions(-)


^ permalink raw reply	[relevance 7%]

* [PATCH 3/3] bump to unicorn 5.0.1, use monotonic clock
  2015-11-18  3:58 [PATCH 0/3] final round of changes for unicorn 5 compatibility Eric Wong
@ 2015-11-18  3:58 ` Eric Wong
  0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2015-11-18  3:58 UTC (permalink / raw)
  To: rainbows-public

The timeout (mis)feature in unicorn uses the monotonic clock
if available.  We must follow suit to avoid having our timeout
functionality completely broken.
---
 lib/rainbows.rb                            | 19 ++++++++++++++++---
 lib/rainbows/coolio/client.rb              |  2 +-
 lib/rainbows/coolio/heartbeat.rb           |  2 +-
 lib/rainbows/epoll/client.rb               |  4 ++--
 lib/rainbows/fiber.rb                      |  2 +-
 lib/rainbows/fiber/base.rb                 |  4 ++--
 lib/rainbows/fiber/coolio/heartbeat.rb     |  2 +-
 lib/rainbows/fiber/io.rb                   |  2 +-
 lib/rainbows/join_threads.rb               |  4 ++--
 lib/rainbows/process_client.rb             |  4 ++--
 lib/rainbows/thread_timeout.rb             |  8 ++++----
 lib/rainbows/xepoll_thread_pool/client.rb  |  4 ++--
 lib/rainbows/xepoll_thread_spawn/client.rb |  4 ++--
 rainbows.gemspec                           |  2 +-
 t/test_isolate.rb                          |  2 +-
 15 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/lib/rainbows.rb b/lib/rainbows.rb
index 0af5620..f23b387 100644
--- a/lib/rainbows.rb
+++ b/lib/rainbows.rb
@@ -75,8 +75,8 @@ module Rainbows
   end
 
   def self.tick
-    @worker.tick = Time.now.to_i
-    exit!(2) if @expire && Time.now >= @expire
+    @worker.tick = now.to_i
+    exit!(2) if @expire && now >= @expire
     @alive && @server.master_pid == Process.ppid or quit!
   end
 
@@ -88,7 +88,7 @@ module Rainbows
     unless @expire
       @alive = false
       Rainbows::HttpParser.quit
-      @expire = Time.now + (@server.timeout * 2.0)
+      @expire = now + (@server.timeout * 2.0)
       tmp = @readers.dup
       @readers.clear
       tmp.each { |s| s.close rescue nil }.clear
@@ -100,6 +100,19 @@ module Rainbows
     false
   end
 
+  # try to use the monotonic clock in Ruby >= 2.1, it is immune to clock
+  # offset adjustments and generates less garbage (Float vs Time object)
+  begin
+    Process.clock_gettime(Process::CLOCK_MONOTONIC)
+    def self.now
+      Process.clock_gettime(Process::CLOCK_MONOTONIC)
+    end
+  rescue NameError, NoMethodError
+    def self.now # Ruby <= 2.0
+      Rainbows.now
+    end
+  end
+
   autoload :Base, "rainbows/base"
   autoload :WriterThreadPool, "rainbows/writer_thread_pool"
   autoload :WriterThreadSpawn, "rainbows/writer_thread_spawn"
diff --git a/lib/rainbows/coolio/client.rb b/lib/rainbows/coolio/client.rb
index ad827f6..cd22c22 100644
--- a/lib/rainbows/coolio/client.rb
+++ b/lib/rainbows/coolio/client.rb
@@ -154,7 +154,7 @@ class Rainbows::Coolio::Client < Coolio::IO
         # buf == :wait_readable
         unless enabled?
           enable
-          KATO[self] = Time.now
+          KATO[self] = Rainbows.now
         end
       else
         on_read(''.freeze)
diff --git a/lib/rainbows/coolio/heartbeat.rb b/lib/rainbows/coolio/heartbeat.rb
index 3ae9e16..fcfbb0f 100644
--- a/lib/rainbows/coolio/heartbeat.rb
+++ b/lib/rainbows/coolio/heartbeat.rb
@@ -13,7 +13,7 @@ class Rainbows::Coolio::Heartbeat < Coolio::TimerWatcher
 
   def on_timer
     if (ot = KEEPALIVE_TIMEOUT) >= 0
-      ot = Time.now - ot
+      ot = Rainbows.now - ot
       KATO.delete_if { |client, time| time < ot and client.timeout? }
     end
     exit if (! Rainbows.tick && CONN.size <= 0)
diff --git a/lib/rainbows/epoll/client.rb b/lib/rainbows/epoll/client.rb
index 6dcbb81..fe04258 100644
--- a/lib/rainbows/epoll/client.rb
+++ b/lib/rainbows/epoll/client.rb
@@ -14,10 +14,10 @@ module Rainbows::Epoll::Client
   Rainbows.at_quit { KATO.each_key { |k| k.timeout! }.clear }
   Rainbows.config!(self, :keepalive_timeout)
   EP = Rainbows::EP
-  @@last_expire = Time.now
+  @@last_expire = Rainbows.now
 
   def self.expire
-    return if ((now = Time.now) - @@last_expire) < 1.0
+    return if ((now = Rainbows.now) - @@last_expire) < 1.0
     if (ot = KEEPALIVE_TIMEOUT) >= 0
       ot = now - ot
       KATO.delete_if { |client, time| time < ot and client.timeout! }
diff --git a/lib/rainbows/fiber.rb b/lib/rainbows/fiber.rb
index a0f3f99..a37512f 100644
--- a/lib/rainbows/fiber.rb
+++ b/lib/rainbows/fiber.rb
@@ -29,7 +29,7 @@ module Rainbows::Fiber
   # right?).  Calling this directly is deprecated, use
   # Rainbows.sleep(seconds) instead.
   def self.sleep(seconds)
-    ZZ[Fiber.current] = Time.now + seconds
+    ZZ[Fiber.current] = Rainbows.now + seconds
     Fiber.yield
   end
 
diff --git a/lib/rainbows/fiber/base.rb b/lib/rainbows/fiber/base.rb
index e8f5b16..7c4fb59 100644
--- a/lib/rainbows/fiber/base.rb
+++ b/lib/rainbows/fiber/base.rb
@@ -40,7 +40,7 @@ module Rainbows::Fiber::Base
   # woken and returns an interval to IO.select on
   def schedule_sleepers
     max = nil
-    now = Time.now
+    now = Rainbows.now
     fibs = []
     ZZ.delete_if { |fib, time|
       if now >= time
@@ -54,7 +54,7 @@ module Rainbows::Fiber::Base
 
     max_sleep = 1.0 # wake up semi-frequently to prevent SIGKILL from master
     if max
-      max -= Time.now
+      max -= Rainbows.now
       return 0 if max < 0.0
       return max_sleep if max > max_sleep
       max
diff --git a/lib/rainbows/fiber/coolio/heartbeat.rb b/lib/rainbows/fiber/coolio/heartbeat.rb
index 6b1e4f9..7014dbe 100644
--- a/lib/rainbows/fiber/coolio/heartbeat.rb
+++ b/lib/rainbows/fiber/coolio/heartbeat.rb
@@ -5,7 +5,7 @@ class Rainbows::Fiber::Coolio::Heartbeat < Coolio::TimerWatcher
   ZZ = Rainbows::Fiber::ZZ
   def on_timer
     exit if (! Rainbows.tick && Rainbows.cur <= 0)
-    now = Time.now
+    now = Rainbows.now
     fibs = []
     ZZ.delete_if { |fib, time| now >= time ? fibs << fib : ! fib.alive? }
     fibs.each { |fib| fib.resume if fib.alive? }
diff --git a/lib/rainbows/fiber/io.rb b/lib/rainbows/fiber/io.rb
index b121854..111132f 100644
--- a/lib/rainbows/fiber/io.rb
+++ b/lib/rainbows/fiber/io.rb
@@ -63,7 +63,7 @@ class Rainbows::Fiber::IO
     expire = nil
     case rv = Kgio.tryread(@to_io, 16384, buf)
     when :wait_readable
-      return if expire && expire < Time.now
+      return if expire && expire < Rainbows.now
       expire ||= read_expire
       kgio_wait_readable
     else
diff --git a/lib/rainbows/join_threads.rb b/lib/rainbows/join_threads.rb
index 7ab2004..2ae6aa4 100644
--- a/lib/rainbows/join_threads.rb
+++ b/lib/rainbows/join_threads.rb
@@ -5,12 +5,12 @@ module Rainbows::JoinThreads
 
   # blocking acceptor threads must be forced to run
   def self.acceptors(threads)
-    expire = Time.now + Rainbows.server.timeout
+    expire = Rainbows.now + Rainbows.server.timeout
     threads.delete_if do |thr|
       Rainbows.tick
       begin
         # blocking accept() may not wake up properly
-        thr.raise(Errno::EINTR) if Time.now > expire && thr.stop?
+        thr.raise(Errno::EINTR) if Rainbows.now > expire && thr.stop?
 
         thr.run
         thr.join(0.01)
diff --git a/lib/rainbows/process_client.rb b/lib/rainbows/process_client.rb
index a39d6cd..4bf9878 100644
--- a/lib/rainbows/process_client.rb
+++ b/lib/rainbows/process_client.rb
@@ -9,7 +9,7 @@ module Rainbows::ProcessClient
   Rainbows.config!(self, :client_header_buffer_size, :keepalive_timeout)
 
   def read_expire
-    Time.now + KEEPALIVE_TIMEOUT
+    Rainbows.now + KEEPALIVE_TIMEOUT
   end
 
   # used for reading headers (respecting keepalive_timeout)
@@ -18,7 +18,7 @@ module Rainbows::ProcessClient
     begin
       case rv = kgio_tryread(CLIENT_HEADER_BUFFER_SIZE, buf)
       when :wait_readable
-        return if expire && expire < Time.now
+        return if expire && expire < Rainbows.now
         expire ||= read_expire
         kgio_wait_readable(KEEPALIVE_TIMEOUT)
       else
diff --git a/lib/rainbows/thread_timeout.rb b/lib/rainbows/thread_timeout.rb
index 8348272..8739d29 100644
--- a/lib/rainbows/thread_timeout.rb
+++ b/lib/rainbows/thread_timeout.rb
@@ -63,7 +63,7 @@ class Rainbows::ThreadTimeout
 
   # The MRI 1.8 won't be usable in January 2038, we'll raise this
   # when we eventually drop support for 1.8 (before 2038, hopefully)
-  NEVER = Time.at(0x7fffffff)
+  NEVER = 0x7fffffff
 
   def initialize(app, opts)
     # @timeout must be Numeric since we add this to Time
@@ -114,7 +114,7 @@ class Rainbows::ThreadTimeout
     # is hopeless and we might as well just die anyways.
     # initialize guarantees @timeout will be Numeric
     start_watchdog(env) unless @watchdog
-    @active[Thread.current] = Time.now + @timeout
+    @active[Thread.current] = Rainbows.now + @timeout
 
     begin
       # It is important to unlock inside this begin block
@@ -162,7 +162,7 @@ class Rainbows::ThreadTimeout
         # that are about to release themselves from the eye of the
         # watchdog thread.
         @lock.synchronize do
-          now = Time.now
+          now = Rainbows.now
           @active.delete_if do |thread, expire_at|
             # We also use this loop to get the maximum possible time to
             # sleep for if we're not killing the thread.
@@ -184,7 +184,7 @@ class Rainbows::ThreadTimeout
           sleep(@timeout)
         else
           # sleep until the next known thread is about to expire.
-          sec = next_expiry - Time.now
+          sec = next_expiry - Rainbows.now
           sec > 0.0 ? sleep(sec) : Thread.pass # give other threads a chance
         end
       rescue => e
diff --git a/lib/rainbows/xepoll_thread_pool/client.rb b/lib/rainbows/xepoll_thread_pool/client.rb
index 001e69d..760bbde 100644
--- a/lib/rainbows/xepoll_thread_pool/client.rb
+++ b/lib/rainbows/xepoll_thread_pool/client.rb
@@ -46,7 +46,7 @@ module Rainbows::XEpollThreadPool::Client
     LOCK.synchronize { clients = KATO.keys; KATO.clear }
     clients.each { |io| io.closed? or io.close }
   end
-  @@last_expire = Time.now
+  @@last_expire = Rainbows.now
 
   def kato_set
     LOCK.synchronize { KATO[self] = @@last_expire }
@@ -70,7 +70,7 @@ module Rainbows::XEpollThreadPool::Client
   end
 
   def self.expire
-    return if ((now = Time.now) - @@last_expire) < 1.0
+    return if ((now = Rainbows.now) - @@last_expire) < 1.0
     if (ot = KEEPALIVE_TIMEOUT) >= 0
       ot = now - ot
       defer = []
diff --git a/lib/rainbows/xepoll_thread_spawn/client.rb b/lib/rainbows/xepoll_thread_spawn/client.rb
index a3277cf..67c5976 100644
--- a/lib/rainbows/xepoll_thread_spawn/client.rb
+++ b/lib/rainbows/xepoll_thread_spawn/client.rb
@@ -35,7 +35,7 @@ module Rainbows::XEpollThreadSpawn::Client
     LOCK.synchronize { clients = KATO.keys; KATO.clear }
     clients.each { |io| io.closed? or io.shutdown }
   end
-  @@last_expire = Time.now
+  @@last_expire = Rainbows.now
 
   def kato_set
     LOCK.synchronize { KATO[self] = @@last_expire }
@@ -59,7 +59,7 @@ module Rainbows::XEpollThreadSpawn::Client
   end
 
   def self.expire
-    return if ((now = Time.now) - @@last_expire) < 1.0
+    return if ((now = Rainbows.now) - @@last_expire) < 1.0
     if (ot = KEEPALIVE_TIMEOUT) >= 0
       ot = now - ot
       defer = []
diff --git a/rainbows.gemspec b/rainbows.gemspec
index afc8b5a..6ddf630 100644
--- a/rainbows.gemspec
+++ b/rainbows.gemspec
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
   # we need unicorn for the HTTP parser and process management
   # we need unicorn 4.8.0+ since we depend on undocumented/unsupported
   # unicorn internals.
-  s.add_dependency(%q<unicorn>, ["~> 4.8"])
+  s.add_dependency(%q<unicorn>, ["~> 5.0"])
 
   s.add_development_dependency(%q<isolate>, "~> 3.1")
   s.add_development_dependency(%q<olddoc>, "~> 1.0")
diff --git a/t/test_isolate.rb b/t/test_isolate.rb
index 98918f6..58bc4dc 100644
--- a/t/test_isolate.rb
+++ b/t/test_isolate.rb
@@ -20,7 +20,7 @@ Isolate.now!(opts) do
   gem 'rack', '1.6.4'
   gem 'kcar', '0.5.0'
   gem 'raindrops', '0.13.0'
-  gem 'unicorn', '4.9.0'
+  gem 'unicorn', '5.0.1'
 
   if engine == "ruby"
     gem 'sendfile', '1.2.2'
-- 
EW


^ permalink raw reply	[relevance 5%]

* [ANN] Rainbows! 5.0.0 - Rack HTTP server for the sleepy
@ 2015-11-25  1:04 Eric Wong
  0 siblings, 0 replies; 3+ results
From: Eric Wong @ 2015-11-25  1:04 UTC (permalink / raw)
  To: ruby-talk; +Cc: rainbows-public

Rainbows! is an HTTP server for sleepy Rack applications.
While it will be maintained as long as anybody uses it,
use of Rainbows! for new projects is not recommended,
try other servers instead:

    http://bogomips.org/rainbows-public/20151020095934.GA19114@dcvr.yhbt.net/

Rainbows! 5.0.0 - maintained as long as anybody uses it!

This release syncs with unicorn 5 and drops some old compatibility
cruft from old releases.  Performance should be roughly unchanged
for Ruby 2.2 users while older Rubies (1.9.3 - 2.1) will see
minor, probably unnoticeable performance regressions.

Compatibility:

* The horrible, proprietary (:P) "Status:" response header is
  finally gone, saving at least 16 precious bytes in every HTTP
  response.  This should make it easier to write custom HTTP clients
  which are compatible across all HTTP servers.  It will hopefully
  make migrating between different Rack servers easier for new
  projects.

* Ruby 1.8 support removed.  Ruby 1.9.3 is currently the earliest
  supported version.  However, expect minor, likely-unnoticeable
  performance regressions if you use Ruby 2.1 or earlier.  Going
  forward, Rainbows! will favor the latest version (currently 2.2) of
  the mainline Ruby implementation, potentially sacrificing
  performance on older Rubies.

New features:

* sd_listen_fds(3) emulation added for systemd compatibility.
  You may now stop using PID files and other process monitoring
  software when using systemd.

* Newly-set TCP socket options are now applied to inherited sockets.

* Dynamic changes in the application to Rack::Utils::HTTP_STATUS
  hash is now supported; allowing users to set custom status lines
  in Rack to be reflected in unicorn.  This feature causes a minor
  performance regression, but is made up for Ruby 2.2 users with
  other optimizations.

* The monotonic clock is used under Ruby 2.1+, making the
  timeout feature immune to system clock changes.

As Rainbows! may be used anonymously without registration, the
project is committed to supporting anonymous and pseudonymous
help requests, contributions and feedback via plain-text mail to:

    rainbows-public@bogomips.org

The mail submission port (587) is open to those behind firewalls
and allows access via Tor and anonymous remailers.
Archives are accessible via:

* http://bogomips.org/rainbows-public/
* nntp://news.public-inbox.org/inbox.comp.lang.ruby.rainbows
* nntp://news.gmane.org/gmane.comp.lang.ruby.rainbows.general

and mirrored to various other places, so you do not even need
to use a valid address when posting.

18 changes since Rainbows! 4.7.0

      README: remove Zbatery references
      http_parser: handle keepalive_requests internally
      kill the moronic Status: header
      reflect changes in Rack::Utils::HTTP_STATUS_CODES
      reduce constant lookup dependencies
      http_parser: workaround hijack changes in unicorn 5
      http_server: add master_pid attribute
      stream_response_epoll: remove hijack_prepare call
      bump to unicorn 5.0.1, use monotonic clock
      add .gitattributes for Ruby method detection
      response: avoid garbage string entirely
      tiny bytecode reductions for cold paths
      Ruby 1.9.3+-only cleanups
      revactor: remove fcntl dependency
      response: simplify regexp
      t0105: fix test reliability
      fix Rainbows.now definition for old Rubies
      fix broken constant lookups in unmaintained bits

* http://rainbows.bogomips.org/
* rainbows-public@bogomips.org
* http://bogomips.org/rainbows-public/
* git clone git://bogomips.org/rainbows.git
* http://rainbows.bogomips.org/NEWS.atom.xml

*zzzzzzzz*

^ permalink raw reply	[relevance 7%]

Results 1-3 of 3 | reverse results
2015-11-18  3:58 [PATCH 0/3] final round of changes for unicorn 5 compatibility Eric Wong
2015-11-18  3:58 ` [PATCH 3/3] bump to unicorn 5.0.1, use monotonic clock Eric Wong
2015-11-25  1:04 [ANN] Rainbows! 5.0.0 - Rack HTTP server for the sleepy Eric Wong


Rainbows! Rack HTTP server user/dev discussion

Archives are clonable:
	git clone --mirror https://bogomips.org/rainbows-public
	git clone --mirror http://ou63pmih66umazou.onion/rainbows-public

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.lang.ruby.rainbows
	nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.rainbows

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox