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.

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
- Refinery CMS Website
- GitHub Repository
- Official Demo Site
- Refinery CMS Google Group
- Official IRC Channel
Post 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.
more »
A Gentle Introduction to Isolation Levels »
Created at: 21.07.2010 13:16, source: Engine Yard Blog, tagged: Uncategorized
Title | Position ---------------------- The Odyssey | 1 The Iliad | 2 The Nostoi | 3Bob 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 | 3If 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
initto 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
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!
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.

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).

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-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 »

