Vintage 0.0.1 - The super slim, micro web framework based on the idea of the old Merb

Vintage is a very small web framework based on the original idea of
Merb: Mongrel serving up ERb (Embedded Ruby) templates. The idea has
been expanded and now Vintage helps you serve up ERb, HAML, Textile,
Markdown, and Markaby templates. So, basically templates with no MVC
or heavy infrastructure.

To use Vintage, you have two options. You can use it in standard mode
or application mode. In standard mode, there is no configuration and
Vintage will serve up templates and static files from the current
folder. To get this mode, then simply type vintage start in
any folder.

$ vintage start

  • vintage version 0.0.1
    starting server on port 5000

Now navigating to a URL will look in the current folder for the file
or template. For example, going to
http://localhost:5000/my_template will look for
my_template.erb (or whatever template engine you are using)
in the current folder and render it if available. If a static file is
requested, then
it is served up. If you request
http://localhost:5000/my_folder/my_template, then the
application will look in my_folder for the
my_template template.

Vintage can also be configured to be used as an application server.
To do so, you can either generate an application or hand create a
configuration.yml file (see one from a generated project for
an example). To generate an application, simple run +vintage+ with a
project name as the argument.

vintage my_project

This command will generate a number of files. Chief among these is
configuration.yml which tells Vintage how you’d like to run
it. Other files include a sample template and the proper folder
structure for the generated configuration to work properly. This
setup allows you to more easily segment your code for easier
maintenance.

You can also create your own helper methods if you drop a module of
methods (in the Vintage::Helpers module) in the helpers/ folder.
There are a few default helpers included, too.

To give you an idea of how much lighter this is than Rails or Merb,
here are the requests per second according to ab on my box:

Merb: 56 rp/s
Rails: 41 rp/s
Vintage: 534 rp/s

Please enjoy; I’m in the #vintage IRC channel on Freenode or you can
use Trac to submit tickets.

Get it (and submit tickets!) at:

http://vintage.devjavu.com

I’m going to create a website and documentation this week.

Cheers,
Jeremy McAnally


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book
http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

Jeremy McAnally wrote:

To give you an idea of how much lighter this is than Rails or Merb,
here are the requests per second according to ab on my box:

Merb: 56 rp/s
Rails: 41 rp/s
Vintage: 534 rp/s

How does it compare to Nitro or Ramaze (neither or which requires you to
follow MVC)?


James B.

www.ruby-doc.org - Ruby Help & Documentation
www.risingtidesoftware.com - Wicked Cool Coding
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.jamesbritt.com - Playing with Better Toys

It’s much simpler than Nitro. It doesn’t offer MVC at all, doesn’t
have an ORM built in, doesn’t have as large a library of helpers, and
so on. It’s much faster though (I couldn’t get good numbers from ab
for Nitro for some reason but from what I could get it’s about 10x
faster).

It’s also much simpler than Ramaze. It doesn’t offer MVC, is about 5x
faster, doesn’t offer as many templating options (yet), doesn’t offer
caching, etc.

The concentration here is similar to what PHP should be used for:
template centric development. I’ll eventually add things like
layouts, caching, cookies, sessions, etc, but I’m not going to go to a
“full fledged” MVC-optional, super framework like these guys. Simple
and speedy is good!

Basically, I’ve always liked the original idea of Merb so I thought I
would resurrect it. :slight_smile:

–Jeremy

On Jan 5, 2008 12:20 PM, James B. [email protected] wrote:

follow MVC)?


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book
http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

Yeah I considered making MVC available but I think I’m going to stick
to the form it’s in now. There are a lot of MVC frameworks that do
their thing much better than I could. :slight_smile:

–Jeremy

On Jan 5, 2008 2:22 PM, James B. [email protected] wrote:

Interesting; what attracted me to Nitro and Ramaze is that you can, if
James B.

http://www.rubyaz.org - Hacking in the Desert
http://www.jamesbritt.com - Playing with Better Toys


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book
http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

Just a quick update:

I ported the Mongrel handler to Rack tonight and only sacrificed about
10 rp/s. It stands up quite well under heavy load apparently (~425
rp/s on ab -c 100 -n 10000), but I still want to see how much
performance I can squeeze out before I implement more features.

I’m anxious to see some numbers with Thin or Evented Mongrel with this
new adapter. :slight_smile:

I’ll be releasing a new gem in a few days when I can get all the HTTP
stuff implemented (cookies and sessions).

–Jeremy

