puma-dev on OSX follow up (tips and tricks)

I’ve been doing a lot more Rails dev recently, and as I wrote about previously, I’ve really been enjoying using puma-dev to do that. I just wanted to add a couple of things to that initial post that may not be initially apparent.

Getting puma to stay idle longer

Out the box, puma-dev will spin down an app after 15 minutes of inactivity. This was a bit short for my tastes so I went asking around for how to extend this. Turns out you can run a simple command …

puma-dev -install -timeout 180m

On OSX this actually updates the plist file that launches puma-dev directly. which brings me to the next point …

Restarting puma-dev manually

On OSX. The puma-dev plist file used by launchd to run puma-dev on startup, seems to be located at /Users/<your username>/Library/LaunchAgents/io.puma.dev.plist

The reason why this is important is that in the puma-dev readme, it says to restart puma-dev by running.

pkill -USR1 puma-dev

However. Lets say, you’ve misconfigured your plist file (like I managed to do), launchd will keep trying to run puma-dev and failing all the while spitting out an error that looks like this in your puma log files every ten seconds

Error listening: accept tcp 0.0.0.0:0: accept: invalid argument

The dead giveaway is entries like this in your system log files located at /private/var/log/system.log

io.puma.dev[1616]): Service exited with abnormal code: 1
Service only ran for 0 seconds. Pushing respawn out by 10 seconds

To stop this just run this command


launchctl unload /Users/<your username>/Library/LaunchAgents/io.puma.dev.plist

This will let you fix up your plist file. Then you can restart it with this command

launchctl load /Users/<your username>/Library/LaunchAgents/io.puma.dev.plist

You can also use this as a way of starting and restarting puma-dev.

Running on a different port

If you have Apache running on port 80 and don’t pass in the right command when installing then puma-dev will fail to launch, and keep failing as described above.

This means you have to run `puma-dev install` with the http-port flag, for example

puma-dev -install -http-port 81

I like this, not for the reason you’d think, but because it allows me access my apps on https://<appname>.dev, while still accessing my php apps with apache on port 80!

Something to note though is that you have to run this command everytime you run `puma-dev install`, or else it will overwrite your settings in your plist file and cause you hours of grief as you try to figure out how you broke all the things amidsts rending of hair and gnashing of teeth

To illustrate … say you have your port set to 81 and you run the command we discussed first

puma-dev -install -timeout 180m

This will reset your port to 80 quietly, and puma-dev will start failing as I described previously. so to avoid that you want to run

puma-dev -install -timeout 180m -http-port 81

instead.

This behavior is subtle enough to cause problems for someone who may have installed puma-dev a while ago and forgotten where everything is and how it all works, so I filed a bug report about it.

Hope this helps someone avoid a stressful afternoon or two!

Fixing the Ruby reject! method

Fun look at the bug/bugfix that caused the Ruby reject! method to go from linear complexity – O(n) – to quadratic complexity – O(n^2) – starting in Ruby 1.9.3*

*Since fixed in Ruby 2.3

http://accidentallyquadratic.tumblr.com/post/157496054437/ruby-reject

json (1.8.3) and rubyracer gems aren’t compatible with ruby 2.4.0

PS: This is moot anyway because it looks like Rails 4.2 doesn’t fully support Ruby 2.4.0 yet

Ran into this problem trying to upgrade a Rails app to use the new version of Ruby.

