Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

20 March 2014

Frame heap idea for Ruby

After listening to @srawlins great talk about new allocation stats features from @tmm1 in ruby 2.1, I got thinking about garbage collection in ruby.  BTW, MWRC 2014 is awesome so far!

I was wondering if there is some hybrid model that takes advantage of the call stack patterns that exist in server-side apps, or in apps that do a lot of iterative processing work.

If I could annotate a certain stack frame as a collection barrier, then I could write something that would modify collection behavior at that call boundary.  On the way in, I could pre-allocate per-call heaps that would be used up to capacity by all code from that point in the call graph on down.  On the way out, collection could be triggered to get rid of the garbage.

The benefits I can see here are as follows:
  • there is greater locality of reference in the heap for objects allocated within a certain call graph
  • objects that survive the frame heap collection would be merged into the global heap
  • objects that overflow the frame heap space would either cause another linked frame heap to be allocated, or would overflow to the global heap
  • there is greater opportunity for compacting the heap, per-call-graph collections imply compaction
  • different collection barriers can be collected in parallel, because unless the call graphs won't overlap, even if they happen concurrently, so concurrent collection logic is potentially lock-free

Possible points of annotation as collection barrier:
  • rack request
  • http client request
  • json parse / save
  • File.readlines w/ block
  • long-running loop{}s early in the stack

My thinking about heap and garbage collection is formed by what I've seen happen over the years in the HotSpot JVM heap structures.  First there was mark/sweep, with large pauses.  Then generational garbage collection came along, optimized for collecting new garbage, and only doing mark/sweep when an object has survived many early collection cycles.  Then there was the garbage-first collector which did memory region analysis, prioritizing entire regions of heap that are likely to contain the most garbage.

Ruby has seen some garbage collection innovation recently, and there is more to come in ruby 2.2.  However, maybe this is a novel idea that can help out.   Or maybe this idea isn't new and has been tried and has failed, but it was at least worth a try to get this out there.

10 January 2012

Awesome CLI gem: Commandable

Ever wanted to drive your ruby code with a CLI?  Well, the commandable gem makes it easy.

At first, I struggled with OptionParser in the stdlib, but I had to duplicate my option handling across CLI code and method invocation.  Then OptionParser didn't handle required parameters at all, requiring me to do required parameters in a non-DRY way.   Also, OptionParse doesn't do sub-commands, git-style, which I needed for the new git plugin I'm working on.

When I saw the pickled_optparse gem (from Mike Bethany), it appeared to solve the missing 'required parameter' feature.  And the subcommand gem seemed to allow for subcommands with their own options, git-style.  However, the duplication across option definition and method invocation was still present.  And even subcommand required you to hook up the command to the class/method that needed to be called.

Finally I found that the author of pickled_optparse had totally rethought CLI in ruby with his commandable gem.  And I really like what he did.

Now there is no real additional logic AT ALL in order to hook your ruby class up to the command line.  Now my option handling code will be in the place it belongs, in the code that is doing the command that I invoked from the command line.

The main awesomeness here is that commandable pushes the CLI code into the appropriate place in your ruby class -- it makes it hard to scatter CLI code all over the place.

My only beef with the gem are the following points:

  • it comes with colors enabled by default (unusual for a CLI)
  • it clears the screen by default when displaying help (when colors are enabled, very unusual and annoying for a CLI)
  • it appears to be hard to do global options like: "cmd --global subcommand [args]"
  • there is no support for parsing command CLI-style options into ruby hashes, but this is a minor nit, because that's what OptionParser is for, and it's easy to use inside the method


I fixed a problem where the screen was cleared even if you disabled colors, and I've pushed it up to my fork.

Here is my hello world that shows commandable in action:

And here's the output for a few representative cases:

21 December 2011

Intrusion Detection through Stackable Filesystems

I've always wondered what exploit might be running on my system, and never had any time to devise/install a detection system that would have the right balance of useful detection (maximize) and performance impact (minimize).

When I stumbled upon unionfs a couple weeks ago, I thought that was an interesting idea from a change-logging perspective.  It's sometimes useful to be able to keep a filesystem-based diff of what a certain operation does to a system, and then bake it onto the system when I know it did what I wanted to.  The takeaway for me was that unionfs's performance profile had the opportunity to be so low because it was so thin and so baked into the kernel.

This compounded with my recent discovery and fiddling with fusefs (in user-land) and I wondered about what kind of useful logic I could put underneath a filesystem.  The GlusterFS feature set, the recent LessFS GC stuff, the bup-fuse stuff, and the S3FS stuff is all just *really* cool.  I ended up gazing longingly at the big backlog of fuse filsystem suggestions on their wiki, and wandered back into the unionfs space.

So, when I saw the I3FS paper (linked from here) about the modular application of this technique to intrusion detection, this really triggered the Useful *AND* Performant neurons and I got really excited.

Unfortunately, on first glance, the stackable filesystems stuff seemed pretty cryptic to set up in a lightweight, just-works kind of way (think custom mount command-lines complete with arcane stacking options).

It would be soooo awesome to have an easy-to-compose ruby DSL for doing some kind of rack-like filesystem mashup with a kernel-level unionfs layer underneath a user-land fusefs layer, but all expressed in the same DSL.

This would be an awesome tool to put on top of the Arch-derived clone I want to put up for people at work.  There are folks who care about living more on the edge of linux stuff, but that don't care to install from scratch, and also might not care that much about not having a full Gnome stack if things just work.  And if I could give them the same tuned IDS-on-the-desktop solution (or upgrade their developer stack by letting them pull a filesystem delta over), that would be really cool.

The cheap development observation [PDF, linked from] because of modularity is one of attributes valued highly by the Ruby community as well.  It is one the key things that makes Ruby as a community awesome.