On Jan 5, 2008 11:20 AM, Jeremy McAnally [email protected]
wrote:

any folder.
requested, then

methods (in the Vintage::Helpers module) in the helpers/ folder.
use Trac to submit tickets.

http://www.mrneighborly.com/
http://www.rubyinpractice.com/


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book
http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

On Jan 5, 2008, at 9:20 AM, Jeremy McAnally wrote:

Merb: 56 rp/s
Rails: 41 rp/s
Vintage: 534 rp/s

this doesn’t smell right. on even a modest box i would expect merb
and rails, with sessions turned off and no db query, to server
somewhere in the hundreds of rps. on my box both rails and merb
would do at least 4-500 rps. conversely, a simple fastcgi process
running under mod_fcgid expanding a simple template might churn out
something like 2000 rps.

are you positive you were running in production mode for rails/merb
with both not using sessions and on top of mongrel? if so it’s very
impressive, but those number just look like development mode with
sessions and no cookie argument to ‘ab’ to me…

on another note vintage looks like a really cool idea - people,
myself included, are yearning for something really simple.

cheers.

a @ http://codeforpeople.com/

No I didn’t run those in production, but that’s mostly because Vintage
reloads templates every time (i.e., no caching and such like
production modes on both of those). I didn’t think about sessions, so
I should turn those off. These numbers were for the same
functionality among all the frameworks.

I’m working on some better numbers using production modes, evented
Mongrels, Thin, and so on. I’ll post them here (hopefully) tonight
when I can get the data collected. :slight_smile:

–Jeremy

On Jan 6, 2008 11:18 AM, ara.t.howard [email protected] wrote:

would do at least 4-500 rps. conversely, a simple fastcgi process


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book
http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

On Jan 6, 2008, at 9:24 AM, Jeremy McAnally wrote:

No I didn’t run those in production, but that’s mostly because Vintage
reloads templates every time (i.e., no caching and such like
production modes on both of those). I didn’t think about sessions, so
I should turn those off. These numbers were for the same
functionality among all the frameworks.

i can see you line of thinking, still, rails and merb both are
loading a TON of more crap and doing a TON more tests if mode!
=production, so it’s probably worthwhile to either test those in
production or implement caching - which is pretty easy (un-tested):

class Template
Cache = Hash.new
Development = ENV[‘development’]

if Development
def self.read path
IO.read(path)
end
else
def self.read path
Cache[path] ||= IO.read(path)
end
end
end

not that this would work for anything but testing - but that it does…

I’m working on some better numbers using production modes, evented
Mongrels, Thin, and so on. I’ll post them here (hopefully) tonight
when I can get the data collected. :slight_smile:

cool. the reason i asked the question is that after doing some
careful benchmarks myself i’ve come to the conclusion that the only
way to get more than a modest speedup out of a ruby web framework,
when compared to rails, is to rework things like cgi parsing in C
(which is done and released as a library) rather than tweak the ruby
bits and framework code. it’s true that one could expect a speedup
of 2x or something but, for me, i’d need to see a speedup of around
and order of magnitude or something to make a switch worthwhile and
my hunch is that - once the code for a ‘real’ app like sessions, db
connection, etc are thrown in - all ruby frameworks will be very
closely matched to rails, which has seen heavy optimization in many
of it’s billions of lines of code. note that i’m really hoping to be
proven wrong - but that’s my gut feeling at the moment. i’ll follow
vintage with great interest.

kind regards.

a @ http://codeforpeople.com/

Right. The point was to show how much lighter it was rather then
how much faster. :slight_smile: It’s faster because it does less but does 99% of
what’s needed for a lot of use cases.

Honestly, I wasn’t thinking about their modes and all that when I did
my initial speed tests, so hopefully these new numbers will look more
normal.

–Jeremy

On Jan 6, 2008 12:13 PM, ara.t.howard [email protected] wrote:

loading a TON of more crap and doing a TON more tests if mode!
end

I’m working on some better numbers using production modes, evented
of 2x or something but, for me, i’d need to see a speedup of around
a @ http://codeforpeople.com/

share your knowledge. it’s a way to achieve immortality.

h.h. the 14th dalai lama


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book
http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/

Jeremy McAnally wrote:

The concentration here is similar to what PHP should be used for:
template centric development. I’ll eventually add things like
layouts, caching, cookies, sessions, etc, but I’m not going to go to a
“full fledged” MVC-optional, super framework like these guys. Simple
and speedy is good!