make "DESTDIR="
compiling generator.c
generator.c:861:25: error: use of undeclared identifier 'rb_cFixnum'
} else if (klass == rb_cFixnum) {
^
generator.c:863:25: error: use of undeclared identifier 'rb_cBignum'
} else if (klass == rb_cBignum) {
^
generator.c:975:5: warning: division by zero is undefined [-Wdivision-by-zero]
rb_scan_args(argc, argv, "01", &amp;opts);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Yikes!

Turns out this is because of Bignum/Fixnum integration that rolled out in ruby 2.4.0

after that I hit another fugly stack trace caused because I hadn’t upgraded therubyracer gem to 0.12.3

I had to include the gems and specific versions in my gemfile

gem 'json', '~> 1.8.6'
gem 'therubyracer', '~> 0.12.3'

then run

bundle update json

Unfortunately, as I mentioned above, I was unable to run Rails 4.2.7 anyway, because it looks like it hasn’t been fully prepped to incorporate Ruby 2.4.0’s integer changes.

Suddenly failing `rvm install`command on os x 10.11 (El Capitan)

This actually started with a strange error, when I went to fire up a rails server in an app I’d been working on the night before.

Unable to load application: LoadError: dlopen(/Users/xxx/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/x86_64-darwin14/readline.bundle, 9): Library not loaded: /usr/local/opt/readline/lib/libreadline.6.dylib

Like I mentioned, I’d fired up this app less than 24 hours prior, so this was very strange to me. Some quick googling around suggested that I try to reinstall my ruby version so I ran the command

rvm reinstall 2.3.0

Well that errored out with another strange error

ruby-2.3.0 - #configuring...........................................................
ruby-2.3.0 - #post-configuration.
ruby-2.3.0 - #compiling...........
Error running '__rvm_make -j 1',
showing last 15 lines of /Users/xxx/.rvm/log/1476345601_ruby-2.3.0/make.log
compiling enc/trans/newline.c
compiling ./missing/explicit_bzero.c
compiling ./missing/setproctitle.c
compiling dmyenc.c
linking miniruby
dyld: lazy symbol binding failed: Symbol not found: _clock_gettime
  Referenced from: /Users/xxx/.rvm/src/ruby-2.3.0/./miniruby (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib
 
dyld: Symbol not found: _clock_gettime
  Referenced from: /Users/xxx/.rvm/src/ruby-2.3.0/./miniruby (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib
 
make: *** [.rbconfig.time] Trace/BPT trap: 5
++ return 2
There has been an error while running make. Halting the installation.

You might notice the “(which was built for Mac OS X 10.12)
which is a bit of a hint at what the problem is.

Because the last line hints the problem is with make, I decided to reinstall make with brew and it dumped the solution to the problem in my lap

brew install make
Warning: You have Xcode 8 installed without the CLT;
this causes certain builds to fail on OS X El Capitan (10.11).
Please install the CLT via:
sudo xcode-select --install

Basically I’d upgraded my Xcode version without installing command line tools. Once I ran this command, my rvm reinstall went fine and my readline problems went away.

Merry Christmas Rubyists … Ruby 2.3.0 is here!

Ruby 2.3.0 has been released

Significant new features include &., Array#dig, Hash#dig and the very user-friendly “did you mean” when you get the name of a gem wrong when bundling your gems.

Of course there are performance improvements, but this blog post brilliantly walks through all the new cool stuff in Ruby 2.3.0 … bookmark away!

Also worthy to note that Heroku currently supports Ruby 2.3.0 but is running a preview version, I’d expect an update to the final release before the end of the year

 

Is Ruby pass-by-reference or pass-by-value?

I was confused by Ruby’s variable assignment paradigm for a while, and even after reading this Stackoverflow thread and checking out out other threads about the same thing I was no closer to understanding it clearly. And in the words of the great Albert Einstein …

“if you can’t explain it simply you don’t understand it well enough”

I eventually figured it out by reading page 53-54 of what I think is the best Ruby book on the market right now, turns out its actually pretty simple to understand.

Ruby ALWAYS passes references to objects on assignment, BUT some types in ruby are stored in variables as immediate values because they are immutable.

For example (you can try these out in irb)

me = we = “we”
me #=> “we”
we #=> “we”
me.upcase!
me #=> “WE”
we #=> “WE”

me = we = [1, 2, 3]
we #=> [1, 2, 3]
me #=> [1, 2, 3]
we << 4
we #=> [1, 2, 3, 4]
me #=> [1, 2, 3, 4]

Ruby does this for all its types, but with primitives that are immutable, namely integers, symbols, nil, and the booleans true and false, it takes a shortcut and actually stores the value IN the variable itself, because … what are you going to do? change an immutable object? 🙂

Pretty clever when you think about it IMO.

I upgraded to Ruby 2.1.0 and all I got was this lousy T-shirt …

Ruby 2.1.0 was released about 2 weeks ago, and after seeing a notable speed performance improvement with my Rails app when going from 1.9.3 to 2.0.0 I was excited to see if the same would happen with Ruby 2.1.0.

I quickly ran another set of very casual tests, mainly running test suites and noting startup times of rails commands and rake tasks at the command line. What I saw was a 20% improvement in those tasks. Nothing to sneeze at …

Excited, I rushed to upgrade my tiny Rails app to ruby 2.1.0 and after doing it I tracked the difference in New Relic

This was my result (deployment happened about 18:00 on December 25th, app is setup to run with one puma worker and 8-16 threads proxied to nginx)

New Relic graph after upgrading to Ruby 2.1.0 (18:00 on the graph)As you can see, there wasn’t much of an improvement in performance at all. In fact here is the graph after a full day of running in the wild.

New Relic graph of my app after a full day of running with Ruby 2.1.0

 

So while you might get better startup times on Rails tasks, you probably won’t see too much of a speed boost on your servers.

Improved GC

What I found interesting, though, is the improved garbage collection. The brown part of the graph (GC execution) almost completely disappears in ruby 2.1.0. And its no wonder, a lot of work went into improving Garbage collection in ruby 2.1.0

The garbage collector in Ruby 2.1 implements a form of generational garbage collection, with Ruby calling their implementation RGenGC (Restricted Generational Garbage Collection).  This replaces the “Mark & Sweep” implementation used in previous versions of Ruby

Using RGenGC provides high compatibility with existing extensions while still bringing performance improvements.  Popular objects Array, String, Hash, Object, and Numeric are Write-Barrier protected, thus able to take advantage of the RGenGC system

The moral of the story? Ruby 2.1.0 has a small performance boost over Ruby 2.0 and upgrading to it should give you a bit of a boost with your Rails app, more if its a pretty big app with non-trivial time spent doing GC.

PS: Brian Hempel has created an awesome site that benchmarks ruby versions using Rails. His results are in line with what I found
PS2: Sorry there wasn’t actually a T-shirt, I just liked the title

tracking down *exactly* where a Ruby object method is defined

Ever spent way longer than you would have liked trying to find out exactly where a particular Ruby object method is defined, especially in something like Rails where a method could have been included from a plugin, gem, helper, or otherwise metaprogrammed in?

Well with Ruby 1.9.3 … you can now do this

Post.first.method(:published?).source_location

and get this back

=> [“/Users/xxx/.rvm/gems/ruby-1.9.3-p362/gems/state_machine-1.1.2/lib/state_machine/machine.rb”, 752]

Blew my mind, and I’ve been writing Ruby for almost 6 years now.

Ruby 2.0.0 is looking like its going to be substantially faster than Ruby 1.9.3

In very unscientific tests Ruby 2.0 is 60-70% faster than 1.9.3.
Very promising.

PS: I couldn’t get my test suite to run in Ruby 2.0.0 but I managed to run the very simple
“time bundle exec rake environment” test

The average was
– 7.74s for ruby 2.0.0
– 11.8s for ruby 1.9.3-p368, a 65% speed improvment, right in line with the results from the gist
– 17.07s for rubinius 2.0.0 (1.9 variant) … yeah thats slow

Unit Testing and Mock Objects

Recently, I’ve been working hard to plug one of the biggest holes in my game … testing. I stumbled across this article, which helped make a lot of things clear for me, with respect to mocking and its relation to Unit testing.

This is partially due to the fact that most geeks don’t actually know what a unit test is. They think that testing the methods of a specific class constitutes a unit test, but that’s only part of the story. A unit test test is when you test the methods of a specific class in isolation, and the difference is critical. You know how some people call us “computer scientists”. Yeah, well this is the science part.

If you’re not doing this, you are not unit testing. That’s not meant to deride what you’re doing. I mean that as a literal statement of fact. Anyone, for example, who is using the built in Rails “unit” testing framework with fixtures (or FactoryGirl fixtures) is guilty of this. No test that relies on a separate class, or API, or interfaces with a database in any way is a unit test. It is an integration test (some people call them functional test), and when something goes wrong it is just a matter of time before it misleads you.

Enjoy the article – The Thing about Mock Objects

How to get Ruby Native gems to install on your windows machine

The bane of any ruby/rails developer on a windows box (apart from piddling performance) is seeing the dreaded …
‘gem install error – ‘cl’ is not recognized as an internal or external command’

No more!
Devkit, a tool used by the folks who create the Windows Ruby Installer of each version of ruby helps you with (most) gems that need to be built natively.
Muchos Gracias to them for graciously providing it to us.

From the books: Exceptions to Ruby’s standard variable assignment by reference behavior

The un-reference: immediate values
Some objects in Ruby are stored in variables as immediate values. These include integers, symbols (which look like :this), and the special objects true, false and nil. When you assign one of these values to a variable (x = 1), the variable holds the value itself, rather than a reference to it

— From page 54 of The Well Grounded Rubyist by Robert Black

Filed under Things I did not know about Ruby 😀

41A+B9T4yGL._SS500_

Fixing the libxml-ruby gem error: uninitialized constant XML (NameError)

I found the highly recommended libxml-ruby gem but was having a lot of trouble getting my sample code below to work

1
2
3
4
require 'libxml'
doc = XML::Document.file('http://search.twitter.com/search.atom?q=obama')
root = doc.root
puts "Root element name: #{root.name}"

I kept getting this error

uninitialized constant XML (NameError) Continue reading

php’s print_r equivalent in ruby on rails

I was going through my google analytics logs today and I noticed that a lot of folks were coming to my site on Google searches for stuff like ‘print_r + ruby on rails‘.

So I figured I’d write a blog post about it, because I’ve had the same problem.

What you’re looking for is ‘inspect’.

If you have an array, hash or object that you want to take a quick-and-dirty look at just type in

objectname.inspect

eg:

posts.inspect

or if you’re in rails just do …

render :text => posts.inspect and return false

and you’ll get an output of the contents of said array, hash or object.

Here is a screen capture of a quick irb session to show you how it works.

print_r equivalent in ruby on rails

I hope this helps.