raindrops is a real-time stats toolkit to show statistics for Rack HTTP servers. It is designed for preforking servers such as unicorn, but should support any Rack HTTP server on platforms supporting POSIX shared memory. It may also be used as a generic scoreboard for sharing atomic counters across multiple processes. * https://bogomips.org/raindrops/ * No subscription necessary, no HTML mail: raindrops-public@bogomips.org * mail archives: https://bogomips.org/raindrops-public/ http://ou63pmih66umazou.onion/raindrops-public/ nntp://news.public-inbox.org/inbox.comp.lang.ruby.raindrops nntp://ou63pmih66umazou.onion/inbox.comp.lang.ruby.raindrops * git clone git://bogomips.org/raindrops.git * https://bogomips.org/raindrops/NEWS.atom.xml * Demo site: https://raindrops-demo.bogomips.org:8443/ Changes: raindrops 0.18.0 The most notable feature of this release is the addition of FreeBSD and OpenBSD TCP_INFO support. This includes the Raindrops::TCP for portably mapping TCP state names to platform-dependent numeric values: https://bogomips.org/raindrops/Raindrops.html#TCP Thanks to Jeremy Evans and Simon Eskildsen on the unicorn-public@bogomips.org mailing list for inspiring these changes to raindrops. There's also a few internal cleanups, and documentation improvements, including some fixes to the largely-forgotten Raindrops::Aggreage::PMQ class: https://bogomips.org/raindrops/Raindrops/Aggregate/PMQ.html 20 changes since 0.17.0: test_inet_diag_socket: fix Fixnum deprecation warning TODO: add item for IPv6 breakage ext: fix documentation for C ext-defined classes TCP_Info: custom documentation for #get! TypedData C-API conversion test_watcher: disable test correctly when aggregate is missing tcp_info: support this struct under FreeBSD define Raindrops::TCP hash for TCP states linux_inet_diag: reduce stack usage and simplify avoid reading errno repeatedly aggregate/pmq: avoid false sharing of lock buffers aggregate/pmq: remove io-extra requirement aggregate/pmq: avoid File#stat allocation Merge remote-tracking branch 'origin/freebsd' Merge remote-tracking branch 'origin/aggregate-pmq' doc: remove private email support address doc: update location of TCP_INFO-related stuff build: avoid olddoc for building the RubyGem doc: document Raindrops::TCP hash aggregate/pmq: update version numbers for Ruby and Linux
Unicorn is an HTTP server for Rack applications designed to only serve fast clients on low-latency, high-bandwidth connections and take advantage of features in Unix/Unix-like kernels. Slow clients should only be served by placing a reverse proxy capable of fully buffering both the the request and response in between unicorn and slow clients. * http://unicorn.bogomips.org/ * public list: unicorn-public@bogomips.org * mail archives: http://bogomips.org/unicorn-public/ * git clone git://bogomips.org/unicorn.git * http://unicorn.bogomips.org/NEWS.atom.xml * nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn Changes: unicorn 5.1.0 - rack is optional, again Note: no code changes since 5.1.0.pre1 from January.^WNo, wait, last minute performance improvement added today. See below. The big change is rack is not required (but still recommended). Applications are expected to depend on rack on their own so they can specify the version of rack they prefer without unicorn pulling in a newer, potentially incompatible version. unicorn will always attempt to work with multiple versions of rack as practical. The HTTP parser also switched to using the TypedData C-API for extra type safety and memory usage accounting support in the 'objspace' extension. Thanks to Adam Duke to bringing the rack change to our attention and Aaron Patterson for helping with the matter. Last minute change: we now support the new leftpad() syscall under Linux for major performance and security improvements: http://mid.gmane.org/1459463613-32473-1-git-send-email-richard@nod.at 8^H9 changes since 5.0.1: http: TypedData C-API conversion various documentation updates doc: bump olddoc to ~> 1.2 for extra NNTP URL rack is optional at runtime, required for dev doc update for ClientShutdown exceptions class unicorn 5.1.0.pre1 - rack is optional, again doc: reference --keep-file-descriptors for "bundle exec" doc: further trimming to reduce noise use leftpad Linux syscall for speed!
Unicorn is an HTTP server for Rack applications designed to only serve fast clients on low-latency, high-bandwidth connections and take advantage of features in Unix/Unix-like kernels. Slow clients should only be served by placing a reverse proxy capable of fully buffering both the the request and response in between unicorn and slow clients. * http://unicorn.bogomips.org/ * public list: unicorn-public@bogomips.org * mail archives: http://bogomips.org/unicorn-public/ * git clone git://bogomips.org/unicorn.git * http://unicorn.bogomips.org/NEWS.atom.xml * nntp://news.public-inbox.org/inbox.comp.lang.ruby.unicorn This is a pre-release, you will need to specify the version to install explicitly when using RubyGems. Changes: unicorn 5.1.0.pre1 - rack is optional, again The big change is rack is not required (but still recommended). Applications are expected to depend on rack on their own so they can specify the version of rack they prefer without unicorn pulling in a newer, potentially incompatible version. unicorn will always attempt to work with multiple versions of rack as practical. The HTTP parser also switched to using the TypedData C-API for extra type safety and memory usage accounting support in the 'objspace' extension. Thanks to Adam Duke to bringing the rack change to our attention and Aaron Patterson for helping with the matter. There might be more documentation-related changes before 5.1.0 final. I am considering dropping pandoc from manpage generation and relying on pod2man (from Perl) because it has a wider install base. 5 changes since v5.0.1: http: TypedData C-API conversion various documentation updates doc: bump olddoc to ~> 1.2 for extra NNTP URL rack is optional at runtime, required for dev doc update for ClientShutdown exceptions class
Eric Wong <e@80x24.org> wrote: > Unfortunately, TypedData is not an official API, yet, > so I'm hesitant to depend on it until it is official: > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/67089 Ruby 2.3 will be released in a few hours or so, and this API hasn't changed since 1.9.3; so I just pushed out commit 5b5cf896871efdb110ae831fd7fc34fb78ec2243 to git://bogomips.org/unicorn.git <http://bogomips.org/unicorn.git/patch/?id=5b5cf896871efd> <http://bogomips.org/unicorn-public/?x=t&q=TypedData> Then there's the optional frozen_string_literal stuff in 2.3...
Eric Wong <e@80x24.org> wrote: > Note: this means we are finally dropping Ruby 1.8 support as > TypedData requires Ruby 1.9 and later. Unfortunately, TypedData is not an official API, yet, so I'm hesitant to depend on it until it is official: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/67089 But there ought to be tiny gains made from dropping 1.8 support, so I'll probably go ahead and do it...
This provides some extra type safety if combined with other C extensions, as well as allowing us to account for memory usage of the HTTP parser in ObjectSpace. Note: this means we are finally dropping Ruby 1.8 support as TypedData requires Ruby 1.9 and later. Future changes will require Ruby 1.9.2 and later (which is already EOL), but still in use at some places. This compiles with warnings on Ruby 1.9.2, but is warning-free on modern Ruby versions. This also currently leaks memory under 1.9.2-p330 x86_64-linux if test_memory_leak is enabled in test/unit/test_http_parser.rb Since 1.9.2 is EOL and 1.9.3+ all work fine (including trunk), I'm not going to spend more time with this problem. Also, keep in mind this type of memory leak wouldn't affect unicorn as we only ever allocate a single parser. This leak would only affect other (concurrent) HTTP servers using this parser, and only under Ruby 1.9.2. --- So with this, I'm strongly considering making unicorn 5 depend on Ruby 1.9.3+, and not just Ruby 1.9.2+. ext/unicorn_http/unicorn_http.rl | 35 +++++++++++++++++++++++------------ test/unit/test_http_parser.rb | 10 ++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/ext/unicorn_http/unicorn_http.rl b/ext/unicorn_http/unicorn_http.rl index 3294357..16741e0 100644 --- a/ext/unicorn_http/unicorn_http.rl +++ b/ext/unicorn_http/unicorn_http.rl @@ -417,11 +417,31 @@ post_exec: /* "_out:" also goes here */ assert(hp->offset <= len && "offset longer than length"); } +static void hp_mark(void *ptr) +{ + struct http_parser *hp = ptr; + + rb_gc_mark(hp->buf); + rb_gc_mark(hp->env); + rb_gc_mark(hp->cont); +} + +static size_t hp_memsize(const void *ptr) +{ + return sizeof(struct http_parser); +} + +static const rb_data_type_t hp_type = { + "unicorn_http", + { hp_mark, (void(*))(void *)-1, hp_memsize, /* reserved */ }, + /* parent, data, [ flags ] */ +}; + static struct http_parser *data_get(VALUE self) { struct http_parser *hp; - Data_Get_Struct(self, struct http_parser, hp); + TypedData_Get_Struct(self, struct http_parser, &hp_type, hp); assert(hp && "failed to extract http_parser struct"); return hp; } @@ -527,21 +547,12 @@ static void finalize_header(struct http_parser *hp) rb_hash_aset(hp->env, g_query_string, rb_str_new(NULL, 0)); } -static void hp_mark(void *ptr) -{ - struct http_parser *hp = ptr; - - rb_gc_mark(hp->buf); - rb_gc_mark(hp->env); - rb_gc_mark(hp->cont); -} - static VALUE HttpParser_alloc(VALUE klass) { struct http_parser *hp; - return Data_Make_Struct(klass, struct http_parser, hp_mark, -1, hp); -} + return TypedData_Make_Struct(klass, struct http_parser, &hp_type, hp); +} /** * call-seq: diff --git a/test/unit/test_http_parser.rb b/test/unit/test_http_parser.rb index 2251dcf..2785df7 100644 --- a/test/unit/test_http_parser.rb +++ b/test/unit/test_http_parser.rb @@ -851,4 +851,14 @@ class HttpParserTest < Test::Unit::TestCase File.readable?(LINUX_PROC_PID_STATUS) && !defined?(RUBY_ENGINE) + def test_memsize + require 'objspace' + if ObjectSpace.respond_to?(:memsize_of) + n = ObjectSpace.memsize_of(Unicorn::HttpParser.new) + assert_kind_of Integer, n + assert_operator n, :<=, 56 # need to update this when 128-bit machines + end + rescue LoadError + # not all Ruby implementations have objspace + end end -- EW