Interesting; what attracted me to Nitro and Ramaze is that you can, if
you like, write apps in a PHP-like style (all one file, or a main logic
file and some templates), and that MVC was completely optional.

(I think Nitro was the only Web framework that allowed for a Hello,
World one-liner example you could type and execute right from the
command line.)


James B.

http://www.rubyaz.org - Hacking in the Desert
http://www.jamesbritt.com - Playing with Better Toys

On Jan 6, 2008 12:13 PM, ara.t.howard [email protected] wrote:

connection, etc are thrown in - all ruby frameworks will be very
closely matched to rails, which has seen heavy optimization in many
of it’s billions of lines of code. note that i’m really hoping to be
proven wrong - but that’s my gut feeling at the moment. i’ll follow
vintage with great interest.

Speaking only to the point about optimizations in C: there is a
lightweight
HTTP server built into EventMachine, and it does all the HTTP parameter
parsing in C. Simply populating a CGI-like hash in Ruby when it crosses
over
into the framework (whichever one you use) is the performance killer.
(Populating the environment so as to use cgi.rb performs so poorly that
it’s
not even a consideration.)

Rather than populate all the parameters, I provided an alternative that
simply lets the framework access the parameters it will actually use.
This
greatly improves performance. The downside is having to use a somewhat
different API to get at the HTTP parameters.

On Jan 6, 2008, at 12:41 PM, Francis C. wrote:

Rather than populate all the parameters, I provided an alternative
that
simply lets the framework access the parameters it will actually
use. This
greatly improves performance. The downside is having to use a somewhat
different API to get at the HTTP parameters.

yeah - agreed on all parts. however, would a real difference in api
really be needed? couldn’t something like

Params = Hash.new{|key, value| lazy_get key, value}

gloss over that?

i’m really interested in this - doc or example code somewhere?

kind regards.

a @ http://codeforpeople.com/

On Mon, 7 Jan 2008, Francis C. wrote:

Yeah, there’s a gem on the Rubyforge EM page: eventmachine_httpserver. Also
Kirk uses it in Swiftiply as a faster alternative to Mongrel.

If you search through the EM mailing-list archive or Google groups page,
you’ll also find a distro of “Unicycle,” which is a RESTful web framework
based on the same HTTP server.

To clarify, I experimented with using it directly in Swiftiply, but went
back to the absolute minimalist HTTP parsing in Swiftiply because I
really
don’t want to parse out more than the absolute minimum that I need to.

