[ANN] eventmachine 0.12.8

I am happy to announce the release of eventmachine 0.12.8. Gems (including
binary builds for win32 and jruby) have been uploaded to rubyforge and should
be available via `gem install` shortly.

This release contains almost 100 patches with numerous bug fixes, improvements
and several new features. Highlights include:

  - Major code cleanups
    - converted all tabs to spaces in ruby source files
    - better documentation for all methods and classes
    - moved all protocol implementations to em/protocols/
    - split out eventmachine.rb to em/{connection,version,timers}.rb
    - removed several deprecated methods and classes
    - rake java:gem task to generate a binary jruby gem

  - Reactor fixes and improvements
    - worked around a kqueue bug in OSX causing nbytes>0 assertion failures
    - reduced the stack size of the epoll/kqueue reactors (this fixes a
      long-standing issue causing performance issues with ruby threads)
    - platforms that support it will use writev() to write data to the
      network, resulting in fewer memcpy()s
    - explicitly set non-blocking mode on attached sockets
    - allow read/write pipes to be watched using EM.attach
    - gettimeofday() is called only once per tick and used for timers,
      heartbeats and gCurrentLoopTime

  - Protocol improvements
    - added a simple DRb style ObjectProtocol, for communication using ruby
      objects (i.e. simple rpc server/clients: http://gist.github.com/96699)

        module RubyServer
          include EM::P::ObjectProtocol

          def receive_object obj
            send_object({'received object' => obj})
          end
        end

    - HttpClient2 callbacks are now passed in the response object
    - cleaner Postgres protocol

  - New APIs
    - EM.kqueue= and EM.epoll= can be used to toggle kqueue/epoll
    - EM.threadpool_size= sets the size of the EM.defer threadpool
    - EM.ssl? will check if the reactor was built with ssl support
    - EM.schedule{} helper runs a block in the main reactor thread
    - EM.reactor_thread? checks if the current thread is the reactor thread
    - EM.system now returns the new process' pid and can take multiple args

        pid = EM.system('sleep', 1000){ |out, status|
          # pid == status.pid
          # 15 == status.termsig
          p [pid, out, status]
        }
        Process.kill 15, pid

    - EM::Channel allows for in-reactor publish/subscribe

        chan = EM::Channel.new
        sid = chan.subscribe{ |msg|
          p [:got, msg]
        }

        chan.push('hello')
        chan.push('world')
        chan.unsubscribe(sid)

    - EM::Queue provides a simple queue with asynchronous pops

        q = EM::Queue.new
        q.push(1, 2)
        3.times do
          q.pop{ |num| p [:got, num] }
        end
        q.push(3)

    - EM.watch_file uses kqueue on OSX or inotify on linux to watch a file,
      triggering events when the file is modified, moved or deleted

        module EtcPasswd
          def file_modified
            STDERR.puts 'WARNING /etc/passwd WAS MODIFIED'
          end
        end

        EM.run{
          EM.watch_file '/etc/passwd', EtcPasswd
        }

    - EM.watch_process will watch a pid, triggering events when the process
      forks or dies (note this currently only works with kqueue)

        module DaemonWatcher
          def process_exited
            STDERR.puts 'WARNING your daemon has died'
          end
        end

        EM.kqueue = true
        EM.run{
          EM.watch_process(some_daemon_pid, DaemonWatcher)
        }

    - EM.enable_proxy will natively proxy data between two connections, without
      the overhead of converting incoming data to ruby strings
    - EM::Connection#comm_inactivity_timeout= now takes a float
    - EM.heartbeat_interval= changes how often sockets are checked
      for inactivity
    - EM.bind_connect binds an outgoing socket to a specific local ip/port
    - EM::Connection#ssl_verify_peer callback allows servers to verify client
      ssl certificates (use start_tls(:verify_peer => true))

  - Ruby API fixes
    - EM.add_timer() can take a number of seconds as a string
    - EM.open_datagram_socket() correctly handles string ports
    - EM::Connection#send_data will now call .to_s on its argument
    - the EM.next_tick{} queue is cleaned up on reactor shutdown (this fixes an
      issue in AMQP when connecting and disconnecting multiple times)
    - fixed potential memory leak in EM.cancel_timer

At this time, there are a few known issues which will be fixed for 0.12.10,
along with a couple new features that are in the works:

  - EM.current_time is broken

      EM.current_time returns random time objects due to a change to
      gCurrentLoopTime in the reactor. This has been fixed in the latest
      git master branch.

  - ruby 1.9 win32 support

      EM works with 1.9 on linux, but still fails to build on win32. The
      next release will include an official win32 ruby 1.9 binary gem.

  - EM::Iterator

      Looping over large arrays blocks the reactor and introduces latency.
      0.12.10 will include EM::Iterator to spread out iterations over multiple
      reactor ticks.

  - jruby patches

      Interest in the jruby reactor has been increasing, and there are several
      patches in the works by Hemant 'gnufied' Kumar. 0.12.8 works with jruby,
      but is missing several features that are available in the c++ reactor.

  - require 'openssl' issues

      Custom ruby builds on OSX will segfault if you require 'openssl' after
      eventmachine. To work around this issue, simply:

        require 'openssl'
        require 'eventmachine'

  - async dns lookups

      There are currently a few ways of doing async dns lookups with EM,
      using either em-dns, em-asyncns or dnsruby. The next release will
      include an async dns implementation which will be used by default.

  - exceptions in post_init/initialize are silently swallowed

      Exceptions raised in your handler's post_init or initialize methods
      are silently swallowed and cause an ConnectionUnbound error to surface
      later on with a confusing error message. If you're experiencing issues,
      use an error handler to catch the original exception:

        EM.error_handler{ |e|
          puts e
          puts e.backtrace.join("\n ")
        }

  - process watching on linux using netlink

      EM.watch_process is currently only implemented for kqueue. The next
      release will add support for linux using the netlink code from God.

  - better, more stable test suite

      The current test suite is very unstable and does not test the pure ruby,
      jruby, kqueue or epoll reactors. We plan on overhauling the suite to
      provide better test coverage and ensure stability of the different
      reactors and platforms.

Special thanks to the following people for making this release possible:
  - Bob Potter
  - Eugene Pimenov
  - Jake 'yakischloba' Douglas
  - Joern Barthel
  - James 'raggi' Tucker
  - coderrr

The rdoc has been updated and is available at http://eventmachine.rubyforge.org

  Aman