<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>TvE 2100 - Home</title>
  <id>tag:blog.voneicken.com,2007:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://blog.voneicken.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.voneicken.com/" rel="alternate" type="text/html"/>
  <updated>2007-01-21T03:09:36Z</updated>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2007-01-17:130</id>
    <published>2007-01-17T04:44:00Z</published>
    <updated>2007-01-21T03:09:36Z</updated>
    <category term="Ruby on Rails"/>
    <category term="profiling"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://blog.voneicken.com/2007/1/17/ruby-prof-does-not-play-nice-with-threads" rel="alternate" type="text/html"/>
    <title>Ruby-prof does not play nice with threads</title>
<content type="html">
            &lt;p&gt;&#8230; or so it seems! I was trying to profile a worker running in BackgrounDRb and I kept getting errors almost as soon as I&#8217;d call &lt;code&gt;RubyProf.start&lt;/code&gt; looking like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
./script/../vendor/rails/activerecord/lib/../../activesupport/lib/active_support/inflector.rb:108: warning: ruby-prof: An error occured when leaving the method Inflector#singularize.
   Perhaps an exception occured in the code being profiled?
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each time the error would occur in a slightly different place. I finally disabled all but one worker (thread) and that seems to have fixed the problem.&lt;/p&gt;

&lt;p&gt;Update: it seems that it is possible to use ruby-prof with threads, but it looks like one has to start the profiling before forking off the threads.&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-12-26:39</id>
    <published>2006-12-26T07:00:00Z</published>
    <updated>2006-12-26T08:13:51Z</updated>
    <category term="Amazon Web Services"/>
    <category term="Ruby on Rails"/>
    <category term="aws"/>
    <category term="ec2"/>
    <category term="https"/>
    <category term="net::http"/>
    <category term="rails"/>
    <category term="ruby"/>
    <category term="ssl"/>
    <link href="http://blog.voneicken.com/2006/12/26/verifying-ssl-certs-when-using-net-http" rel="alternate" type="text/html"/>
    <title>Verifying SSL certs when using Net:HTTP</title>
<content type="html">
            &lt;p&gt;What good is an HTTPS web service if you're not verifying the certificate presented by the web service? That's what I was wondering when I started to use the Amazon Elastic Compute Cloud web service and used a sample that used simple HTTP. So I looked into the docs and quickly found that the trick is to set &lt;code&gt;http.verify_mode = OpenSSL::SSL::VERIFY_PEER&lt;/code&gt; when creating the https connection object. Unfortunately that turned out not to be so simple, because the only effect I got is an error on every connection attempt telling me that the peer's certificate cannot be validated. Very useful!&lt;/p&gt;

&lt;p&gt;&lt;img src='/assets/2006/12/26/20050930-201352-blog_1.jpg' alt='Black-necked Stilts' /&gt;
&lt;br&gt;&lt;span&gt;Black-necked Stilts, Devereux Slough, Santa Barbara, CA &amp;copy;2005 Thorsten von Eicken&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Of course my next step was a Google search, but after a long time all I found is that everyone turns the verification off! I then proceeded to look at the source code to figure out what is going on, and I finally gave up after a couple of hours. Finally, the Pragmatic Studio alumni mailing list came to the rescue: Devin Mullins gave me the critical tip that made it work: one has to give the certificate file a special name, duuuh. Here is in detail what I did to get it to work:&lt;/p&gt;

&lt;p&gt;I have a file 'cacert.pem' that has all the root certs I care about. I ran the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# openssl x509 -hash &amp;lt; cacert.pem
f73e89fd
-----BEGIN CERTIFICATE-----
MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
-----END CERTIFICATE-----
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The trick is that the file basename must be the hash printed out by the above command plus an appended .0! So my next move was:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mv cacert.pem f73e89fd.0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I then adjusted my code as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  http = Net::HTTP.new(link.host, link.port)
  if link.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.ca_file = &quot;#{RAILS_ROOT}/lib/ec2/f73e89fd.0&quot;
  end
  http.start
  response = http.get(link.request_uri)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This now works like a charm! Phew!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Upon further inspection, it looks like the above only works for the first certificate in my original &lt;code&gt;cacert.pem&lt;/code&gt; file and I was lucky that that's the one I need for EC2. What I need to do to use all the certs in the file is break it up, one cert per file, use openssl to figure out the filenames, and then use &lt;code&gt;http.ca_path&lt;/code&gt; instead of &lt;code&gt;http.ca_file&lt;/code&gt; to point to the directory with all the cert files.&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-12-20:30</id>
    <published>2006-12-20T23:31:00Z</published>
    <updated>2007-01-17T18:18:09Z</updated>
    <category term="Amazon Web Services"/>
    <category term="Ruby on Rails"/>
    <category term="aws"/>
    <category term="ec2"/>
    <category term="rails"/>
    <category term="ruby"/>
    <category term="ucsb"/>
    <link href="http://blog.voneicken.com/2006/12/20/course-on-scalable-internet-services-in-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>Course on Scalable Internet Services (in Ruby on Rails)</title>
<content type="html">
            &lt;p&gt;Phew, I just finished teaching a &lt;a href='http://www.voneicken.com/courses/ucsb-cs290f-fa06'&gt;graduate course on building scalable internet services&lt;/a&gt; at UCSB (Univ. of California At Santa Barbara). This was a very hands-on, learn-by-doing course with a significant project in Ruby on Rails! The goal was for the students to learn about all the technologies that go into a scalable internet service, specifically into dynamic web sites. The lectures provided background information to support the project and they explained technologies beyond the scope of the project.&lt;/p&gt;

&lt;p&gt;&lt;img src='/assets/2006/12/20/20050327-084607-blog_2.jpg' alt='Hummingbirds' /&gt;
&lt;br&gt;&lt;span&gt;Anna&#8217;s Hummingbirds, Joshua Tree, CA, Mar 2005, &amp;copy;2005 Thorsten von Eicken&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The project consisted of building a transactional dynamic web site in Ruby on Rails and running on Amazon&#8217;s Elastic Compute Cloud (EC2). Each site had to hold &gt;100&#8217;000 database records that could be searched and explored, have user accounts, and include some form of transaction, such as a shopping cart check-out.&lt;/p&gt;

&lt;p&gt;Each project then had to be deployed on multiple servers on EC2 and the groups had to use httperf to demonstrate that they could scale the performance of their site by running a front-end load balancer server, a database server, a memcached server, and up to 10 application servers. All this had to fit into a 10-week quarter, with none of the students knowing either Ruby or Rails at the outset!&lt;/p&gt;