However, that experiment resulted in a bunch of optimizations to the
http
server that have become part of what I am working on with Wisteria
(http://wisteria.swiftcore.org), and that I will commit back to the
original sources.

I haven’t released yet because I am still experimenting with a couple
alternatives for the parsing, one of which is a lazy get kind of like
you
describe.

Thin kind of gave me a kick in the butt, though, so a release will be
forthcoming soon.

Kirk H.

Before Jeremy even had a chance to port Vintage to Rack I swiped the
evented mongrel hooks from merb and ran some very rough numbers on my
aging MacBook Pro (Core Duo, 2.16).

Each set is an ab run of 1000 hits @ 1, 10, and 100 concurrency. No
other ab flags were used. I only did one pass, so the numbers are not
properly averaged. (Not to mention I ran was ab and merb/vintage on
the same dual core machine.)

merb/ab.mutex.mongrel:Requests per second: 421.94 [#/sec] (mean)
merb/ab.mutex.mongrel:Requests per second: 378.36 [#/sec] (mean)
merb/ab.mutex.mongrel:Requests per second: 284.33 [#/sec] (mean)

merb/ab.mutex.evented:Requests per second: 444.44 [#/sec] (mean)
merb/ab.mutex.evented:Requests per second: 466.85 [#/sec] (mean)
merb/ab.mutex.evented:Requests per second: 490.68 [#/sec] (mean)

merb/ab.no-mutex.mongrel:Requests per second: 420.70 [#/sec] (mean)
merb/ab.no-mutex.mongrel:Requests per second: 378.93 [#/sec] (mean)
merb/ab.no-mutex.mongrel:Requests per second: 290.28 [#/sec] (mean)

merb/ab.no-mutex.evented:Requests per second: 447.23 [#/sec] (mean)
merb/ab.no-mutex.evented:Requests per second: 459.56 [#/sec] (mean)
merb/ab.no-mutex.evented:Requests per second: 478.01 [#/sec] (mean)

vintage/ab.erb.mongrel:Requests per second: 981.35 [#/sec] (mean)
vintage/ab.erb.mongrel:Requests per second: 650.20 [#/sec] (mean)
vintage/ab.erb.mongrel:Requests per second: 406.17 [#/sec] (mean)

vintage/ab.erb.evented:Requests per second: 1250.00 [#/sec] (mean)
vintage/ab.erb.evented:Requests per second: 1338.69 [#/sec] (mean)
vintage/ab.erb.evented:Requests per second: 1288.66 [#/sec] (mean)

This is for a fresh Merb-0.4.2 project with an Erb template of…
“Hello World!”. Same for Vintage. I was intrigued that disabling the
mutex in Merb (an undocumented feature) actually made stock mongrel
performance poorer. Merb was run in production mode, Vintage has no
similar setting.

Corey

On Jan 6, 2008 2:58 PM, ara.t.howard [email protected] wrote:

Yeah, there’s a gem on the Rubyforge EM page: eventmachine_httpserver.
Also
Kirk uses it in Swiftiply as a faster alternative to Mongrel.

If you search through the EM mailing-list archive or Google groups page,
you’ll also find a distro of “Unicycle,” which is a RESTful web
framework
based on the same HTTP server.

On Jan 6, 2008, at 9:46 PM, Corey J. wrote:

No other ab flags were used.

unless you have session turned off you have to use the cookie and
cookie-jar options (or perhaps that’s curl, i forget…)

or was this without sessions?

cheers.

a @ http://codeforpeople.com/

Jeremy McAnally wrote:

Yeah I considered making MVC available but I think I’m going to stick
to the form it’s in now. There are a lot of MVC frameworks that do
their thing much better than I could. :slight_smile:

It looks quite slick, and I’ll be poking around with it some more.

Thanks,


James B.

“A principle or axiom is of no value without the rules for applying it.”

  • Len Bullard

On Jan 6, 2008, at 8:46 PM, Corey J. wrote:

merb/ab.mutex.mongrel:Requests per second: 378.36 [#/sec] (mean)
merb/ab.no-mutex.evented:Requests per second: 447.23 [#/sec] (mean)

This is for a fresh Merb-0.4.2 project with an Erb template of…
“Hello World!”. Same for Vintage. I was intrigued that disabling the
mutex in Merb (an undocumented feature) actually made stock mongrel
performance poorer. Merb was run in production mode, Vintage has no
similar setting.

Corey

I think you made the classic mistake of comparing a merb template
rendered inside of a layout rather than a standalone template like you
are testing with vintage. Here are my numbers for the same template
with no layout in merb and vintage, Also note that this goes through
merbs router and instantiates a full controlller object which vintage
does not.

Merb evented mongrel:

ab -n 1000 -c 1 Requests per second: 911.04 [#/sec] (mean)
ab -n 1000 -c 10 Requests per second: 1073.71 [#/sec] (mean)
ab -n 1000 0c 100 Requests per second: 1232.75 [#/sec] (mean)

Vintage evented mongrel:

ab -n 1000 -c 1 Requests per second: 1103.15 [#/sec] (mean)
ab -n 1000 -c 10 Requests per second: 1232.75 [#/sec] (mean)
ab -n 1000 0c 100 Requests per second: 1309.67 [#/sec] (mean)

Clearly a bit faster but not as much as indicated when compared in a
fair test.

Cheers-

On Jan 7, 2008, at 00:24 , Ezra Z. wrote:

ab -n 1000 -c 10 Requests per second: 1073.71 [#/sec] (mean)
a fair test.
Thanks, still kicking merb’s hubcaps.

Corey

On Jan 6, 2008, at 21:39 , ara.t.howard wrote:

On Jan 6, 2008, at 9:46 PM, Corey J. wrote:

No other ab flags were used.

unless you have session turned off you have to use the cookie and
cookie-jar options (or perhaps that’s curl, i forget…)

or was this without sessions?

Sessions appear to be off by default in merb. Vintage doesn’t have
sessions yet.

curl -D - -o /dev/null http://localhost:4000/erb
HTTP/1.1 200 OK
Connection: close
Date: Mon, 07 Jan 2008 08:12:08 GMT
Content-Type: text/html
Content-Length: 436

% Total % Received % Xferd Average Speed Time Time
Time Current
Dload Upload Total Spent
Left Speed
100 436 100 436 0 0 114k 0 --:–:-- --:–:--
–:--:-- 0

Corey

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs