14 Ruby and Rails Jobs for August 2010 »

Created at: 24.07.2010 01:35, source: Ruby Inside, tagged: Miscellaneous

It's been a couple of months since the last job round up but the Ruby Inside job board has been hopping! There are 14 live listings to go over today and they're not all in San Francisco. Jobs in Denver and Maryland bring in a bit of interesting variety.

A tweak to the format now that Ruby Inside has gone all "tumblelog" on you: I've decided not to include blurbs about every job in the listings since if you're interested in a company or the location is suited to you, you're going to click through and read the extended information anyway. Most companies give quite a lot of detail so click through and check them out.

Ruby on Rails Developer(s) (Entry-level-to-Senior)
CreaTek Solutions, Inc. —Boulder, Colorado

Ruby on Rails Developer
Foraker —Boulder, Colorado

Senior Ruby on Rails Developer
Get Satisfaction —San Francisco, California

Sr. Ruby Engineer- CoTweet
ExactTarget + CoTweet —San Francisco, California

Ruby On Rails Developer
On-Site.com —Lafayette, Colorado

Front End Developer
SingleFeed —San Francisco, California

Rails Developer
Context Optional, Inc —San Francisco, California

Sr. Ruby on Rails Programmer (or perl/python/django/catalyst)
Insight —Birmingham, Alabama

Software Engineer, Scalability
Zendesk —San Francisco, California

Software Ruby/Rails leader Engineers
RotoHog —Los Angeles, California

RoR Engineer
Zendesk —San Francisco, California

User Interface Software Engineer
BoxTone —Columbia, Maryland

Front End Developer
Zendesk —San Francisco, California

Frontend Engineer
Onehood, Inc —San Francisco, California

Want your job(s) to appear on Ruby Inside and on the sidebar of Rails Inside? Check out our "Post a Job" page for info on how it all works and how much it costs.


more »

Software Craftsmanship 2010 »

Created at: 24.07.2010 00:04, source: The GitHub Blog

The Software Craftsmanship North America 2010 conference looks pretty interesting and has a killer speaker lineup. Gonna be in Chicago in October? Check it out. Want to be in Chicago in October? Here's your excuse!

Some info from the conference itself:

Software Craftsmanship North America (SCNA) is planting a root in the industry as the premier event for the Craftsmanship movement. Software Craftsmanship, which sprouts from the Agile Principles, embraces the core attributes of successful software developers. SCNA is the place to be to develop new software skills and techniques, meet other devoted craftsmen, or find quality people for your company!

Early bird registration ends August 15th so grab a ticket today!


more »

August 3rd »

Created at: 23.07.2010 17:39, source: RailsTips - Home, tagged: harmony

We are going to be opening Harmony’s doors on August 3rd. It has been a long time coming and I am excited/nervous about the launch, but that is no reason to keep things locked up.

We already have over 60 live sites and several paying customers, so we are quite confident that Harmony is ready for consumption.

For now, you can check out the features, view the pricing, read the documentation, and comment on the blog.


more »

An Introduction to Refinery CMS – A Rails Content Management System »

Created at: 22.07.2010 23:53, source: Rails Inside, tagged: Miscellaneous

Refinery CMS is an open source Ruby on Rails CMS for small businesses. The project was originally closed source for 4 years at Resolve Digital until it was finally released to the open source community in mid 2009. Refinery focuses on doing things "the Rails way" where possible. This means you don't have to learn too much to start theming it and building your own custom plugins.

refinery-dashboard.png

What it's it good at?

Refinery is great for small business sites where the client needs to be able to update their website themselves without being bombarded with anything too complicated.

Unlike other content managers, Refinery is truly aimed at the end user making it easy for them to pick up and make changes themselves. The UI is clean and simple so the end user feels at ease and hopefully won't bug the developer with questions!

What Features Does It Have?

  • Theming support
  • Easy to use Rails-like plugin generator and plugin architecture
  • WYSIWYG content editing
  • Localisation (currently supports 10 langauges)
  • Page management
  • Image and File management
  • Contact form and inquiry management
  • Search Engine Optimisation

How do I install it?

Firstly install the Refinery CMS gem. This gives you a 'refinerycms' command you can run that creates a new Rails project with Refinery CMS hooked into it.

gem install refinerycms
refinerycms path/to/project