&lt;p&gt;Note that the emphasis of the course was on the scalability aspect of the sites and not on the web design or feature-set. Thus it was more important to understand the performance characteristics and optimize the core of the site than to have the most eye-candy. (Although eye-candy is always appreciated, of course&#8230;)&lt;/p&gt;

&lt;p&gt;Please check out the &lt;a href='http://www.voneicken.com/courses/ucsb-cs290f-fa06'&gt;course wiki&lt;/a&gt; for more information, including all course materials!&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-12-03:25</id>
    <published>2006-12-03T08:40:00Z</published>
    <updated>2006-12-03T08:42:24Z</updated>
    <category term="Ruby on Rails"/>
    <category term="java"/>
    <category term="rjb"/>
    <category term="ruby"/>
    <link href="http://blog.voneicken.com/2006/12/3/accessing-inner-java-classes-via-rjb" rel="alternate" type="text/html"/>
    <title>Accessing inner Java classes via Rjb</title>
<content type="html">
            &lt;p&gt;The entry below is copied straight from another blog. I ran into the problem described therein a few minutes ago and found this solution via Google&#8217;s cache. The origin server doesn&#8217;t respond, so who knows, this may be lost as soon as it pops out of the cache, so I am duplicating it here. I also can&#8217;t tell who wrote it, just that it came from &lt;a href='http://doodle.barelylegible.com/blog/?cat=5'&gt;http://doodle.barelylegible.com/blog/?cat=5&lt;/a&gt;. So here we go:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;== RubyJavaBridge is nice ==
    Sunday, February 12th, 2006&lt;/p&gt;
    
    &lt;p&gt;I’ve been playing with the RubyJavaBridge that was talked up at the last Ruby get-together and so far it is indeed very swank.&lt;/p&gt;
    
    &lt;p&gt;I couldn’t resist investigating the issue Les had with accessing static inners and I think I found the syntax. Accessing inner classes (static or not) can look a little wonky but it is doable. Statics are loaded like any other class, but their pathname is ‘OuterClass$StaticInnerClass’. The nonstatic inner classes are a tiny bit trickier. Import like the static, with ‘OuterClass$Inner’; now you have the inner class, but the trick is in instantiating an instance: you must provide an OuterClass instance as the first argument to the constructor (thus revealing a little behind the curtain of java the implicit access an inner has to its outer’s methods and data):&lt;/p&gt;
    
    &lt;p&gt;Outer = Rjb::import(&#8216;Outer&#8217;)&lt;br&gt;
    Inner = Rjb::import(&#8216;Outer$Inner&#8217;)&lt;br&gt;
    StaticInner = Rjb::import(&#8216;Outer$StaticInner&#8217;)&lt;/p&gt;
    
    &lt;p&gt;outer = Outer.new&lt;br&gt;
    inner = Inner.new(outer)&lt;br&gt;
    staticInner = StaticInner.new&lt;/p&gt;
    
    &lt;p&gt;I have full sources and the example output below.&lt;/p&gt;
    
    &lt;p&gt;I have so many ways I want to use this bridge. This is the key I need to access the AS400 from Ruby. Tasty tasty.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;[Sorry, the &#8220;full sources and examples&#8221; are not in the Google cache&#8230;]&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-12-03:23</id>
    <published>2006-12-03T05:48:00Z</published>
    <updated>2006-12-04T01:14:21Z</updated>
    <category term="Ruby on Rails"/>
    <category term="benchmarking"/>
    <category term="ec2"/>
    <category term="httperf"/>
    <category term="profiling"/>
    <category term="rails"/>
    <link href="http://blog.voneicken.com/2006/12/3/optimizing-a-rails-app-part-1" rel="alternate" type="text/html"/>
    <title>Optimizing a Rails application, part 1</title>
<content type="html">
            &lt;p&gt;I&#8217;m working on a really cool Rails application called &lt;a href='https://www.aws-console.com'&gt;AWS-Console&lt;/a&gt; which manages servers on Amazon&#8217;s &lt;a href='http://www.amazon.com/gp/browse.html?node=3435361'&gt;Elastic Compute Cloud&lt;/a&gt;. With the click of a button, we can instantiate new servers which fire up within a couple of minutes. We can even take a svn repository of a Rails app and launch it fully automatically, takes about 10 minutes to come up. Our test uses mephisto: want 10 instances of mephisto running? Clicke here&#8230; &lt;/p&gt;

&lt;p&gt;So I was measuring the performance of the AWS-Console site and it turned out to be abysmal! Like 1 request per second max, running apache+mongrel_cluster on a 2Ghz/2GB box. That was rather disappointing. So I rolled up my sleeves to try and figure out what is going on, and this is the tale of my first Rails performance adventure!&lt;/p&gt;

&lt;p&gt;&lt;img src='/assets/2006/12/2/20040220-070917-blog2.jpg' alt='Sandhill Cranes' /&gt;
&lt;br&gt;&lt;span&gt;Sandhill Cranes, Bosque del Apache, NM, Feb 2004, &amp;copy;2004 Thorsten von Eicken&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;The goal&lt;/h1&gt;

&lt;p&gt;Up to now we&#8217;ve been exclusively focused on functionality and have not cared a bit about performance. But at some point one does have to make sure that performance is in the ballpark. I&#8217;ve read Stefan Kaes&#8217;  excellent &lt;a href='http://railsexpress.de/blog/'&gt;blog&lt;/a&gt; with his many suggestions  on how to improve performance. So I have about 20 things in mind that I could &#8220;fix&#8221; and hope that they improve performance. But I don&#8217;t like working blindly, so I decided to follow the conventional procedure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;benchmark the application to get baseline measurement(s)&lt;/li&gt;
&lt;li&gt;profile the application to figure out where the time is going&lt;/li&gt;
&lt;li&gt;optimize the bottlenecks using Stefan&#8217;s tips or things I figure out on my own&lt;/li&gt;
&lt;li&gt;re-benchmark the application to see whether I actually improved things&lt;/li&gt;
&lt;li&gt;go back to step 1 until satisfied&lt;/li&gt;
&lt;li&gt;learn from what I did so I don&#8217;t have to do it all over for the next app/feature&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I&#8217;m planning to write up the whole story here, this is just the first part. I hope this will be useful to others and I hope it will jog my memory the next time I&#8217;m going through this :-).&lt;/p&gt;

&lt;h1&gt;Part 1: benchmarking&lt;/h1&gt;

&lt;p&gt;For the benchmarking I am using &lt;a href='http://www.hpl.hp.com/research/linux/httperf/'&gt;httperf&lt;/a&gt; which is an excellent program to apply realistic load to a web site. The reason I like httperf is that it decouples request generation from server responses, which means that it can continue opening new concurrent connections to the server no matter how fast the server responds. This is as it happens in real life: users come to the site no matter how slow the server is and only as they browse around they get slowed down by the server&#8217;s response time. The bottom line is that this allows httperf to overload the server and really drive it against the wall. Httperf can also take little scripts of URLs which describe a flow through the site and it will open a connection and then &#8220;walk through&#8221; the URLs one at a time, and if the site has images, it can request the images for a page in a burst. So all-in-all it&#8217;s a good and realistic benchmarking tool.&lt;/p&gt;

&lt;p&gt;The downside of httperf is that the URL scripts are very primitive, and in particular if the site requires authentication, then it&#8217;s tedious to have httperf log in as a different user every time it opens a connection.&lt;/p&gt;

&lt;h2&gt;Creating a workload&lt;/h2&gt;

&lt;p&gt;To get started I downloaded httperf from &lt;a href='http://www.hpl.hp.com/research/linux/httperf/'&gt;HP&#8217;s site&lt;/a&gt; and installed it. I don&#8217;t remember the details, but it seemed pretty straightforward.&lt;/p&gt;

&lt;p&gt;The key to using httperf as described above where it walks through a sequence of URLs is the &#8211;wsesslog workload generator. If you want to play with it, you will need to check out the man page for all the details, but here is what I did. The first thing was to create a file with the workload. My first test of the AWS-console looked as follows:&lt;/p&gt;

&lt;pre&gt;
/
/sessions/new
  /javascripts/prototype.js?1160194386
  /javascripts/effects.js?1160194386
  /javascripts/dragdrop.js?1160194386
  /javascripts/controls.js?1160194386
  /javascripts/application.js?1154539549
  /javascripts/niftycube.js?1160194386
  /stylesheets/yui/reset.css?1157476643
  /stylesheets/yui/fonts.css?1157693397
  /stylesheets/yui/grids.css?1160194386
  /stylesheets/syslitics.css?1162714447
  /stylesheets/niftyCorners.css?1160194386
  /images/loading.gif?1154732591
/favicon.ico
/sessions method=POST contents='email=test@test.com&amp;password=test'
/
/ec2_instances
/ec2_images
/ec2_instances
/ec2_images
/ec2_instances
/ec2_images
/ec2_instances
/ec2_images
&lt;/pre&gt;

&lt;p&gt;This file fetches &#8220;/&#8221;, which redirects to &#8220;/sessions/new&#8221; and which is followed by fetching all the javascripts and stylesheets referenced by the response. Then comes the favicon and that is followed by a POST of the login information. Then it fetches &#8220;/&#8221; because the login redirects there, and then a bunch of fetches of the instances and images pages.&lt;/p&gt;

&lt;p&gt;The way I came up with this list is to start a fresh browser and navigate to the site, and then look at the server log in &lt;code&gt;/var/log/httpd/access_log&lt;/code&gt; (or similar) and grab all the URIs listed there. I had to make-up the contents of the post myself, but it&#8217;s simply a URL-encoded string of the various form fields.&lt;/p&gt;

&lt;p&gt;Note that httperf does handle cookies in a simple but effective manner. At the first request, the site will return a session cookie to httperf which the latter dutifully presents with all subsequent requests. So a site where the user has to login before proceeding actually does work correctly. Nice!&lt;/p&gt;

&lt;p&gt;Then I tested this using httperf with the following command line:&lt;/p&gt;

&lt;pre&gt;
httperf --hog --server test.aws-console.com --wsesslog=1,0,aws-test1 \
--session-cookie -ssl --print-reply
&lt;/pre&gt;

&lt;p&gt;The &#8211;hog option has to do with sockets and is important but not interesting, &#8211;session-cookie enables cookie handling as described above, &#8211;server is the address of the server, &#8211;print-reply prints out all the responses from the server so I can check that the proper pages get returned and not some errors, &#8211;ssl uses https (aws-console is an SSL site), and &#8211;wsesslog references the workload file. The &#8211;wsesslog options signify that httperf should run through the workload file once, and delay 0 seconds between URLs (to simulate user think time, which I&#8217;m not interested in), and aws-test1 is the filename of my workload. Printing out the replies means lots of stuff to scroll through, but it allowed me to check that the login and the other page fetches worked properly.&lt;/p&gt;

&lt;h2&gt;Applying some load&lt;/h2&gt;

&lt;p&gt;Then a quick test running 30 sessions and starting a new session every two seconds:&lt;/p&gt;

&lt;pre&gt;
httperf --hog --server www.aws-console.com --wsesslog=30,0,aws-test1 --session-cookie --rate 0.5
&lt;/pre&gt;

&lt;p&gt;To produce a graph, I would vary &#8211;rate from about 0.1 to 5 (ramp starting a new session from one every 10 seconds up to 5 per second). Good numbers for your app will depend on the performance that you see.&lt;/p&gt;

&lt;p&gt;Well, the result I got was a whopping 1.2 replies per second on average!!! Given that almost half the requests are for static pages (the style sheets and java scripts) which are served blindingly fast by apache, I can only say &#8220;abysmal!&#8221;&lt;/p&gt;

&lt;p&gt;With this poor performance there really isn&#8217;t much point in generating a graph that shows reply rate as load is increased or load vs. response time.&lt;/p&gt;

&lt;p&gt;Something I did is to add more sessions to my description file so that I can exercise different use cases (flows through the site). I though of automatically generating variants of the workload file where I change the login id and perhaps some other post parameters, but I haven&#8217;t implemented that yet.&lt;/p&gt;

&lt;p&gt;Note that httperf has a &#8220;-v&#8221; option which is helpful in seeing progress. One can specify a very large number of sessions in &#8211;wsesslog and then watch httperf print out its requests/sec measurements every 5 seconds and after one to two dozen measurements, hit ctrl-C to get the overall stats.&lt;/p&gt;

&lt;h2&gt;Figuring out where the time is going&lt;/h2&gt;

&lt;p&gt;So, why doesn&#8217;t it do more requests per second than it does? That&#8217;s an excellent question for part2, to appear soon!&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-11-14:17</id>
    <published>2006-11-14T01:19:00Z</published>
    <updated>2007-01-17T18:17:56Z</updated>
    <category term="Amazon Web Services"/>
    <category term="aws"/>
    <category term="ec2"/>
    <category term="tools"/>
    <link href="http://blog.voneicken.com/2006/11/14/installing-a-new-version-of-the-ec2-ami-tools" rel="alternate" type="text/html"/>
    <title>Installing a new version of the EC2 AMI Tools</title>
<content type="html">
            &lt;p&gt;The Amazon Web Services &lt;span class='caps'&gt;EC2&lt;/span&gt; AMi Tools are the set of tools needed to create a new Xen image for Amazon&#8217;s Elastic Compute Cloud.&lt;/p&gt;


	&lt;p&gt;To install a new version, the following commands are recommended:&lt;/p&gt;


&lt;pre&gt;
rpm -q ec2-ami-tools
wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm
rpm -Uvh ec2-ami-tools.noarch.rpm
rpm -q ec2-ami-tools
&lt;/pre&gt;

	&lt;p&gt;That&#8217;s it!&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-09-22:16</id>
    <published>2006-09-22T22:26:00Z</published>
    <updated>2007-01-16T19:22:18Z</updated>
    <category term="Amazon Web Services"/>
    <category term="aws"/>
    <category term="ec2"/>
    <category term="mysql"/>
    <link href="http://blog.voneicken.com/2006/9/22/why-running-mysql-on-amazon-ec2-and-s3-is-not-that-simple" rel="alternate" type="text/html"/>
    <title>Why running mysql on Amazon EC2 and S3 is not that simple</title>
<content type="html">
            &lt;p&gt;Jeff posted a &lt;a href='http://aws.typepad.com/aws/2006/09/amazon_ec2_mysq.html'&gt;blog entry&lt;/a&gt; that implies that it&#8217;s not that difficult to run mysql on Amazon &lt;span class='caps'&gt;EC2&lt;/span&gt;. Ha! Possible : yes. Easy: noooo! The devil is in the details, many of them!&lt;br /&gt;&lt;br /&gt;For example, MyISAM tables do not replicate correctly because the replication (binary) log does not obey transactions. You can have a transaction that rolls back on the master but it&#8217;s in the log and happily executed on the slave. Ouch!&lt;br /&gt;&lt;br /&gt;Even if you use InnoDB tables, you are not safe. For example, you can write non-deterministic &lt;span class='caps'&gt;SQL&lt;/span&gt; statements that may produce different results on the slave than on the master. An example is creating a table with an auto-increment key using a select from another table. The keys assigned depend on the order in which the select produces results. This may be different on the slave than the master and you end up with different keys, which is not going to match subsequent operations! (A friend ran into this one, one slave matched the master while two others became inconsistent quickly, he spent hours and hours figuring out what went wrong!)&lt;br /&gt;&lt;br /&gt;You also assume multiple &lt;span class='caps'&gt;EC2&lt;/span&gt; instances in your description, but there is no control over their location. They may well be on the same power circuit that goes out. What about the S3 node? I forget the semantic details: when S3 ACKs the store request, does it guarantee that the data is replicated already or does it only guarantee that it is on persistent storage? In other words, could it be on a machine in the same datacenter on the same &lt;span class='caps'&gt;UPS&lt;/span&gt; that goes down with the &lt;span class='caps'&gt;EC2&lt;/span&gt; mysql box and doesn&#8217;t come back up until the &lt;span class='caps'&gt;UPS&lt;/span&gt; is repaired a few hours later? In that case, yes, the data would be safe on S3, but unavailable for a few hours. That wouldn&#8217;t help me in quicly restoring from S3 onto a new mysql instance, would it?&lt;br /&gt;&lt;br /&gt;Someone else also mentioned restore time on the &lt;span class='caps'&gt;EC2&lt;/span&gt; forum. How long would it take to restore a 70GB database? (70GB is probably the max you can put on an &lt;span class='caps'&gt;EC2&lt;/span&gt; instance if you ever want to be able to make a backup copy without jumping through hoops.) My guess is at least 10-15 minutes, and that doesn&#8217;t count the time to apply the logs.&lt;br /&gt;&lt;br /&gt;Oh, talking about logs, when do you start your logs? You need a clean full backup and then you can start the (incremental) replication logs. After a while, you really should start afresh so you don&#8217;t collect endless logs that would take forever to apply. If your app is not 24/7 it&#8217;s easy, but if it&#8217;s 24&#215;7 you need to do what&#8217;s called a hot-backup. Ahhh, no such support in mysql/innodb unless you pay for it.&lt;br /&gt;&lt;br /&gt;And performance? Did you know that a mysql slave can easily be slower than the master? The reason is that the slave reads and applies the replication log using a single thread. So while your app server bangs on your master with high concurrency, your slave performs one operation at a time. Usually this is not an issue because the master has the additional load of reads, but the problem does exist.&lt;br /&gt;&lt;br /&gt;The bottom line is that in theory everything is available to set-up a nice mysql installation on &lt;span class='caps'&gt;EC2&lt;/span&gt;/S3, but in practice it&#8217;s far from easy to actually pull it off in a reliable manner.&lt;br /&gt;&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-09-17:15</id>
    <published>2006-09-17T17:48:00Z</published>
    <updated>2007-01-16T19:22:54Z</updated>
    <category term="Xen virtual machines"/>
    <category term="debian"/>
    <category term="xen"/>
    <link href="http://blog.voneicken.com/2006/9/17/creating-a-debian-xen-virtual-machine" rel="alternate" type="text/html"/>
    <title>Creating a Debian Xen virtual machine</title>
<content type="html">
            &lt;p&gt;This is brief note on how to create a Debian Sarge Xen VM on a Gentoo box. I&#8217;m using file-based disk images because it&#8217;s so flexible. I don&#8217;t believe the partition based ones are actually significantly faster. Inspiration for some of this came from this &lt;a href='http://mark.foster.cc/wiki/index.php/Debian_Sarge_on_Xen'&gt;wiki page.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First I created a 30G &lt;span class='caps'&gt;LVM&lt;/span&gt; volume to hold disk images, created an &lt;span class='caps'&gt;XFS&lt;/span&gt; file system, and mounted it. Then I created a 4GB root image for Debian using &lt;span class='caps'&gt;XFS&lt;/span&gt; as well. I like &lt;span class='caps'&gt;XFS&lt;/span&gt; because it allows me to shrink and expand the filesystem and it also allows me to take snapshots.
&lt;pre&gt;hydra xen # lvcreate -L 30G vg1 -n images
 Logical volume &quot;images&quot; created
hydra xen # mkdir /etc/xen/images
hydra xen # cat &amp;gt;&amp;gt;/dev/fstab
/dev/vg1/images  /etc/xen/images xfs  noauto,noatime  0 2
&amp;lt;ctrl-D&amp;gt;
hydra xen # mkfs.xfs /dev/vg1/images 
meta-data=/dev/vg1/images        isize=256    agcount=16, agsize=491520 blks
         =                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=7864320, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096  
log      =internal log           bsize=4096   blocks=3840, version=1
         =                       sectsz=512   sunit=0 blks
realtime =none                   extsz=65536  blocks=0, rtextents=0
hydra xen # mount /dev/vg1/images
hydra xen # df -h /dev/vg1/images
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/mapper/vg1-images
                       30G   13G   18G  41% /etc/xen/images
hydra ~ # dd if=/dev/zero of=/etc/xen/images/debian.root bs=1024k count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 129.508 seconds, 33.2 MB/s
hydra xen # mkdir /mnt/xen/debian.root
hydra xen # mkfs.xfs /xen/xen/images/debian.root 
meta-data=/big/xen/debian.root   isize=256    agcount=8, agsize=131072 blks
         =                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=1048576, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096  
log      =internal log           bsize=4096   blocks=2560, version=1
         =                       sectsz=512   sunit=0 blks
realtime =none                   extsz=65536  blocks=0, rtextents=0
hydra xen # mount -o loop /etc/xen/images/debian.root /mnt/xen/debian.root
hydra xen #
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Now we&#8217;re ready to install Debian Sarge: 
&lt;pre&gt;hydra xen # emerge debootstrap
Calculating dependencies ...done!
&amp;gt;&amp;gt;&amp;gt; emerge (1 of 2) app-arch/dpkg-1.10.28 to /
...
&amp;gt;&amp;gt;&amp;gt; emerge (2 of 2) dev-util/debootstrap-0.2.45-r1 to /
...
hydra xen # debootstrap --arch i386 sarge /mnt/xen/debian.root http://ftp.us.debian.org/debian
I: Retrieving debootstrap.invalid_dists_sarge_Release
I: Validating debootstrap.invalid_dists_sarge_Release
I: Retrieving debootstrap.invalid_dists_sarge_main_binary-i386_Packages
I: Validating debootstrap.invalid_dists_sarge_main_binary-i386_Packages
I: Checking adduser...
...
I: Base system installed successfully.
umount: /mnt/xen/debian.root/dev/pts: not mounted
umount: /mnt/xen/debian.root/dev/shm: not mounted
umount: /mnt/xen/debian.root/proc/bus/usb: not mounted
hydra xen # 
&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;Now we configure the new system:
&lt;pre&gt;hydra xen # chroot /mnt/xen/debian.root/
hydra:/# cd /etc
hydra:/etc# cat &amp;gt;fstab
/dev/sda1     /     ext3     defaults     0     1
/dev/sda2     none  swap     sw                    0     0
proc          /proc proc     defaults              0     0
hydra:/etc# mv /lib/tls /lib/tls.disabled
hydra:/etc# exit
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Here&#8217;s my Xen config file, note that I have a &lt;span class='caps'&gt;DHCP&lt;/span&gt; server with static leases based on the mac address, that&#8217;s why I specify it carefully.:
&lt;pre&gt;hydra xen # cat debian 
kernel = &quot;/boot/vmlinuz-2.6.16-r1-xenU&quot; 
memory = 128
name = &quot;debian&quot; 
vif = [ 'mac=00:16:3E:00:00:24' ]
disk = ['file:/etc/xen/images/debian.root,sda1,w', 'file:/etc/xen/images/debian.swap,sda2,w']
root = &quot;/dev/sda1 ro&quot; 
hydra xen # 
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Let&#8217;s start the virtual machine!
&lt;pre&gt;hydra xen # umount /mnt/xen/debian.root/
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-25:14</id>
    <published>2006-08-25T18:40:00Z</published>
    <updated>2006-12-02T02:42:33Z</updated>
    <category term="Amazon Web Services"/>
    <category term="aws"/>
    <category term="ec2"/>
    <link href="http://blog.voneicken.com/2006/8/25/top-missing-features-for-amazon-ec2" rel="alternate" type="text/html"/>
    <title>Top missing features for Amazon EC2</title>
<content type="html">
            &lt;p&gt;We need Static IPs. Dynamic IPs don&#8217;t work for a reliable web server. Hopefully a solution will come combined with a simple load balancing option.
&lt;br /&gt;
&lt;br /&gt;
&lt;span class='caps'&gt;SQL&lt;/span&gt; database: I think that what&#8217;s really missing is a &lt;span class='caps'&gt;SQL&lt;/span&gt;
database service. Yes, I can run mysql or similar on &lt;span class='caps'&gt;EC2&lt;/span&gt;, but it&#8217;s
really not a good fit. The lack of persistence is not a show-stopper
but it is a pain right now. But more importantly, the machine specs for
&lt;span class='caps'&gt;CPU&lt;/span&gt; speed, memory size, number of spindles, and disk space just don&#8217;t
cut it. There isn&#8217;t enough oomph there to run a real database-backed
web service. Amazon needs to step up and offer a &lt;span class='caps'&gt;D2B&lt;/span&gt; service:
Distributed DataBase. I&#8217;ll pay for storage at 2x the cost of S3 (since
DB storage tends to be more expensive) and $.20 per MegaTransactions
(equivalent to $0.20 for 1 hour at 277 tps). Well, 2006 isn&#8217;t over yet,
is it :-)&lt;br /&gt;&lt;br /&gt;The lack of persistence is not an real showstopper issue. The only set-up I could
imagine that would really improve things is if they had &lt;span class='caps'&gt;SAN&lt;/span&gt; type of
storage attached to their machines. This way the machine can be fried
and your data is still intact on the &lt;span class='caps'&gt;SAN&lt;/span&gt; and can be mounted on a fresh
machine. Use &lt;span class='caps'&gt;RAID&lt;/span&gt; on the &lt;span class='caps'&gt;SAN&lt;/span&gt; to safeguard against failures there or
against datacenter-wide outages. At that point, failures should be down
sufficiently in probability that a &#8220;disaster recovery&#8221; type of backup
is sufficient. For example incremental backups to S3 every 10-30
minutes. Alternatively all enterprise class SANs have mirroring
options. You could pay Amazon a few more bucks to be allocated on a
wide-area mirrored &lt;span class='caps'&gt;SAN&lt;/span&gt; partition. But all this gets into big bucks
quickly, even on an Amazon scale, so I don&#8217;t think we&#8217;ll see that
anytime soon.&lt;br /&gt;&lt;br /&gt;I believe the persistence issue will be solved though log
replication. Replicate database logs to another instance or to S3 in a
real-time manner and have &lt;span class='caps'&gt;EC2&lt;/span&gt; give you some control over the placement
of instances so that a cluster pair has some degree of failure
isolation. For files use a log-based filesystem and also replicate the
logs. Ok, all that will take some time for people to sort out, but when
they/we do, everyone will benefit, not just &lt;span class='caps'&gt;EC2&lt;/span&gt; users because all this
is not just an &lt;span class='caps'&gt;EC2&lt;/span&gt; problem. Your machine at joe-hosting.com is just as
affected. Just that usually when it crashes your disk doesn&#8217;t get
wiped, or if the motherboard dies joe moves the HD to the new box for
you. Just wait until something more interesting happens, or the
datacenter goes out for a few hours and the data is as good as gone
because you have to bring up your disaster recovery datacenter after 30
minutes of outage and once traffic hits it you can&#8217;t merge any data
recovered from the old box back in anymore.
&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-25:13</id>
    <published>2006-08-25T18:02:00Z</published>
    <updated>2007-01-17T18:18:36Z</updated>
    <category term="Ruby on Rails"/>
    <category term="radrails"/>
    <category term="ruby"/>
    <link href="http://blog.voneicken.com/2006/8/25/radrails-no-go" rel="alternate" type="text/html"/>
    <title>RadRails no-go</title>
<content type="html">
            &lt;p&gt;Up to now I&#8217;ve been using JEdit as my editor when programming RoR apps. Nice, but not quite there. Also, would be nice to have an &lt;span class='caps'&gt;IDE&lt;/span&gt;, me thinks. So I finally gave RadRails a spin. This is on a windows box, so no TextMate&#8230; I&#8217;ll switch to a Mac when Vista forces me to upgrade one way or the other. Tangent. Back to what I found out after two days of trying RadRails.&lt;br /&gt;&lt;br /&gt;The first thing that drove me nuts is that RadRails doesn&#8217;t support drag&amp;amp;drop cut&amp;amp;paste of text. I&#8217;m so used to selecting text and then dragging the
selection in order to move the text that I just can&#8217;t do without. I can&#8217;t believe that it&#8217;s not supported, it just can&#8217;t be true, yet I haven&#8217;t
found a way to &#8220;enable&#8221; such a feature. Please let me know if there is a solution!&lt;br /&gt;&lt;br /&gt;Then I found out that I don&#8217;t seem to be able to split
the editor window, e.g. to see two files at the same time. It&#8217;s easy to
switch between the most recent few files using the tabs at the top, but
I often really want to see two or three files tiled vertically on top
of one another. Ouch!&lt;br /&gt;&lt;br /&gt;I love being able to stop &amp;amp; restart the webbrick server at the bottom, and the tailing of the log file is also often handy. But I don&#8217;t see any instructions on how to set things up so I can run rails in the debugger and set breakpoints. Maybe that&#8217;s not possible, dunno. So I haven&#8217;t seen any way to turn all these nifty debugging buttons from being teasers to becoming actually useful.&lt;br /&gt;&lt;br /&gt;I&#8217;m coming to the conclusion that at this point RadRails is a no-go and
am switching back to JEdit. Maybe in a few months RadRails will have
improved sufficiently to give it another spin&#8230;&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-25:12</id>
    <published>2006-08-25T16:03:43Z</published>
    <updated>2007-01-15T07:23:27Z</updated>
    <link href="http://blog.voneicken.com/2006/8/25/upgrading-typo-2-6-to-typo-4-0-3" rel="alternate" type="text/html"/>
    <title>Upgrading typo 2.6 to typo 4.0.3</title>
<content type="html">
            &lt;p&gt;Well &lt;a href='http://scottstuff.net/blog/articles/2006/07/22/typo-4-0-0'&gt;typo-4 is out&lt;/a&gt;. I had installed the typo-2.6-with-rails archive which had given me everthing in one big easy to install bundle. But can you believe it, the typo folks did not post any upgrade instructions! Yeah, there&#8217;s a great new installer, but that&#8217;s only great if you want sqlite and stuff like that.&lt;/p&gt;


	&lt;p&gt;Anyway, I&#8217;m running Fedora Core 5 (FC5), mysql, and lighttpd for typo. So here&#8217;s the upgrade story:&lt;/p&gt;


First upgrade your stock ruby &#38; rails installs. I used the typo gem to get the dependencies:
&lt;pre&gt;&lt;code&gt;gem install typo&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And when it asked to install sqlite I said &#8220;no&#8221;. But by then I got everything else I needed. A hack, but it worked for me.&lt;/p&gt;


	&lt;p&gt;Download the new typo tgz archive and extract it to a new directory:&lt;pre&gt;&lt;code&gt;wget http://rubyforge.org/frs/download.php/12504/typo-4.0.3.tgz
tar zxf typo-4.0.3.tgz
cd typo-4.0.3
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;Now copy over your database.yml and edit /etc/lighttpd/lighttpd.conf to point to the new typo dir. For me that ended up being these two lines:&lt;pre&gt;&lt;code&gt;'server.document-root        = &quot;/home/typo-4.0.3/public/&quot; 

&quot;bin-path&quot; =&amp;gt; &quot;/home/typo-4.0.3/public/dispatch.fcgi&quot;,
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;Now back up your database:&lt;pre&gt;&lt;code&gt;mysqldump -u &lt;/code&gt;typo_user_name&lt;code&gt; -p --opt -A &amp;gt;dump-2006-08-25
&lt;/code&gt;&lt;/pre&gt;
 And migrate the DB content:&lt;pre&gt;rake environment RAILS_ENV=production migrate&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;Now copy any themes over from the old themes dir and finally restart lighttpd:&lt;pre&gt;/etc/init.d/lighttpd restart&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;Done! (Well, if you&#8217;re lucky!)&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-25:11</id>
    <published>2006-08-25T14:31:00Z</published>
    <updated>2007-01-18T16:40:49Z</updated>
    <category term="Amazon Web Services"/>
    <category term="aws"/>
    <category term="ec2"/>
    <link href="http://blog.voneicken.com/2006/8/25/more-thoughts-on-ec2-pricing" rel="alternate" type="text/html"/>
    <title>More thoughts on EC2 pricing</title>
<content type="html">
            &lt;p&gt;[This is from a comment I left on &lt;a href='http://blogsiegel.blogspot.com'&gt;Jonathan&#8217;s blog&lt;/a&gt;.]&lt;/p&gt;


	&lt;p&gt;I have to admit I am disappointed at the pricing of &lt;span class='caps'&gt;EC2&lt;/span&gt;. At this rate it costs $72/mo for a not so hot machine, without persistent disk storage, and without bandwidth. Once you add bandwidth and storage you easily exceed the costs of a dedicated server at a decent hosting company&lt;/p&gt;


	&lt;p&gt;Compare this to S3 where you have to pay at least 2x for anything remotely similar. With &lt;span class='caps'&gt;EC2&lt;/span&gt; there is no such 2x factor.&lt;/p&gt;


	&lt;p&gt;So the only advantage over another hosting company is that if the thing fails you have a higher chance of being able to get a new box up and running within minutes, and if your usage skyrockets it&#8217;s quick to get more machines online. But we really don&#8217;t know about the reliability and scalability of &lt;span class='caps'&gt;EC2&lt;/span&gt; since Amazon doesn&#8217;t reveal any details whatsoever. At this point it could well be that they have all of &lt;span class='caps'&gt;EC2&lt;/span&gt; in a couple of racks at a single location&#8230;&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-24:10</id>
    <published>2006-08-24T19:25:00Z</published>
    <updated>2007-01-15T07:22:19Z</updated>
    <category term="Amazon Web Services"/>
    <category term="aws"/>
    <category term="ec2"/>
    <link href="http://blog.voneicken.com/2006/8/24/amazon-elastic-compute-cloud-just-launched" rel="alternate" type="text/html"/>
    <title>Amazon Elastic Compute Cloud just launched</title>
<content type="html">
            &lt;p&gt;See the &lt;a href='http://www.amazon.com/b/ref=sc_fe_c_1_3435361_1/002-9267424-7193607?ie=UTF8&amp;amp;node=201590011&amp;amp;no=3435361&amp;amp;me=A36L942TSJ2AJA'&gt;&lt;span class='caps'&gt;EC2&lt;/span&gt; announcement &lt;/a&gt;on the Amazon Web Services site. Pretty cool to have &#8220;infinite&#8221; compute resources available (credit card limit permitting)! Basically you get a Xen virtual linux image that you store on Amazon S3 and can &#8220;intantiate&#8221; on a server. The server is actually dedicated, so the Xen virtual image is just used in order to conveniently load the image and control the set-up.&lt;br /&gt;&lt;br /&gt;The specs of a server are &lt;span class='small'&gt;&#8220;the equivalent of a system with a 1.7Ghz Xeon &lt;span class='caps'&gt;CPU&lt;/span&gt;, 1.75GB of &lt;span class='caps'&gt;RAM&lt;/span&gt;, 160GB of local disk, and 250Mb/s of network bandwidth.&#8221; The virtual server image that is on S3 and that gets instantiated is limited to 10GB. Once running, there is a swap partition (2GB, I believe) and a 160GB &#8220;ephemeral&#8221; partition that is mounted as well. The ephmeral partition is lost if the server crashes and the machine instance is restarted on a different server. This means that for persistent storage one better use S3 or multiple instances.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Overall this sounds a bit more expensive than I had hoped. For $120/mo you get a 
dedicated box with 2TB transfer at various hosting facilities (without trying to get rock-bottom). At Amazon it costs you 
$72/mo if you run an instance 24/7. If you then did 2TB of transfer that 
would slap on another $200, ouch!
Looks like the a good idea would be to run the base servers at some 
traditional hosting facility and to leverage Amazon for peaks only.&lt;br /&gt;&lt;br /&gt;SOne of the things that is missing from &lt;span class='caps'&gt;EC2&lt;/span&gt; is static IPs. Every instance gets a dynamic IP allocated. That makes it difficult to run a reliable external-facing web server. One can use dynamic &lt;span class='caps'&gt;DNS&lt;/span&gt; services, but with the amount of caching going on in the &lt;span class='caps'&gt;DNS&lt;/span&gt; system that&#8217;s really not a satisfactory solution. Hopefully &lt;span class='caps'&gt;AWS&lt;/span&gt; will add some form of load balancing solution with static IPs soon!&lt;br /&gt;&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-17:9</id>
    <published>2006-08-17T13:33:00Z</published>
    <updated>2007-01-15T07:23:45Z</updated>
    <category term="Ruby on Rails"/>
    <link href="http://blog.voneicken.com/2006/8/17/rails-list-show-edit-variations" rel="alternate" type="text/html"/>
    <title>Rails list / show / edit variations</title>
<content type="html">
            &lt;p&gt;Having tried the standard Rails scaffold and now the new Streamlined scaffold, I feel like I&#8217;m back to square one in terms of designing the interaction model for my app. It seems it all boils down to how one handles handles list / show / edit, in particular where &lt;span class='caps'&gt;AJAX&lt;/span&gt; edit in place is possible and where it isn&#8217;t. There are only a few combinations possible, but unfortunately both the standard Rail scaffold as well as Streamlined only implement one of them, so it makes it difficult to move stuff around or to build an app that uses more than one model of interaction.&lt;br /&gt;&lt;br /&gt;The standard Rails scaffold doesn&#8217;t use &lt;span class='caps'&gt;AJAX&lt;/span&gt; at all. It&#8217;s model is as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;List &lt;/b&gt;- Table with 1 row per object, buttons for &lt;i&gt;show &lt;/i&gt;/ &lt;i&gt;edit &lt;/i&gt;/ &lt;i&gt;delete &lt;/i&gt;per row, &lt;i&gt;new &lt;/i&gt;(create) button at end of table&lt;/li&gt;&lt;li&gt;&lt;b&gt;Show &lt;/b&gt;- Table with 1 row per attribute, buttons for &lt;i&gt;back &lt;/i&gt;and &lt;i&gt;edit &lt;/i&gt;at the bottom&lt;/li&gt;&lt;li&gt;&lt;b&gt;Edit &lt;/b&gt;- Form table similar to show, but with editable forms, buttons for &lt;i&gt;save &lt;/i&gt;and &lt;i&gt;cancel &lt;/i&gt;at the bottom&lt;/li&gt;&lt;/ul&gt;Streamlined takes a different approach and basically operates entirely from within the list view. Show and edit are handled within pop-up layers:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;List &lt;/b&gt;- Table with 1 row per object, buttons for &lt;i&gt;show &lt;/i&gt;/ &lt;i&gt;edit &lt;/i&gt;/ &lt;i&gt;delete &lt;/i&gt;per row, &lt;i&gt;new &lt;/i&gt;button at end of table&lt;/li&gt;&lt;li&gt;&lt;b&gt;Show &lt;/b&gt;- Pop-up table with 1 row per attribute, &lt;i&gt;edit &lt;/i&gt;button at end, and &#8220;window&#8221; &lt;i&gt;close/minimize/maximize&lt;/i&gt; buttons in the pop-up window title bar&lt;/li&gt;&lt;li&gt;&lt;b&gt;Edit &lt;/b&gt;- Uses same pop-up window as &lt;i&gt;show &lt;/i&gt;and transition between &lt;i&gt;show &lt;/i&gt;and &lt;i&gt;edit &lt;/i&gt;is smooth (but does require server request), buttons for &lt;i&gt;save &lt;/i&gt;and &lt;i&gt;show &lt;/i&gt;at the bottom.&lt;/li&gt;&lt;/ul&gt;A nice aspect of the streamlined &lt;i&gt;show&lt;/i&gt;/&lt;i&gt;edit &lt;/i&gt;pop-up windows is that it is possible to show multiple elements at the same time.&lt;br /&gt;&lt;br /&gt;The ajax scaffold seems to be similar to Streamlined in that it operates entirely out of the list view. I haven&#8217;t tried it, so I&#8217;m not 100% sure. From what I can gather it operates as follows:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;List &lt;/b&gt;- Table with 1 row per object, buttons to &lt;i&gt;edit &lt;/i&gt;and &lt;i&gt;delete&lt;/i&gt;, button for &lt;i&gt;new &lt;/i&gt;(create) at the top.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Show &lt;/b&gt;- no such view, it&#8217;s all shown in the list table&lt;/li&gt;&lt;li&gt;&lt;b&gt;Edit &lt;/b&gt;- Creates an in-place form by increasing the (vertical size of the row and placing a form into the row with buttons for &lt;i&gt;save &lt;/i&gt;and &lt;i&gt;cancel&lt;/i&gt;.&lt;/li&gt;&lt;/ul&gt;The mode I&#8217;d like to have at the moment is different from the above. The primary reason is that I have a lot of information for each object, including images, thus maing it impractical to show everything in a list view. What I&#8217;d like is:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;List &lt;/b&gt;- Table with 1 row per object, showing only selected attributes, click on row to &lt;i&gt;show&lt;/i&gt;, button at top for &lt;i&gt;new&lt;/i&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Show &lt;/b&gt;- Page with 1 row per attribute, click on any attribute to switch to &lt;i&gt;edit&lt;/i&gt;, button at top for &lt;i&gt;delete&lt;/i&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Edit &lt;/b&gt;- Seamless in-place transition between show and edit, buttons for &lt;i&gt;save &lt;/i&gt;and &lt;i&gt;cancel &lt;/i&gt;at the bottom&lt;/li&gt;&lt;/ul&gt;The second reason I&#8217;d like to have a full page for show, instead of the pop-up that Streamlined creates, is that I have a bunch of many-to-many relationships for which I&#8217;m still trying to find a good editing model. I am not using the Rail &lt;span class='caps'&gt;HABTM&lt;/span&gt; at all and am instead creating explicit models for the relationships because each of these relationships has attributes on its own. What I&#8217;d like to happen with these relationships in the views of the entities that are being related is the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;List &lt;/b&gt;- There is no &lt;i&gt;list &lt;/i&gt;view for a relationship on its own, but there is a &lt;i&gt;list &lt;/i&gt;partial that can be included in a cell in the &lt;i&gt;list &lt;/i&gt;view of either of the entities being related&lt;/li&gt;&lt;li&gt;&lt;b&gt;Show &lt;/b&gt;- There is no &lt;i&gt;show &lt;/i&gt;view for a relationship on its own, but there is a &lt;i&gt;show &lt;/i&gt;partial that is included in the &lt;i&gt;show &lt;/i&gt;view of either of the entities being related. The &lt;i&gt;show &lt;/i&gt;partial is really more like a &lt;i&gt;list &lt;/i&gt;view in that it shows a table with one row per relationship.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Edit &lt;/b&gt;- Again, there is no &lt;i&gt;edit &lt;/i&gt;view for a relationship on its own, but there is an &lt;i&gt;edit &lt;/i&gt;partial very similar to the &lt;i&gt;show &lt;/i&gt;partial that is intended to be included in the &lt;i&gt;edit &lt;/i&gt;view of either of the entities being related. The &lt;i&gt;edit &lt;/i&gt;partial allows inline editing of the relationship attributes, and it has a &lt;i&gt;delete &lt;/i&gt;button for each row. At the bottom it has a drop-down select box to add new relationships.&lt;/li&gt;&lt;/ul&gt;Ok, I really need to add some pictures to explain this. But actually the real point I want to make is not that the way I&#8217;d like to structure the list / show / edit interaction is better, but that I need the flexibility. So what I&#8217;d like is the scaffold to offer more flexibility and generate more possibilities for me: don&#8217;t try to lock me into one interation model. Either give me a bunch of options to pass to the generator ot generate a whole bunch of partials that I can combine in different ways.&lt;br /&gt;&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
  <entry xml:base="http://blog.voneicken.com/">
    <author>
      <name>tve</name>
    </author>
    <id>tag:blog.voneicken.com,2006-08-07:8</id>
    <published>2006-08-07T13:20:00Z</published>
    <updated>2007-01-15T07:22:34Z</updated>
    <category term="Ruby on Rails"/>
    <category term="Xen virtual machines"/>
    <link href="http://blog.voneicken.com/2006/8/7/installing-ruby-on-rails-on-a-rimuhosting-fedora-core-machine" rel="alternate" type="text/html"/>
    <title>Installing Ruby on Rails on a Rimuhosting Fedora Core machine</title>
<content type="html">
            &lt;p&gt;Here I go for my second Ruby on Rails install. This time it&#8217;s on a &#8220;virtual private server&#8221; at &lt;a href='//www.rimuhosting.com'&gt;Rimuhosting&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Installing a whole bunch of &lt;strong&gt;ruby&lt;/strong&gt; stuff:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;yum install ruby ruby-libs ruby-mode ruby-rdoc ruby-irb ruby-devel ruby-docs&lt;/code&gt;&lt;/p&gt;


Installing &lt;strong&gt;gems&lt;/strong&gt; (check for latest version on &lt;a href='//rubyforge.org/frs/?group_id=126'&gt;RubyForge&lt;/a&gt;) 
&lt;pre&gt;
wget http://rubyforge.org/frs/download.php/11289/rubygems-0.9.0.tgz
tar zxvf rubygems-0.9.0.tgz
cd rubygems-0.9.0
ruby setup.rb
&lt;/pre&gt;

	&lt;p&gt;I installed &lt;strong&gt;rails&lt;/strong&gt;:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;gem install rails --include-dependencies&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;Now &lt;strong&gt;mySQL&lt;/strong&gt;, which was installed but needed a bit of config:&lt;/p&gt;


&lt;pre&gt;
chkconfig --add mysqld
chkconfig --level 3 mysqld on
/etc/init.d/mysqld start
/usr/bin/mysqladmin -u root password 'somethingsmart'
/usr/bin/mysqladmin -u root -h graphs.voneicken.com password 'somethingsmart'
&lt;/pre&gt;

	&lt;p&gt;Now we&#8217;re ready for the ruby mysql interface. First install the mysql-devel package (Rimu uses apt on &lt;span class='caps'&gt;FC5&lt;/span&gt;, not yum):&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;apt-get install mysql-client&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;and then the ruby interface itself:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;gem install mysql -- --with-mysql-dir=/usr/lib/mysql --with-mysql-config=/usr/bin/mysql_config&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;Now we&#8217;re ready for &lt;strong&gt;mongrel&lt;/strong&gt;!&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;gem install mongrel&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;did it&#8217;s job without complaining. What a relief!&lt;/p&gt;
          <!-- ckey="00326668" --></content>  </entry>
</feed>
