Guillermo Iguaran edited this page Mar 20, 2014 · 55 revisions

Google Summer of Code 2014

This page hosts the ideas for Google Summer of Code 2014! Add your ideas here, improve others, and if you're a student, perhaps something on this list will interest you!

You can discuss the ideas posted here or new ideas with others in our mailing list

Here's some ideas to get you started:

Unify controller and integration tests

One of the most common misunderstandings amongst new Ruby on Rails developers is the difference between controller/functional tests and integration tests. Functional tests are like unit tests for controllers and don't generate a proper request - they merely mock the request based upon the test arguments. This means that features implemented as Rack middleware generally don't work in functional tests leading to lots of mistaken bug reports.

To ease this confusion it'd be helpful to make functional tests behave like integration tests but to do this would require performance improvements to the integration test code as they are approximately 25% slower than functional tests. After of complete this the functional tests will be deprecated in favor of the integration tests.

Mentors: Pending
Skills: Ruby, Test::Unit/MiniTest and some experience with developing RoR applications.

Refactor Ruby on Rails URL generation and recognition

Ruby on Rails 3.0 introduced a new DSL for defining application routes and as part of that the URL recognition and generation was split off into a separate gem called Rack::Mount with the intention of it being a generic router for Rack-based applications. This never really took off and as part of the 3.2 upgrade Ruby on Rails switched to a new router called Journey which has been re-integrated into the Action Pack framework as part of the upcoming 4.0 release.

As a result of this process there are a lot of abstractions and inefficiencies which can be eliminated now there's no need to maintain generic API for Rack applications. Some specific examples are:

  • The Routing DSL needs to know what keys are in the path so it can build the defaults and requirements hashes used to add a route. It does this by parsing the path but this path is then parsed again when the route is added.

  • The route class doesn't know about controllers and actions so the Routing DSL must normalize all these as part of the process of adding a route. It would be sensible to make the route class more aware of the routing conventions so that a lot of the normalization code can be simplified.

  • Because of the need for a simple API for Rack::Mount the router doesn't know whether a route represents a resource or not. This is useful information which could be used to fix long-standing problems like generating polymorphic urls with singular resources.

  • The internal implementation of the Routing DSL uses an hash to maintain the current scope whilst evaluating the routes.rb file - this makes the DSL code hard to maintain and test. If it's refactored so that classes represent the different types of scope it would simplify the implementation and make it easier to test.

This would be a good project for a student wanting to learn about re-factoring a large, complicated codebase whilst maintaining backward compatibility.

Mentors: Andrew White
Skills: Ruby, HTTP protocols, Web servers and some experience with developing RoR applications.

Rails Performance under JRuby

Over the years, JRuby has gotten better and better at running Rails, but there remains work to do. This project would involve gathering existing benchmarks and "standard" applications (Redmine, etc) and using them to find remaining perf issues in JRuby. Some possible areas that could use improvement:

  • ActiveRecord-JDBC, the library that JRuby uses to wrap JDBC with ActiveRecord's ORM API. We have done various performance investigations over the years, but a concentrated effort to make it consistently faster across databases has never really been attempted.

  • ActiveRecord-Basin, a new approach to connection pooling for Rails with special care for JRuby. AR's built-in pool is great with MRI, but on JRuby from time-to-time it stands in the way of high performance "native" pools (e.g. with JNDI configurations). Would be interesting to experiment with the possibility of avoiding pooling on AR's side and/or building a specialized pool (using some of the great Java ones) for JRuby.

  • JRuby-Rack and other servers. A JRuby on Rails app can only serve requests quickly if the server frontend is fast. There's always more that we can do to improve the speed of these requests, in jruby-rack (used for serving JRuby in existing Java app servers like Tomcat) or in purpose-built servers like Torquebox (JRuby for JBoss), Puma, Passenger, and others.

  • Data format libraries like json and yaml. More and more users of Rails are building JSON-based RESTful APIs atop it, and again the performance of one library (json) can be the limiting factor.

  • Templating libraries like Haml. In order to render results quickly to the browser, these libraries need to be fast. Haml in particular employs a number of Ruby code patterns that can severely impact performance. We need to investigate the performance of all these libraries and ensure that we run them as fast as possible.

  • Other libraries commonly used in Rails apps, such as for accessing caching servers like memcached, nosql databases like mongo, and queues like zeromq.

  • One potential target would be improving the standing of the various Rails permutations on the TechEmpower Framework Benchmarks, both for C Ruby and JRuby. This would likely mean concentrating on the performance of Rails itself and the handful of libraries used in those tests, versus concentrating on specific JRuby servers that can already run basic Rack applications drastically faster than Rails applications.

Mentors: Karol Bucek, Guillermo Iguaran, Ben Browning
Skills: Ruby, HTTP protocols, Java, Servlets API, Java WebServers and some experience with developing RoR applications.

Make the Rails test suite run in a random order

Currently our test suite has to be run in the order in which it is defined. This is primarily due to global configuration changes that are being persisted from one test to another. We'd like to run our tests in a random order as this helps identify obscure bugs so important project for us is to fix the global state modification in the problem tests. Our goals are:

  • Make our tests more robust. Order dependent tests tend to fail randomly and are hard to debug. This is a time sink. Have a look at our CI Server to see such "random" failures.
  • Lay the foundation for application level tests to run in random order. ActiveSupport::TestCase is currently enforcing a fixed order. As this is the Base class for all application level tests, these also have to run in order.

There are two distinct cases to address:

  1. Independence within a single test case. This means you can run the test_XX methods of a single test case in any order. This is controlled by a flag in ActiveSupport::TestCase
  2. Independence of test cases. This means you can run the test cases in any order. Currently our rake tasks run them in alphabetical order.

Whilst not as glamorous as working on something like Active Record our test suite is vitally important to our ability to deliver high quality releases with as few regressions as possible.

Mentors: Yves Senn
Skills: Ruby, Test::Unit/MiniTest and some experience with developing RoR applications.

Improve the error page and integrate the web console

Rails has always provided helpful error pages but we feel that we can do even better than we do at the moment by providing an interactive page along the lines of Better Errors, building upon the web console work from the GSoC 2013 program. Some of the features we'd like to see are:

  • Full stack trace
  • Source code inspection
  • Local and instance variable inspection
  • Live REPL support (via the web console)

Adding this will make all Rails developers lives better.

Mentors: Guillermo Iguaran, Genadi Samokovarov
Skills: Ruby, HTTP protocols, HTML, JavaScript and some experience with developing RoR applications.

International data input

Rails has provided strong i18n support for a number of years but this is currently only one way. For example, in half the world numbers are display using a comma instead of a decimal point (1,99 instead of 1.99). This is easy to output using our existing i18n support but when we take in user input the data still has to be entered in the standard form with a decimal point. We'd like to reduce the confusion for users by allowing the input of i18n-formatted data.

Mentors: Carlos Antonio
Skills: Ruby, HTML, and some experience with developing RoR applications with I18n.

Improve Security Defaults

Rails needs to level up its security defaults, We would like to add support for HSTS (HTTP Strict Transport Security), CSP (Content Security Policy) headers, etc. Some ideas introduced in the Twitter SecureHeaders gem can be used as starting point for this. This talk from RailsConf last year contains some interesting ideas as well.

Additionally we want to introduce a PerishableMessageVerifier. Whenever you generate a signed message, very often you'd want to make sure you can expire that to avoid replay attacks. For example, if you use the application verifier to generate a password-reset token, and you just put the user_id inside the message, then if an attacker captures that message, he can reuse it to reset passwords for the same user in the future. Making the message perishable after a short time (e.g. 1 day) would help limit the scope of such attacks.

Expiring signed cookie jars can be built on top of the PerishableMessageVerifier. These seems to be more challenges around how to hook things up correctly for cookies, and upgrade path concerns, etc. The josh's pull request can be used as starting point for this.

Mentors: Godfrey Chan, Rafael França
Skills: Ruby, HTTP protocols, basic cryptography and some experience with developing RoR applications.

## Add Form Models

Currently, we have the fields_for helper and accepts_nested_attributes_for to help creating complex objects and nested objects with HTML forms. This design tightly couples view layer concerns with model layer concerns and makes it difficult to support alternative use cases (e.g. alternative ORMs and JSON APIs).

We would like to decouple these APIs by introducing some intermediate layer to replace accepts_nested_attributes_for and fields_for, such as "form models" and push this down to the Active Model layer. The solution would should be backwards compatible with the existing form helpers (e.g. form_for) and third-party gems (e.g. simple_form/formtastic).

Mentors: Carlos Antonio, Guillermo Iguaran
Skills: Ruby, HTML and some experience with developing RoR applications.

Long running Ruby and Rails benchmarks

We would like to have a long running Ruby and Rails set of benchmarks. For a very long time Python has had the pypy speed center and recently golang has added its own go performance dashboard

Writing fast software requires data. We need to know right away when our framework or platform is getting slower or faster. This information can be fed directly to the team informing them of big wins and losses. Often small changes can lead to unexpected gains or losses.

Finding out about regressions months in to the development cycle can often incur a massive cost, fixing bugs early on is cheap. Usually the longer we wait the more expensive it is to fix.

Read the Sam Saffron's blog post about this for more details.

Mentors: Sam Saffron, Arthur Neves, Damien Mathieu, Ben Browning
Skills: Ruby, some experience with developing RoR applications.

ActiveRecord::Schema support for foreign keys and views

Rails has espoused the philosophy of application logic belongs in the application and not the database since its inception but not everyone has the benefit of working with a clean database or they may like the data integrity enforced by foreign keys. It is possible to use views and foreign keys with Rails applications but it means switching away from the schema.rb format to the structure.sql format for storing your database schema. We'd rather that developers weren't forced to make this decision out of necessity and to facilitate this we want to add support for adding/removing foreign keys and views via schema migrations and saving them in schema.rb. Ideally, we'd even want to support triggers but that may be a step too far - unless some enterprising student has a good solution they can propose!

Mentors: Arthur Neves
Skills: Ruby, SQL, some experience with developing RoR applications.