Finally change into the project start the web server

cd path/to/project
ruby ./script/server

Visit http://localhost:3000 and set up your first Refinery user.

What's coming up in Refinery CMS

Refinery is gearing up for it's 1.0 release with Rails 3.0 support. There is also a Refinery Day coming up where members of the community will be combining efforts to support Rails 3. Check the Google Groups below for details.

Useful Links

david-jones.jpgPost written by David Jones. David started Refinery CMS in 2004 and is the Technical Director at Resolve Digital, a Rails development company with offices in New Zealand and California.

Post to Twitter Tweet This Post


more »

A Gentle Introduction to Isolation Levels »

Created at: 21.07.2010 13:16, source: Engine Yard Blog, tagged: Uncategorized

Hello all, Our latest post is from a special guest and Engine Yard partner Xavier Shay. He'll be running a pair of training sessions on "using your database to make your Ruby on Rails applications rock solid" at Engine Yard's San Francisco office on the 24th and 31st of July. Visit www.dbisyourfriend.com for course and registration details.
Bob opens a database transaction and selects everything from the books table. Tom comes along and adds a new book, then Bob, in his same transaction, repeats his same query for all the books. Does Bob see the new book that Tom added? The answer is that you get to choose! It's important to understand what your choices are (and what choice your preferred database makes for you) so that you can ensure your code executes in a way that you intend. The SQL standard specifies levels for how "isolated" transactions running at the same time are, all the way from being able to see uncommitted changes (not isolated) to effectively running the transactions in serial (full isolation). Academically there are eight levels of isolation, but for most purposes you only need to worry about the four defined by the standard. MySQL implements all four, PostgreSQL only two. You can specify a global isolation level for your database, but also override it for individual transactions. The easiest to understand are the extreme levels: no isolation and total isolation. The first of these is known as *read uncommitted*, and it allows Bob to read the new book that Tom is adding _even before Tom has committed his changes_. As you can imagine this level is mostly useless, however it can very occasionally be handy in some reporting situations. At the other end of the spectrum is full isolation, known in the spec as **serializable**. Bob will never see the new book that Tom is adding until he starts a new transaction. The database Bob sees is consistent---within the one transaction, the same query will always return the same result. At first glance this level seems like a great option but there's a lot of overhead involved, it drastically reduces the amount of concurrency you can achieve, and for most purposes the serializable level is overkill. There are two isolation levels in between read uncommitted and serializable, they are *read committed* and *read repeatable*, and this is where it gets interesting. Read committed is the default isolation level in PostgreSQL and Oracle, and is one step up from read uncommitted. It is the most "common sense" level: Bob will not see any changes made by Tom until Tom commits them. MySQL defaults to *read repeatable*. In this level, Bob will not see any _updates_ Tom commits, but will see any _inserts_. Say in Bob's first select he sees one book titled "The Odessey". Tom then fixes the spelling mistake to "The Odyssey", and also add Homer's other epic poem "The Iliad". When Bob selects all books again, he will see "The Odessey" (old title, no spelling fix) and "The Iliad" (the inserted book). To summarize, the four levels from least isolated to most isolated are: *read uncommitted*, *read committed*, *repeatable read*, and *serializable*. They define what types of changes made by Tom that Bob will be able to see within a single transaction. h2. In Practice Say the books we are selecting are ordered based on an arbitrary position column (they're on our bookshelf, for instance). Assume read committed isolation level.
Title       | Position
----------------------
The Odyssey | 1
The Iliad   | 2
The Nostoi  | 3
Bob wants to move "The Odyssey" to the bottom position. To do this, he needs to update its position to the bottom of the list (position 4), then subtract 1 from all positions. At the same time, Tom is adding a new book "The Cypria". Working this through: # Bob checks the bottom position, finds it to be 4 # Tom inserts "The Cypria" in the bottom position of 4 # Bob updates the position of "The Odyssey" to 4 # Bob subtracts 1 from all positions, and since he is using *read committed* he will "see" and update the newly inserted book. # Both "The Odyssey" and "The Cypria" have a position of 3
Title       | Position
----------------------
The Iliad   | 1
The Nostoi  | 2
The Odyssey | 3
The Cypria  | 3
If Bob had used the *serializable* level, the list would have remained consistent for his entire transaction, so his update would not have affected "The Cypria" that Tom inserted, and so would not have updated its position from 4 to 3. (In practice the way databases normally handle this is to actually abort one of the transactions with an error.) For those using Rails, you may have recognized the above scenario as a typical @acts_as_list@ scenario, and you'd be correct. In a default configuration, the @acts_as_list@ plugin makes the same mistake outlined above, and will leave you with inconsistent data. The quickest fix is to wrap all list operations in a serializable transaction.
Book.transaction do
  Book.connection.execute("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE")
  @book = Book.find_by_name("The Odyssey")
  @book.move_to_bottom
end
(It may have occurred to you that some locking or a unique index on position could avoid the exact scenario above, but that breaks @acts_as_list@ and fails to address some other edge cases left as an exercise for the reader. The main point for the purpose of this article is to understand why it breaks under read committed, but works under serializable.) As a general rule, read committed is a sensible default. It's easy to reason about, fast, and forces you to be explicit about your locking strategy. Jump up to serializable when needed, usually when dealing with ranges. MySQL's repeatable read default can be confusing and deadlock in unintuitive ways, as such it is not recommended. This has been a very brief introduction to the four standard SQL isolation levels: read uncommitted, read committed, repeatable read, and serializable. Hopefully it has helped you get your head around them. I'll be going into much more detail with practical hands on exercises in my training days at Engine Yard's San Francisco office on the 24th and 31st of July. Visit www.dbisyourfriend.com for course and registration details.


more »

GCC optimization flag makes your 64bit binary fatter and slower »

Created at: 20.07.2010 15:59, source: time to bleed by Joe Damato, tagged: debugging linux systems testing x86


If you enjoy this article, subscribe (via RSS or e-mail) and follow me on twitter.

The intention of this post is to highlight a subtle GCC optimization bug that leads to slower and larger code being generated than would have been generated without the optimization flag.

UPDATED: Graphs are now 0 based on the y axis. Links in the tidbits section (below conclusion) for my ugly test harness and terminal session of the build of the test case in the bug report, objdump, and corresponding system information.

Hold the #gccfail tweets, son.

Everyone fucks up. The point of this post is not to rag on GCC. If writing a C compiler was easy then every asshole with a keyboard would write one for fun.

WARNING: THERE IS MATH, SCIENCE, AND GRAPHS BELOW.

Watch yourself.

The original bug report for -fomit-frame-pointer.

I stumbled across a bug report for GCC that was very interesting. It points out a very subtle bug that occurs when the -fomit-frame-pointer flag is passed to GCC. The bug report is for 32bit code, however after some testing I found that this bug also rears its head in 64bit code.

What is -fomit-frame-pointer supposed to do?

The -fomit-frame-pointer flag is intended to direct GCC to avoid saving and restoring the frame pointer (%ebp or %rbp). This is supposed to make function calls faster, since the function is doing less work each invocation. It should also make function code take fewer bytes since there are fewer instructions being executed.

A caveat of using -fomit-frame-pointer is that it may make debugging impossible on certain systems. To combat this on Linux, .debug_frame and .eh_frame sections are added to ELF binaries to assist in the stack unwinding process when the frame pointer is omitted.

What is the bug?

The bug is that when -fomit-frame-pointer is used, GCC erroneously uses the frame pointer register as a general purpose register when a different register could be used instead.

wat.

The amd64 and i386 ABIs1 2 specify a list of caller and callee saved registers.

  • The frame pointer register is callee saved. That means that if a function is going to use the frame pointer register, it must save and restore the value in the register.
  • The test case provided in the bug report shows that other caller saved registers were available for use.
  • Had the function used a caller saved register instead, there would be no need for the additional save and restore instructions in the function.
  • Removing those instructions would take fewer bytes and execute faster.

What are the consequences?

Let’s take a look at two potential pieces of code.

The first piece is the code that would be generated if -fomit-frame-pointer is not used:

test1:
        pushq %rbp       ; save frame pointer
        movq %rsp,%rbp   ; update frame pointer to the current stack pointer
           ; here is where your function would do work
        leave            ; restore the stack pointer and frame pointer
        ret              ; return

Size: 6 bytes.

The above assembly sequence uses the frame pointer.

Let’s take a look at the code that is generated by GCC when -fomit-frame-pointer is used:

        sub $0x8, %rsp    ; make room on the stack
        movq %rbp, (%rsp) ; store rbp on the stack
          ; here is where your function would modify and use %rbp as needed
        movq (%rsp), %rbp ; restore %rbp
        add $0x8, %rsp    ; get rid of the extra stack space
        ret               ; return

Size: 17 bytes.

The above assembly sequence is what is generated when GCC decides to use the frame pointer register as a general purpose register. Since it is callee saved, it must be saved before being modified and restored after being modified.

So -fomit-frame-pointer makes your binary fatter, but does it make it slower?

Only one way to find out: do science.

I built a simple (and very ugly) testing harness to test the above pieces of code to determine which piece of code is faster. Before we get into the benchmark results, I want to tell you why my benchmark is bullshit.

Yes, bullshit.

You see, it makes me sad when people post benchmarks and neglect to tell others why their benchmark may be inaccurate. So, lemme start the trend.

This benchmark is useless because:

  • Reading the CPU cycle counter is unreliable (more on this below the conclusion). I also tracked wall clock time, too.
  • I don’t have the ideal test environment. I ran this on bare metal hardware, and set the CPU affinity to keep the process pinned to a single CPU… BUT
  • I could have done better if I had pinned init to CPU0 (thereby forcing all children of init to be pinned to CPU0 – remember child processes inherit the affinity mask). I would have then had an entire CPU for nothing but my benchmark.
  • I could have done better if I forced the CPU running my benchmark program to not handle any IRQs.
  • I only tested one version of GCC: (Debian 4.3.2-1.1) 4.3.2
  • I could have taken more samples.

You can find more testing harness tidbits below the conclusion.

Benchmark Results

test 1 — Code sequence simulating using the frame pointer.
test 2 — Code sequence simulating using the frame pointer as a general purpose register.

64bit results

Using -fomit-frame-pointer is SLOWER (contrary to what you’d expect) than not using it!

cycles test 1 cycles test 2 microsecs test 1 microsecs test 2
mean 3514422987.92 4559685515.66 1882707.27 2442663.94
median 3507007423.5 4562511684.5 1878721.5 2444171.5
max 3922780211 4672066854 2101457 2502869
min 3502194976 4327782795 1876113 2318452
std dev 31927179.5632 15449507.8196 17103.7755 8275.49788
variance 1.02E+15 238687291867021 292539135.936 68483865.11835


32bit results

Using -fomit-frame-pointer is FASTER (as it should be) than not using it! The binary is still fatter, though.

cycles test 1 cycles test 2 microsecs test 1 microsecs test 2
mean 3502932799.49 3491263364.89 1876553.08 1870301.35
median 3501486586.5 3492013955.5 1875778 1870702.5
max 3905163528 3731985243 2092032 1999259
min 3500916510 3408834436 1875472 1826144
std dev 10066939.1113 7992367.6913 5393.0412 4281.5466
variance 101343263071403 63877941312996.4 29084893.2588 18331640.9459


Conclusion

  • GCC is a really complex piece of software; this bug is very subtle and may have existed for a while.
  • I’ve said this a few times, but knowing and understanding your system’s ABI is crucial for catching bugs like these.
  • Math and science are cool now, much like computers. You should use both.

Thanks for reading and don’t forget to subscribe (via RSS or e-mail) and follow me on twitter.

Testing harness tidbits

Each run of the benchmark executes either test1 or test2 (from above) 500,000,000 times. I did around 2500 runs for each test function.

You can get the testing harness, a build script, and a test script here: http://gist.github.com/483524

You can look at the terminal session where I build the test from the original bug report on my system: http://gist.github.com/483494

The code I used to read the CPU cycle counter looks like this:

static __inline__ unsigned long long rdtsc(void)
{
  unsigned long hi = 0, lo = 0;
  __asm__ __volatile__ ("lfence\n\trdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

The lfence instruction is a serializing instruction that ensures that all load instructions which were issued before the lfence instruction have been executed before proceeding. I did this to make sure that the cycle counter was being read after all operations in the test functions were executed.

The values returned by this function are misleading because CPU frequency may be scaled at any time. This is why I also measured wall clock time.

References

  1. http://www.sco.com/developers/devspecs/abi386-4.pdf
  2. http://www.x86-64.org/documentation/abi.pdf


more »

Engine Yard AppCloud CLI »

Created at: 20.07.2010 12:00, source: Engine Yard Blog, tagged: Uncategorized

At Engine Yard we've been helping developers ship Ruby applications for almost four years. Our approach to deployment has changed a few times but at its core our focus has always been helping people deploy and scale Ruby on Rails applications on virtualized hardware. Almost two years ago, we started experimenting with Amazon's AWS service and realized that people wanted more of a self service setup. For the first time, we decided to take a stab at providing the same kind of service on other people's hardware instead of our own. This has grown into our AppCloud offering. Today, we're happy to announce an awesome new addition to AppCloud that enables developers to ship code faster, easier, and straight from the command line.

A Bit of EY History

In our early days, we provided our customers with customized capistrano recipes to deploy their ruby applications to our clusters. A problem quickly arose because we also needed to help them maintain this recipe as we helped them scale their applications. We learned that keeping our customers' capistrano recipes up to date was a truly painful exercise, so when we built AppCloud we went with a more centralized approach.

Early AppCloud Direction

We thought that solving the problem of keeping most of the deployment related information in sync was so painful that we built a web based deployment strategy. It wasn't the worst idea ever, but the disconnect between leaving your shell and going to a web browser isn't really what developers want. In addition, we were so excited about the idempotency that chef offered at a configuration level that we felt it was imperative to "verify" the state of the system with a chef run each time we shipped code. This made pushing code slower than necessary and occasionally created panic situations if the chef run failed for some strange reason. People could still use capistrano with AppCloud, but it required them to re-download their deployment recipes every time their environment changed. There also wasn't an easy way to maintain customizations if customers kept having to re-download the capistrano recipe. Over and over again, we kept hearing the same complaints from customers. Customers liked the provisioning flexibility on AWS but shipping code on AppCloud was suboptimal. A few months ago, we finally admitted that our intentions were correct but we hadn't been doing the best things for our customers. We started working on a way to help our customers ship code more effectively.

Customer Feedback is Awesome

We accepted that idempotency is extremely important when it comes to system configuration but that doesn't mean you need to re-run chef each time you ship application code. We realized that people want to see their code running on their servers ASAP. Finally, we embraced the idea that people want to ship code with a command line tool similar to the way most people use rake to run their test suite. We're happy to introduce a more pleasant way to ship code to AppCloud, the engineyard gem.

A Better Workflow

The old way of deploying with chef works, but it forces you to reconfigure your servers every single time you deploy. The workflow looked like this: * Boot some instances (provision, configure, deploy) * Ship code (run configuration, deploy code) * Ship code (run configuration, deploy code) * Ship code (run configuration, deploy code) * Tweak system configuration (configure) * Ship code (configure, deploy) * Ship code (configure, deploy) * ... With the Engine Yard CLI, you can deploy without verifying your system's configuration, so it's quite a bit faster to ship new code. The new workflow looks like this: * Boot some instances (provision, configure) * Ship code (deploy) * Ship code (deploy) * Ship code (deploy) * Tweak system configuration (configure) * Ship code (deploy) * Ship code (deploy) * ... We really think our customers are going to prefer this approach because, let's face it, we ship code way more often than we reconfigure systems.

Get Started

* gem install engineyard * cd ~/myapp * ey deploy One of the things we like most about the new CLI is that it shows you, in real time, what's going on with your deploy. If something goes wrong, you don't have to scroll through a huge log in your browser; the error messages are right there in your terminal. When it succeeds, the process exits, so you know immediately that it's done. No more staring at the dashboard waiting for a spinning dot to turn into a green one. How about ey deploy && mpg123 woohoo.mp3 || mpg123 sad-trombone.mp3? That's immediate, unmistakable, annoying, audible feedback. You can't get that from a green dot.

Other Great Features

* Full Bundler Support * Maintenance Pages * Deploy Hooks for Extra Configuration * Advanced Deployment Customization * Ensure System Configuration is Current You can do a lot more than just deploy with the engineyard gem. Check out the docs and the FAQ. Go forth and ship! ship it squirrel


more »

The 2010 Ruby Implementation Performance Shootout »

Created at: 20.07.2010 04:28, source: Ruby Inside, tagged: Miscellaneous

Hot on the heels of his Windows Ruby implementation shootout comes Antonio Cangiano's Great Ruby Shootout of July 2010 where Antonio pits 8 different Ruby implementations against each other in a performance shootout!

Antonio's findings and observations are interesting and well worth a read (particularly the parts about memory consumption) but if you're in a hurry, the conclusion is that Ruby 1.9.2 RC2 and JRuby 1.5.1 are almost joint first place for fastest Ruby implementation (but 1.9.2 takes it by a hair.) Ruby 1.9.1 and Maglev are then very close behind.


more »

NoSQL, Heroku, and You »

Created at: 20.07.2010 03:42, source: Heroku

Why NoSQL Matters

“NoSQL” is a label which encompasses a wave of innovation now happening in the database space. The NoSQL movement has sparked a whirlwind of discussion, debate, and excitement in the technical community. Why is NoSQL generating so much buzz? What does it mean for you, the application developer? And what place does NoSQL have for apps running on the Heroku platform?

SQL (the language) and SQL RDBMS implementations (MySQL, PostgreSQL, Oracle, etc) have been the one-size-fits-all solution for data persistence and retrieval for decades. The rise of the web and the LAMP stack cemented the role of the relational database. But in 2010 we see a variety of application needs which are not satisfied by MySQL and friends. New problems demand new tools. High availability, horizontal scaling, replication, schemaless design, and map/reduce capability are some of the areas being explored by a new crop of datastores, all of which are loosely categorized as NoSQL.

Heroku Add-ons

To understand why NoSQL is important to you as an app developer, let’s consider the use cases for some of these features:

  • Frequently-written, rarely read statistical data (for example, a web hit counter) should use an in-memory key/value store like Redis, or an update-in-place document store like MongoDB.
  • Big Data (like weather stats or business analytics) will work best in a freeform, distributed db system like Hadoop.
  • Binary assets (such as MP3s and PDFs) find a good home in a datastore that can serve directly to the user’s browser, like Amazon S3.
  • Transient data (like web sessions, locks, or short-term stats) should be kept in a transient datastore like Memcache. (Traditionally we haven’t grouped memcached into the database family, but NoSQL has broadened our thinking on this subject.)
  • If you need to be able to replicate your data set to multiple locations (such as syncing a music database between a web app and a mobile device), you’ll want the replication features of CouchDB.
  • High availability apps, where minimizing downtime is critical, will find great utility in the automatically clustered, redundant setup of datastores like Casandra and Riak.

Despite all the use cases described above, there will always be a place for the highly normalized, transactional, ad-hoc-query capabilities of SQL databases. We’re adding new tools to our toolbox, not removing old ones.

Polyglot Persistence – or, How Do You Pick a NoSQL Datastore?

Part of the NoSQL message is: pick the right tool for the job. The use cases outlined above should help guide your choice of datastore, as will many resources around the web like this diagram, these slides, or this video. And, like any technology, you should pick something that feels right for you and your team.

But most apps encompass multiple use cases. How do you pick one database to handle all the types of data your app needs to deal with? NoSQL answers: you don’t have to pick just one. This concept is called polyglot persistence (more details).

Heroku App

For example, we can imagine a web app which uses four different datastores:

  • MySQL for low-volume, high-value data like user profiles and billing information
  • MongoDB for high-volume, low-value data like hit counts and logs
  • Amazon S3 for user-uploaded assets like photos and documents
  • Memcached for temporary counters and rendered HTML

Polyglot persistence also makes it easy to dip your toes into NoSQL. Don’t migrate your existing production data – instead, use one of these new datastores as a supplementary tool. (Example: put non-critical session data or stats into Redis or Tokyo Tyrant.) And if you’re starting on a new app, you should give serious consideration to NoSQL options for your primary datastore, in addition to the venerable SQL choices.

NoSQL and the Cloud

The SQL databases we’re using today were designed over a decade ago. They were written with the constraints of 1990s hardware in mind: storage is cheap, memory and cpu are expensive. Today’s machines have different parameters. Memory and CPU are cheap, and can easily be scaled up on demand without capital expenditure using a service like Amazon EC2. But EC2, like all cloud technology, is based on virtualization. Virtualization’s weakness is I/O performance. So, the constraints of disk and memory have swapped: disk is the weak link in the chain, memory and cpu (spread out horizontally) are the strong links. It’s not surprising, then, that the datastores built a decade ago aren’t a good fit for the new parameters of cloud computing.

NoSQL databases tend to use memory over disk as the first-class write location: Redis and Memcached are in-memory only, and even systems like Casandra use memtables for writes with asynchronous flushing to disk, preventing inconsistent I/O performance from creating write speed bottlenecks. And since NoSQL datastores typically emphasize horizontal scalability via partitioning, this puts them in an excellent position to take advantage of the elastic provisioning capability of cloud. NoSQL and cloud are a natural fit.

Database-as-a-Service is the Future

Infrastructure-as-a-service like Amazon EC2 and Rackspace Cloud are what most of us think of as “cloud.” One of the effects of these large public clouds is that apps now have extremely low latency between themselves and other apps or service providers – 1ms or less compared to 50ms+ on the open internet. This latency difference opens up vast new possibilities for what a 3rd party service provider can offer.

Database as a service

Database-as-as-service is one of the coming decade’s most promising business models. Already services like MongoHQ (MongoDB), Cloudant (CouchDB), and Amazon RDS (MySQL) are offering fully hosted and managed databases to apps running in EC2. Like IaaS, DaaS promises remove up-front capex costs, and bring efficiency of scale and specialization in the admin and operation of databases. Although these services are still very young, the potential benefit of being able to outsource all the headaches of running and scaling your app’s database are enormous.

DaaS also goes hand-in-glove with polyglot persistence. Thanks to database services, you won’t need to learn how to sysadmin/DBA for every datastore you use – you can instead outsource that job to a service provider specializing in each database. One of the reasons databases have historically had a tribal affiliation (someone is a “MySQL guy” or a “Postgres gal” or an “Oracle guy,” but rarely two or all three) is because of the time investment in learning how to admin whatever database you use. DaaS removes that barrier and opens up even greater possibility for polyglot persistence in production use.

Heroku’s Commitment to Database Innovation

Heroku already supports two of the most popular NoSQL databases, MongoDB and CouchDB, as add-ons: MongoHQ and Cloudant. We also support the transient key-value datastore, Memcache, via Northscale’s service.

Looking forward to the future: we have more NoSQL add-ons coming down the pipeline, such as Redis To Go. And we’ll be continuing to work with technology leaders in the NoSQL community to help them bring their database services to market. Our goal is to provide access to the cornucopia of breakthrough new database technologies from the NoSQL world, available from the Heroku add-ons catalog at the click of a button. We hope to make Heroku a great place to play with these new technologies, while still curating a list of options that are fully baked and ready for use in real production applications.

Of course, we can’t forget that Heroku currently runs the largest and most mature SQL-database-as-a-service in the world: our PostgreSQL service, packaged with every Heroku app. We’re continuing to expand and improve this service (including support for great new features in Postgres 9), because we know SQL and the apps that depend on it are here to stay. Reinforcing our commitment to polyglot persistence, we’ll be turning our Postgres service into a separately packaged add-on – still installed by default into each app, but possible to opt out, or combine with other datastore add-ons. We also hope to see other providers in the SQL-as-a-service space besides Heroku’s Postgres service and Amazon RDS.

It’s an exciting time for data, and our team here at Heroku is thrilled to take part in the continuing growth of the NoSQL movement.


more »

Redmine 1.0 Released: Ruby’s Top Project Management Webapp Hits Maturity »

Created at: 19.07.2010 22:53, source: Ruby Inside, tagged: Miscellaneous

http://redmineblog.com/articles/redmine-1.0.0-released/ (or on Ruby Inside)

It's out, it's out. Redmine 1.0 is released!

The first release candidate for Redmine 1.0 has been released to Rubyforge. This is a major release which includes many new features and bugfixes since the last major release, (0.9 in 2010-01-09).

This is still considered a release candidate (RC) release. The code has been stabilized over the past 6 weeks and we believe it is ready to be tested in production, but there still might be some rough edges. We are using this release to get some for final feedback, both for 1.0.1 (bug fixes) and our next major release 1.1.0.

Eric Davis

I don't understand the odd release candidate vs "1.0 is released" situation, but I've been following Eric's progress for months and he's put a lot of effort into making Redmine - a Ruby and Rails-based project management system used by the Ruby, RubySpec, Puppet and Typo3 projects, amongst others.


more »