These kinds of ideas really matter, and making them so cheap and stable that you don't have to think about them really matters even more.

NOTE: The I3FS paper is really pretty old (2004), and the whole unionfs stack is older than that.  The fuse stack came into the kernel a long time ago too (2005).  So while this is new to me, it's been around for quite a long time.  I'm playing catch-up.

Unicode Support Better Now in Ruby

Unicode support in Ruby has historically been one of Ruby's major problems for me.

With the advent of Ruby 1.9 of course, Unicode support started being added to the language.  However, it's not as straightforward as Java, which supported some version of Unicode from the beginning.

Even though it's been a rough decade, things are finally looking up.  In fact, I actually like the way things got factored after all of the mess.

The thing I like is that the minimal amount of support is included in the standard library, and it's easy to compose things in non-standard ways for weird scenarios or data in improperly encoded formats.

The core library has support for strings of codepoints and bytes and a flexible set of encoding facilities.

In addition, there are two libraries of interest:
  • unicode_utils - includes implementations of word-break functionality, grapheme boundaries, etc.
  • jcode (if you're stuck on ruby 1.8.x)

This series of posts gives you a full understanding of the topic.  Highly recommended!

This post gives a high-level view of where things were at around 2006, much of which is valuable background.

This post has a good summary of unicode-related resources, as does this stackoverflow question.

19 December 2011

Some Git/Ruby stuff of interest


While taking the git survey a while back, I encountered:

  • git-annex: awesome git-enabled large file archive support

which led me to:


also this morning ran into:

  • rib: irb, except better, including rib-heroku
  • rest-core: like rack, except for RESTful clients
  • gemgem: easy gem building, without all the hoe dependency cruft

I just wish that gem-man read the README{,.md} in the root of a gem (like gemgem does) if that gem didn't have a manpage.  Sounds like a good patch to send.  That will help me understand how gems can access their own filesystem post-install.

Thought you might like to know.

And btw, rbenv is way nicer to interact with than rvm, at least that's been my experience over the last couple weeks.

29 October 2011

Backwards Names

My family likes to play a fun game called Backwards Names.  This game is played by taking each name piece of a person's name and reversing the characters and trying to pronounce it fluently.

I was just sitting on the couch tonight after a long Saturday and not thinking about backwards names at all.  I had my laptop open to get some work done, but my son sat down next to me, and I wanted to show him some programming.

I started out in irb and just did some simple string substitution with his name, but irb and ruby make it so easy to just mess around that I ended up with an implementation of Backwards Names before I knew it.

Here it is:


It was just really fun to do that with him and see lights start to turn on about what programming was like.

19 October 2011

Git as Menograph

Background

In Mar. 2010, Matz came and talked at MWRC.

The awesome talk focused around Ruby as a great invention that makes it possible for programmers to bring a new world into being that could only be imagined before.

He made reference to the inventor in Hugo Gernsback's book: Ralph 124c 41 +.  The name was a play on words "One to foresee for one", with "+" being reserved for the 10 or so greatest inventors currently living.

Although Matz's reference could be interpreted as prideful, anyone who has ever had anything to do with him would correct you -- he is a very humble programmer who does awesome stuff.

Because I wanted to understand Matz's reference very thoroughly, I went and read the book.  I was able to appreciate the scope of Matz's talk much more clearly after having read about Ralph, the great inventor.

Menograph, the invention

One thing that Ralph invented was a Menograph.  It was a mind-recording device, operated by pressing a button that started a mind wave recorder and operated a scroll of fabric on which the waves were traced in ink, similar to an old-style seismograph.

The Menograph was one of Ralph 124C 41 +'s earliest inventions, and entirely superseded the pen and pencil.  It was only necessary to press the button when an idea was to be recorded and to release the button when one merely reflected and did not wish the thought-words recorded.

Those thoughts could then be replayed again verbatim by any person by use of a device called a Hypnobioscope.

After reading an account of Ralph using this invention, which is more detailed than I am able to reproduce here, I had a vague sense that I had experienced a similar feeling before while programming.

Git as Menograph

After thinking about it for a while, I realized that how Ralph used his Menograph is how I use git.

While coding, I work on stuff, then I record commits into git.  Then I work on stuff some more, then record commits.

Then I take passes back over what I've recorded and get rid of the bad stuff and keep the good stuff.  Then I push it out to the team.  Sometimes, a pair or triple on the team do this as a group exercise, working history over a few time until it won't break the world.

The parallel to git was eye-opening.  In fact, after having noticed this behavior in myself, and seeing the behavior tendency grow over time, I'd say that git encourages multi-pass thinking styles.

P.S.  If you care at all about Ruby, listen to Matz's talk.  Some of the future stuff he was talking about is already in Ruby 1.9.2.  NOTE: I'm on linux, and I had to use the flash player to get the video to show.

09 March 2011

Excited for MWRC

I am so stoked for MountainWest RubyConf this year. Last year was great, but I can feel it in the air that this year is going to be sooo much better!

20 March 2009

MountainWest RubyConf 2009

MountainWest RubyConf 2009 really helped me reorient in a very good way.

The emergent theme seemed to be "modularity".

Six main talks that were really enlightening:
Rack totally changed how I thought about building a webapp. Decomposing things into pieces that have the minimum to do with each other is possible in a really clean way with rack. And treating each of those pieces as a separate app, even, with its own release schedule, etc. -- that was a very refreshing view.

When I heard Jon say that the Perl script he had up on the screen was a monolith -- he was absolutely right. And I thought that the system *I* was working on was a monolith.

I was going to give a lightning talk about fshelper.org's link feature, but I wanted to rewrite it in broken-up rack pieces. I tried my best to do that between talks, but I didn't quite get the app to function as middleware, so I just gave up and listened.