<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8315047248038686888</id><updated>2024-09-11T19:55:30.057-04:00</updated><category term="logistics"/><category term="db"/><category term="schema"/><category term="import"/><category term="milestone"/><category term="config"/><category term="status"/><category term="activemq"/><category term="documentation"/><category term="migration"/><category term="graphing"/><category term="messaging"/><category term="rails convention"/><category term="aptana"/><category term="catch-22"/><category term="install"/><category term="nfs"/><category term="postponed"/><category term="school"/><title type='text'>Thesis Development</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-2656109568041294330</id><published>2009-06-04T21:58:00.000-04:00</published><updated>2009-06-04T21:58:20.571-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>Thesis Document</title><content type='html'>The final version of my thesis document was approved on April 28th.&amp;nbsp; A PDF version is available &lt;a href=&quot;http://dl.getdropbox.com/u/85513/docs/Paul_Russell_Masters_Thesis_v6-FINAL-to-Wells-Bindery.pdf&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://dl.getdropbox.com/u/85513/docs/Paul_Russell_Masters_Thesis_v6-FINAL-to-Wells-Bindery.pdf&quot;&gt;&lt;img border=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN1no2BQBYSu4HMOWimUGtFxy3WkGAop57xDlK9NKW8B3beMSI2ptq3x2e052gyfAkcdYPvUFj67xOzdZE8WdTAw7DBLFnhLC47evbGxOfMUgQHAhdzmpRhkN3NvLUSk1mchKzZJ2sh-WH/s320/Picture+8.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Per the requirements of the thesis course I sent it off to the binders who were kind enough to turn it into an actual book for just under $100. The final version of the book was approved by my thesis director on May 11, 2009 at which point I took up sleeping again.&amp;nbsp; The book is now sitting on a shelf in the Grossman Library in Harvard Yard.&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;iframe frameborder=&quot;0&quot; height=&quot;350&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Harvard+yard,+Cambridge,+MA+02138&amp;amp;sll=42.38039,-71.117463&amp;amp;sspn=0.017689,0.034075&amp;amp;g=1350+Massachusetts+Ave,+Cambridge,+MA+02138&amp;amp;ie=UTF8&amp;amp;cid=9083814586948534389&amp;amp;ll=42.383021,-71.115189&amp;amp;spn=0.02219,0.036478&amp;amp;z=14&amp;amp;iwloc=A&amp;amp;output=embed&quot; width=&quot;425&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;small&gt;&lt;a href=&quot;http://maps.google.com/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Harvard+yard,+Cambridge,+MA+02138&amp;amp;sll=42.38039,-71.117463&amp;amp;sspn=0.017689,0.034075&amp;amp;g=1350+Massachusetts+Ave,+Cambridge,+MA+02138&amp;amp;ie=UTF8&amp;amp;cid=9083814586948534389&amp;amp;ll=42.383021,-71.115189&amp;amp;spn=0.02219,0.036478&amp;amp;z=14&amp;amp;iwloc=A&quot; style=&quot;color: blue; text-align: left;&quot;&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;br /&gt;
&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
I haven&#39;t actually seen the bound copy since it was sent directly from the binders to the school.&amp;nbsp;&amp;nbsp; I think I&#39;ll stop by the library when I go to pick up my diploma.  I&#39;ve been thinking about taking Alex (my 5 year old son) and making a day of it.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/2656109568041294330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/2656109568041294330' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/2656109568041294330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/2656109568041294330'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/06/thesis-document.html' title='Thesis Document'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN1no2BQBYSu4HMOWimUGtFxy3WkGAop57xDlK9NKW8B3beMSI2ptq3x2e052gyfAkcdYPvUFj67xOzdZE8WdTAw7DBLFnhLC47evbGxOfMUgQHAhdzmpRhkN3NvLUSk1mchKzZJ2sh-WH/s72-c/Picture+8.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-8405396854861459448</id><published>2009-04-28T21:26:00.000-04:00</published><updated>2009-04-28T21:26:22.617-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="documentation"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><title type='text'>Advanced Page Numbering in Microsoft Word</title><content type='html'>For the past few weeks I&#39;ve been responding to review comments on my thesis document. it boils down to a lot of tweaking of the text, and proofreading until I wish I never heard of my thesis project.  But it was all pretty straight forward until tonight.&lt;br /&gt;
&lt;br /&gt;
Today, in what I hope was the last review comment, I was told that the page numbering in my 262 page document was not correct.  My document starts with the first page numbered 1 and proceeds to increment up to page 262. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;But the thesis document requirement is:&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The first three pages of the document should have no page numbers&lt;/li&gt;
&lt;li&gt;starting on the 4th page pages should be numbered in roman numerals starting with the number iv. (so basically the first three pages were i, ii, and iii, but those numbers are supposed to be hidden.)&lt;/li&gt;
&lt;li&gt;Starting with the first page of Chapter 1, the pages should be numbered with incrementing Arabic numbers. 1, 2, 3...&lt;/li&gt;
&lt;/ol&gt;If you, like me, are a casual Microsoft Word user you will find this task infuriating. As did the author of the Harvard Extended blog in &lt;a href=&quot;http://harvardextended.blogspot.com/2007/07/thesis-update-formatting-horrors-and.html&quot;&gt;this post&lt;/a&gt;.  He came up with an answer, but it turns out there was a much simpler way to meet the above requirements.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;The Solution&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitdTgv3oA5OL6wVzoTQbd_-J-0_pJVFsG3Wo4gcOO_As90xNdUmRAOmxK7TqzQfVKqDSYGGV9dfVW_sWz91sHXNyJg5bkVyCyMCoVN7EpwLs6SHt4_St_ernPaZkBIfauO0RPY7FPMuzzV/s1600-h/Picture+9.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitdTgv3oA5OL6wVzoTQbd_-J-0_pJVFsG3Wo4gcOO_As90xNdUmRAOmxK7TqzQfVKqDSYGGV9dfVW_sWz91sHXNyJg5bkVyCyMCoVN7EpwLs6SHt4_St_ernPaZkBIfauO0RPY7FPMuzzV/s320/Picture+9.png&quot; /&gt;&lt;/a&gt;
&lt;li&gt;Read &lt;a href=&quot;http://word.mvps.org/faQs/Numbering/PageNumbering.htm&quot;&gt;How to control the page numbering in a Word document&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Find some way to thank &lt;a href=&quot;http://word.mvps.org/AboutMVPs/bill_coan.htm&quot;&gt;Bill Coan&lt;/a&gt; for identifying this preposterous use case and writing such a useful article about how to address it. &lt;/li&gt;
&lt;li&gt;Create a new &quot;Section&quot; at the end of each of the first three pages using the menu &lt;i&gt;&lt;b&gt;Insert &amp;gt;&amp;gt; Break &amp;gt;&amp;gt; Section Break.&lt;/b&gt;&lt;/i&gt; Section breaks replace page breaks in these locations and will let you number the pages per the requirements above. &lt;/li&gt;
&lt;li&gt;Create a &quot;Section&quot; just before the Chapter 1 chapter heading&lt;b&gt; &lt;/b&gt;using the same method as in step 3.&lt;/li&gt;
&lt;li&gt;Put the courser on the first page and add page numbers using the menu &lt;i&gt;&lt;b&gt;INSERT &amp;gt;&amp;gt; Page Numbers&lt;/b&gt;&lt;/i&gt; Be sure to un-check &quot;Show number on the first page&quot; just like I did the picture tot he right. Since this page is it&#39;s own section no page numbers will appear.&lt;/li&gt;
&lt;li&gt;Repeat this step for page 2 and 3 if there are page numbers showing. Those sections, may inherit the settings from page one. In that case you may not need to do anything.&lt;/li&gt;
&lt;li&gt;Put the courser on page 4 add page numbers again, but this time (per the &lt;i&gt;Page Number Format&lt;/i&gt; image):&lt;/li&gt;

&lt;ol&gt;&lt;li&gt; CHECK the &quot;Show number on first page&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Choose &lt;i&gt;&lt;b&gt;Alignment &quot;Center&quot;&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;i&gt;&lt;b&gt;Format...&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Choose &lt;i&gt;&lt;b&gt;Number Format &quot;i, ii, iii...&quot;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Choose&lt;i&gt;&lt;b&gt; Start At &quot;iv&quot;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;Put the courser on the first page of Chapter 1 and add page numbers again, but this time:&lt;/li&gt;

&lt;ol&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL0ZvpoIk8CpTnHznoFf87N1Mn9fnwniF8KmTC0xCKu4rL53eWcaa-iw5nhfZqQNTcQj-01TPUykJhHQ90j6bRjygXg2EH33db49hyFyX6V6DnFFgQ7EHXIKeWS1zvFkO5iY-ycT0Vsq6P/s1600-h/Picture+10.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL0ZvpoIk8CpTnHznoFf87N1Mn9fnwniF8KmTC0xCKu4rL53eWcaa-iw5nhfZqQNTcQj-01TPUykJhHQ90j6bRjygXg2EH33db49hyFyX6V6DnFFgQ7EHXIKeWS1zvFkO5iY-ycT0Vsq6P/s320/Picture+10.png&quot; /&gt;&lt;/a&gt;
&lt;li&gt; CHECK the &quot;Show number on first page&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Choose &lt;i&gt;&lt;b&gt;Alignment &quot;Center&quot;&lt;/b&gt;&lt;/i&gt; &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;i&gt;&lt;b&gt;Format...&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Choose &lt;i&gt;&lt;b&gt;Number Format &quot;1, 2, 3...&quot;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Choose&lt;i&gt;&lt;b&gt; Start At &quot;1&quot;&lt;/b&gt;&lt;/i&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/ol&gt;&lt;br /&gt;
That&#39;s it. You should now have a document that follows the conventions for the Harvard ALM in IT Masters Thesis document. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;Acknowledgments&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I&#39;d like to thank Ian Lamont, the author of &lt;a href=&quot;http://harvardextended.blogspot.com/&quot;&gt;Harvard Extended&lt;/a&gt;. I wish I had found his blog more than two weeks before I was about to finish school.   And of course thanks to &lt;a href=&quot;http://google.com/&quot;&gt;Google&lt;/a&gt; for pointing &lt;a href=&quot;http://word.mvps.org/AboutMVPs/bill_coan.htm&quot;&gt;Bill Coan&lt;/a&gt; who wrote &lt;a href=&quot;http://word.mvps.org/faQs/Numbering/PageNumbering.htm&quot;&gt;this obscure but brilliant article&lt;/a&gt; on MS Word page numbering.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/8405396854861459448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/8405396854861459448' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/8405396854861459448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/8405396854861459448'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/04/advanced-page-numbering-in-microsoft.html' title='Advanced Page Numbering in Microsoft Word'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitdTgv3oA5OL6wVzoTQbd_-J-0_pJVFsG3Wo4gcOO_As90xNdUmRAOmxK7TqzQfVKqDSYGGV9dfVW_sWz91sHXNyJg5bkVyCyMCoVN7EpwLs6SHt4_St_ernPaZkBIfauO0RPY7FPMuzzV/s72-c/Picture+9.png" height="72" width="72"/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-5972449268268171359</id><published>2009-03-31T23:25:00.027-04:00</published><updated>2009-04-01T00:44:24.273-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>Zero Hour</title><content type='html'>&lt;div class=&quot;&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixzN4lzi_i1LZX1HljI6hK3SfdbXnhzVPU3ONPiJBv5KYzqLOr-L1gAm66Pz42LFOehjke13IMqOEUmHK6n5VESle_xHzJYi_XpW7fmmIUMbVBB512VeetMRnuWFKoJg6UV-Ii0Myht8Ou/s1600-h/Picture+2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixzN4lzi_i1LZX1HljI6hK3SfdbXnhzVPU3ONPiJBv5KYzqLOr-L1gAm66Pz42LFOehjke13IMqOEUmHK6n5VESle_xHzJYi_XpW7fmmIUMbVBB512VeetMRnuWFKoJg6UV-Ii0Myht8Ou/s320/Picture+2.png&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;I turned my 89 page thesis document in to my thesis adviser and thesis director at 11:15pm March 31st 2009. 45 minutes before it was due.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;&quot; style=&quot;clear: both; text-align: left;&quot;&gt;I expect them to send back comments and change requests. There will probably be a few more revisions before the thesis is accepted.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;There is one outstanding task: The code needs to be included in the final doc, so I need to write a script to read through the rails code and convert it into the format they expect in the doc.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;I should be bouncing off the walls, but at the moment I&#39;m too tired to be excited.  Allison seems to have a horrible stomach bug, so I&#39;m off be be Dad an check on her before I pass out.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/5972449268268171359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/5972449268268171359' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/5972449268268171359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/5972449268268171359'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/zero-hour.html' title='Zero Hour'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixzN4lzi_i1LZX1HljI6hK3SfdbXnhzVPU3ONPiJBv5KYzqLOr-L1gAm66Pz42LFOehjke13IMqOEUmHK6n5VESle_xHzJYi_XpW7fmmIUMbVBB512VeetMRnuWFKoJg6UV-Ii0Myht8Ou/s72-c/Picture+2.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6306826281824290349</id><published>2009-03-20T21:42:00.005-04:00</published><updated>2009-03-20T21:50:27.338-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="documentation"/><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>Thesis Document First Draft</title><content type='html'>The first draft of the thesis document is complete! It came in at a paltry 50 pages.&lt;br /&gt;&lt;br /&gt;Fortunately I&#39;ll be able to pad the page count with all the code I&#39;m required to put in the appendix. Rendered as a PDF it only takes up 1.4mb of space. It&#39;s almost as if I didn&#39;t have anything to say.&lt;br /&gt;&lt;br /&gt;Since the chances of my getting it just right the first time are next to nill, I&#39;m expecting a pile of comments and recommendations from my thesis adviser. I&#39;ll have to act quickly to make any changes he requests before I turn it in on April 1st.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the mean time, this is what Google Docs thinks of the thesis document.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVyrn7Ao7cDb8QUKqvp8sXd7S7NLf-Xb07bwx39UEgk9wkfso8-pD8jQF-u_LtPw5mSzaDwIO9fUrlxnLDLJ1w5Co8jwWrASOLf1qvRhOj8w0MwYDHKSyjrvZUXpllAAl1B6-Yykdld9M2/s1600-h/Picture+1.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 317px; height: 400px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVyrn7Ao7cDb8QUKqvp8sXd7S7NLf-Xb07bwx39UEgk9wkfso8-pD8jQF-u_LtPw5mSzaDwIO9fUrlxnLDLJ1w5Co8jwWrASOLf1qvRhOj8w0MwYDHKSyjrvZUXpllAAl1B6-Yykdld9M2/s400/Picture+1.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5315452205182771122&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6306826281824290349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6306826281824290349' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6306826281824290349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6306826281824290349'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/thesis-document-first-draft.html' title='Thesis Document First Draft'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVyrn7Ao7cDb8QUKqvp8sXd7S7NLf-Xb07bwx39UEgk9wkfso8-pD8jQF-u_LtPw5mSzaDwIO9fUrlxnLDLJ1w5Co8jwWrASOLf1qvRhOj8w0MwYDHKSyjrvZUXpllAAl1B6-Yykdld9M2/s72-c/Picture+1.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-924499800624345082</id><published>2009-03-07T16:31:00.000-05:00</published><updated>2009-03-07T16:31:27.513-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="graphing"/><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>A Very Beautiful Graph</title><content type='html'>Of all the parts of my project, graphing has the most moving parts. It requires the generators to work, the controller to respond quickly and for a bunch of JavaScript to combine lots of data from both the generator and the controller and format that data into a Google chart URL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDbnLu_aOCG-_U6l22u84sGPgM5kRZN5IAZwp4pYcLm0n5OdaWAoR3K8_vcYFflphOTyIP8Rd6W-qyJ9AcTfTAJDbyDe_5cumSExObebDjotftt9p4KYYhaj9M7WMc-4NAaDz-t4d6Q_7M/s1600-h/chart.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDbnLu_aOCG-_U6l22u84sGPgM5kRZN5IAZwp4pYcLm0n5OdaWAoR3K8_vcYFflphOTyIP8Rd6W-qyJ9AcTfTAJDbyDe_5cumSExObebDjotftt9p4KYYhaj9M7WMc-4NAaDz-t4d6Q_7M/s400/chart.png&quot; style=&quot;cursor: move;&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
This is an actual graph, of actual projections, and actual bug counts. It was served up by the controller after I clicked on a graph link from a generated project summary page. It&#39;s using completely real data from the controller DB and the generators history.js files generated at the same time as the enotify project page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In other words. It works!&lt;br /&gt;
&lt;br /&gt;
More importantly, there are NO caveats!&lt;br /&gt;
&lt;br /&gt;
This is production data.&amp;nbsp; I didn&#39;t hold it&#39;s hand or even watch.&amp;nbsp; I just came back after it the generator did it&#39;s thing, went to the web page and TA-DAAAAA!</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/924499800624345082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/924499800624345082' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/924499800624345082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/924499800624345082'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/very-beautiful-graph.html' title='A Very Beautiful Graph'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDbnLu_aOCG-_U6l22u84sGPgM5kRZN5IAZwp4pYcLm0n5OdaWAoR3K8_vcYFflphOTyIP8Rd6W-qyJ9AcTfTAJDbyDe_5cumSExObebDjotftt9p4KYYhaj9M7WMc-4NAaDz-t4d6Q_7M/s72-c/chart.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6077489892047478210</id><published>2009-03-07T11:38:00.005-05:00</published><updated>2009-03-07T11:45:50.306-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>Running the Real Thing</title><content type='html'>I just launched a longevity test of the system using current production data. To this point all of the runs used data that was over 6 months old. While that data is valid, there are features of the graphing system that don&#39;t get exercised.&lt;br /&gt;&lt;br /&gt;In order to get a full real life view of the graph functionality you need projections that span at least 1 week before and after the current date.  While the graphs were tested with test projections that met that requirement, the 6 month old data didn&#39;t provide a real life view of a fully exercised graph.&lt;br /&gt;&lt;br /&gt;So basically, I&#39;ve tested this thing every way I can, and the only thing left to do is to import production data into the controller and let the generators do their thing.&lt;br /&gt;&lt;br /&gt;If all goes as expected I&#39;ll be able to demo the running system with production data and extremely cool, live updating graphs.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6077489892047478210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6077489892047478210' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6077489892047478210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6077489892047478210'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/running-real-thing.html' title='Running the Real Thing'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-4715824506300061498</id><published>2009-03-07T00:22:00.005-05:00</published><updated>2009-03-07T00:32:34.374-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><title type='text'>Late night thoughts and Connecting to MySql on a Remote Machine</title><content type='html'>I&#39;m sitting here in the dark loading lots of production data into the project so I can get some realistic looking graphs for the demo of the project.&lt;br /&gt;&lt;br /&gt;Two things occur to me at this late hour:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;This project while ridiculously large in scope, was a good idea. Even as I run the import script data on different sites, I&#39;m discovering that as structured as the data is, there are still differences between the data formats and types on the legacy server. A central db and controller is long overdue.&lt;/li&gt;&lt;li&gt;I should have written down the instructions for enabling a remote mysql client/user to connect to a mysql instance. Here they are for the next time:&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Users need permission to connect to mysql on a remote linux machine. If they don&#39;t have it, trying to log in with MYSQL Admin or MYSQL Query Analyzer will fail with a 1045 error.&lt;br /&gt;&lt;br /&gt;To fix this log into the shell on the mysql server and type this:&lt;br /&gt;&lt;br /&gt;make sure you have granted access to your user: (run command line)&lt;br /&gt;mysql&gt; GRANT ALL ON databaseName.* TO &#39;your_mysql_name&#39;@&#39;your_client_host_or_ip&#39;;&lt;/blockquote&gt;I found these instructions @ &lt;a href=&quot;http://forums.mysql.com/read.php?35,9919,12139#msg-12139&quot;&gt;http://forums.mysql.com/read.php?35,9919,12139#msg-12139&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/4715824506300061498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/4715824506300061498' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/4715824506300061498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/4715824506300061498'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/late-night-thoughts-and-connecting-to.html' title='Late night thoughts and Connecting to MySql on a Remote Machine'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6814332945106588912</id><published>2009-03-04T01:05:00.000-05:00</published><updated>2009-03-04T01:05:31.859-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="documentation"/><title type='text'>Starting the Thesis Document</title><content type='html'>My intention is to reuse&amp;nbsp; most of my &lt;a href=&quot;http://docs.google.com/View?docid=dfn4hjr3_162g78332gv&quot;&gt;thesis proposal document&lt;/a&gt; in my final thesis document. It is yet unclear if that is an option and I&#39;m not totally clear on the best way to frame this project for the thesis document.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
My understanding to date is that this document is intended to describe the problem, the solution, the value of the solution and any inovative and/or cool thinkgs I came up with or learned during the project.&lt;br /&gt;
&lt;br /&gt;
My first step is to create a thesis outline and my thesis advisor has suggested writing 3documents to help me frame what I&#39;m talking about. &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;http://docs.google.com/Doc?id=dfn4hjr3_231gr73twfq&quot;&gt;The top 5 benefits to the student - inovations or challenges overcome in the project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.google.com/View?docid=dfn4hjr3_232gqdc4kg8&quot;&gt;The top 5 benefits to the end users&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A new 1 page summary of the project.&lt;/li&gt;
&lt;/ol&gt;The first two documents are completed.&amp;nbsp; I started with them because they were the most straight forward and I&#39;m struggling to find a way to describe this project that differs from my original &lt;a href=&quot;http://docs.google.com/View?docid=dfn4hjr3_162g78332gv&quot;&gt;thesis proposal&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
My goal is to have the outline and 1 page summary completed by tomorrow.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6814332945106588912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6814332945106588912' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6814332945106588912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6814332945106588912'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/starting-thesis-document.html' title='Starting the Thesis Document'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-510003720871023958</id><published>2009-03-04T00:55:00.000-05:00</published><updated>2009-03-04T00:55:47.800-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>Development Complete!</title><content type='html'>Thesis Development completed last night at ~10:30pm. I was too tired and relieved to write about it at the time. The code has been deployed on VMs and is currenly running with copies of production projects (a.k.a sites).&lt;br /&gt;
&lt;br /&gt;
I except to make some minimal changes as I test the project over the next two weeks. Most of them will be CSS related.&lt;br /&gt;
&lt;br /&gt;
The focus of the thesis project now shifts to writing the thesis document. The entire project and thesis document is due April 1st. That is not a joke.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/510003720871023958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/510003720871023958' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/510003720871023958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/510003720871023958'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/03/development-complete.html' title='Development Complete!'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-8283682757160918456</id><published>2009-02-25T22:32:00.000-05:00</published><updated>2009-02-25T22:32:55.124-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><title type='text'>Success!</title><content type='html'>Tonight it was time to take the controller and generators for a spin and see if this thing was going to work in real life. Once the &lt;a href=&quot;http://thesisdev.blogspot.com/2009/02/install-instructions.html&quot;&gt;install&lt;/a&gt; was complete:&lt;br /&gt;
&lt;br /&gt;
I fired up the controller...&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;ruby /usr/local/enotify/controller/script/server start&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;
And kicked off a generator on a separate machine..&lt;br /&gt;
&lt;blockquote&gt;&lt;tt&gt;cd /usr/local/enotify/generator&lt;br /&gt;
&lt;br /&gt;
perl ./bin/enotify.pl&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;
The generator called out to the Controller and asked for a site to generate, the Controller responded with a site. The generator generated the site, checking in and updating the controller on it&#39;s progress.&lt;br /&gt;
&lt;br /&gt;
When it finished the site was available through the controller web server!&lt;br /&gt;
&lt;br /&gt;
&lt;tt&gt;http://enotify-controller/sites/faq/output/website/index.html&lt;/tt&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;color: lime; font-size: x-large;&quot;&gt;&lt;b&gt;SUCCESS!!!&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: black; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;color: black; text-align: left;&quot;&gt;The hard part of the development is DONE!!! The dev tasks that remain are:&lt;/div&gt;&lt;div style=&quot;color: black; text-align: left;&quot;&gt;&lt;ul&gt;&lt;li&gt; adding the controller scheduler logic (basically translating this from the legacy system)&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;adding the replacement graphing code (all JS based and prototyped)&lt;/li&gt;
&lt;li&gt;Admin UI CSS for cleaning up the look and feel &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;ldap integration for creating owner lists. &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;testing &lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div style=&quot;color: black; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;color: black; text-align: left;&quot;&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/8283682757160918456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/8283682757160918456' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/8283682757160918456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/8283682757160918456'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/success.html' title='Success!'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-97739748737262042</id><published>2009-02-25T22:12:00.003-05:00</published><updated>2009-02-25T22:21:30.658-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="config"/><category scheme="http://www.blogger.com/atom/ns#" term="install"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><category scheme="http://www.blogger.com/atom/ns#" term="nfs"/><title type='text'>Install Instructions</title><content type='html'>I installed the project on virtual machines today.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;The machines used&lt;/span&gt;&lt;br /&gt;
&lt;table border=&quot;2&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;machine name&lt;/th&gt;&lt;th&gt;description&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;enotify-controller&lt;/td&gt;&lt;td&gt;This is the controller! rails administration installed here&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;enotify-gen-01&lt;/td&gt;&lt;td&gt;generated site storage and generator code stored here and shared via nfs. generator 1 chron task runs here&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;enotify-gen-02&lt;/td&gt;&lt;td&gt;mounts enotify-gen-01/generator &amp;amp; sites and has a chron task that runs the generator from that machine. &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
Once the controller and first generator are set up with nfs all future generators need nothing but to mount the generator code in gen-01 and run the generator. The controller takes care of the rest!!! So bringing new generators online means nothing more than finding a linux machine, mounting the gen-01 generator nfs mount and calling&lt;br /&gt;
&lt;br /&gt;
&lt;tt&gt;/urs/local/enotify/generator/bin/enotify.pl --remote --gen --update&lt;/tt&gt;&lt;br /&gt;
&lt;br /&gt;
I&#39;ve updated enotify.pl to use a new package called &lt;tt&gt;Enotify::Generator::ControllerCommunicator&lt;/tt&gt; &lt;a href=&quot;http://thesisdev.blogspot.com/2009/02/generator-controller-communication.html&quot;&gt;described here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
So the change to the legacy generator was literally the addition of about 15 lines. A new option --remote to tell the generator to call the controller, and the calls to &lt;tt&gt;ControllerCommunicator&lt;/tt&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following are the install instructions for this setup. There&#39;s no reason to read this unless you&#39;re trying to reproduce it. I took notes while I set up the controller and generators. Here&#39;s exactly what I did to install them:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;The Generator&lt;/span&gt;&lt;br /&gt;
Copy a legacy generator (existing code and libraries) to &lt;tt&gt;enotify-gen-01:/usr/local/enotify/generator&lt;/tt&gt;  such that you end up with &lt;tt&gt;/usr/local/enotify/generator/bin/enotify.pl&lt;/tt&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;The Controller&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;Installing RUBY on the controller&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6.tar.gz&lt;br /&gt;
tar -xzvf ruby-1.8.6.tar.gz&lt;br /&gt;
cd ruby-1.8.6&lt;br /&gt;
./configure&lt;br /&gt;
make &lt;br /&gt;
make install&lt;br /&gt;
&lt;br /&gt;
ruby is installed to /usr/local/bin/ruby&lt;br /&gt;
* don&#39;t believe the rubyonrail.org website, there are bugs between rails 2.0.2 and ruby 1.8.7. You need 1.8.6 for this to work. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;INSTALLING RUBY GEMS&lt;/b&gt;&lt;br /&gt;
wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz&lt;br /&gt;
tar -xzvf rubygems-1.3.1.tgz&lt;br /&gt;
cd rubygems-1.3.1&lt;br /&gt;
chmod 755 setup.rb&lt;br /&gt;
ruby setup.rb&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;INSTALLING RAILS &lt;/b&gt;&lt;br /&gt;
gem install rails -v=2.0.2&lt;br /&gt;
&lt;br /&gt;
# mongrel didn&#39;t get installed, so I installed it&lt;br /&gt;
sudo gem install mongrel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;INSTALLING THE CONTROLLER RAILS APP&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
#copy the controller code over to enotify-controller into /urs/local/enotify/controller&lt;br /&gt;
&lt;br /&gt;
#copy the legacy site directories you want to import into &lt;br /&gt;
mkdir /usr/local/enotify/site_to_import&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;INSTALLING MYSQL&lt;/b&gt;&lt;br /&gt;
# the server&lt;br /&gt;
wget http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-server-community-5.1.31-0.rhel4.i386.rpm/from/http://mysql.mirrors.pair.com/&lt;br /&gt;
&lt;br /&gt;
rpm -ivh MySQL-server-community-5.1.31-0.rhel4.i386.rpm&lt;br /&gt;
&lt;br /&gt;
# the client&lt;br /&gt;
wget http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-client-community-5.1.31-0.rhel4.i386.rpm/from/http://mysql.mirrors.pair.com/&lt;br /&gt;
&lt;br /&gt;
rpm -ivh MySQL-client-community-5.1.31-0.rhel4.i386.rpm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#In order to get a remote MYSQL Administrator to be able to connect&lt;br /&gt;
mysql -u root mysql&lt;br /&gt;
grant all privileges on *.* to &#39;root&#39;@&#39;&lt;insert_your_ip_address_here&gt;&#39;;&lt;br /&gt;
&lt;br /&gt;
# now you can connect as the root user from your pc&lt;br /&gt;
&amp;nbsp;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;Create a new DB User match username and password to rails/controller/config/database.yml&lt;br /&gt;
right click on the user and set the user to be able to connect from localhost&lt;br /&gt;
&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;CREATE THE RAILS DBs&lt;/b&gt;&lt;br /&gt;
Under Catalogs Choose &quot;Create New Schema&quot;&lt;br /&gt;
Create a new schema for&lt;br /&gt;
&lt;br /&gt;
thesisedev_development&lt;br /&gt;
thesisedev_test&lt;br /&gt;
thesisedev_production&lt;br /&gt;
&lt;br /&gt;
# Give the new user privileges&lt;br /&gt;
Under users click on the new user and choose the schema privileges tab.&lt;br /&gt;
For each thesis_dev schema add all privileges for this user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;NFS Shares and Mounts&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SETUP THE NFS SHARES&lt;/b&gt;&lt;br /&gt;
On enotify-gen-01:/etc/exports add&lt;br /&gt;
/usr/local/enotify/generator    enotify*.flubber.com(rw,no_root_squash)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;b&gt;SETUP THE NFS MOUNT&lt;/b&gt;&lt;br /&gt;
On the controller and every other generator add this to /etc/fstab&lt;br /&gt;
enotify-gen-01:/usr/local/enotify/generator /usr/local/enotify/generat&lt;br /&gt;
or      nfs     defaults        0 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;CONTROLLER DIRECTORIES&lt;/b&gt;&lt;br /&gt;
/usr/local/enotify/controller  = rails app&lt;br /&gt;
/usr/local/enotify/site_to_import  = sites that will be imported into the &lt;br /&gt;
controller when you run &lt;br /&gt;
controller/script/import/p&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DATA STORE DIRECTORIES&lt;/b&gt;&lt;br /&gt;
/usr/local/enotify/generator  = enotify generator code and sites.&lt;br /&gt;
&lt;br /&gt;
the sites directory is [insert_your_ip_address_here]/usr/local/enotify/generator/sites because this is where the legacy generators expect to find it.&lt;br /&gt;
&lt;insert_your_ip_address_here&gt; &lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
Making generated sites available from the controller&lt;/span&gt;&lt;br /&gt;
make a symbolic link that puts the sites directory under the controller public director. This lets rails serve up the static generated files.&amp;nbsp;&lt;/insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;tt&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;insert_your_ip_address_here&gt;ln -s /usr/local/enotify/controller/public/sites &lt;/insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt; /usr/local/enotify/generator/sites&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;insert_your_ip_address_here&gt;&lt;/tt&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;DB Schema and Legacy Site Import&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#Set up the schema:&lt;br /&gt;
rake db:migrate&lt;br /&gt;
# migrate in the new data&lt;br /&gt;
./p&lt;br /&gt;
&lt;br /&gt;
# start the server&lt;br /&gt;
ruby script/server start&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;/insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;insert_your_ip_address_here&gt;&lt;br /&gt;
&lt;/insert_your_ip_address_here&gt;&lt;/insert_your_ip_address_here&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/97739748737262042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/97739748737262042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/97739748737262042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/97739748737262042'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/install-instructions.html' title='Install Instructions'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6604994249681902071</id><published>2009-02-24T01:58:00.000-05:00</published><updated>2009-02-24T01:58:44.948-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="activemq"/><category scheme="http://www.blogger.com/atom/ns#" term="messaging"/><title type='text'>Generator Controller Communication</title><content type='html'>In my last post I mentioned that I took ActiveMQ out of the project and settled on web services for communicating between the Generators an the controller, but I left out how the communication would work.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I settled on a very simple model. Generators are responsible for asking for work and attempting to update the controller with generation status. The Controller is responsible for doling out work, tracking progress, error management and and dealing with rogue generators.&lt;br /&gt;
&lt;br /&gt;
Rogue generators aren&#39;t likely given their stability over the last 5 years, but if they were to go bad they would do things like:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Ask for a site to generate. Not complete generating the site.&amp;nbsp; Ask for another site to generate.&lt;/li&gt;
&lt;li&gt;Fail to report a status update for generating a site. &lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;In these cases, the controller has the error checking capabilities to clean up the generation data as much as possible and either tell the generator to do nothing, re-render a site, or render a new site.&lt;br /&gt;
&lt;br /&gt;
The Perl Doc for the &lt;a href=&quot;http://code.google.com/p/thesisdev/source/browse/trunk/controller/test/perl/Enotify/Generator/ControllerCommunicator.pm&quot;&gt;module used by the generator to communicate with the controller&lt;/a&gt; is probably the best way to understand how this works. &lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;=head1 Enotify::Generator::ControllerCommunicator&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; This package enables communication with the enotify controller &lt;br /&gt;
&amp;nbsp; web application.&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&amp;nbsp; The functionality in this package supports the communication model&lt;br /&gt;
&amp;nbsp; where the generator ALWAYS initiates contact with the Controller.&lt;br /&gt;
&amp;nbsp; The process flow is as follows&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&amp;nbsp; 1) a cron task kicks off the generator&lt;br /&gt;
&amp;nbsp; 2) the generator asks the controller what work to do&lt;br /&gt;
&amp;nbsp; 3) the controller responds with the name of a project&lt;br /&gt;
&amp;nbsp; 4) the generator generates the site &amp;amp; sends status messages&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; to the controller during the update process&lt;br /&gt;
&amp;nbsp; 5) the generator finishes the site update, notifies the controller and exits&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
the cron tab is on a 2 minute retry, with logic to keep multiple generators from starting. so step 1 will happen at most 2 minutes after step 5 completes&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; What does the controller do with the status updates.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; The controller uses these status updates to record the progress of the generator in the Generation object. Each status message corresponds to a column in the generation table. The Controller records the current time in that columns when it recieves a status&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; message.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Status updates are simply messages saying the generator is starting or ending some part of the site generation. For example:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_BUG_LIST_DOWNLOAD_START means the generator is about to start downloading&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; the sites bug lists and GENERATION_BUG_LIST_DOWNLOAD_END means the generator finished&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; downloading those bug lists.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Complete list of status messages&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_START&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_END&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_BUG_LIST_DOWNLOAD_START&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_BUG_LIST_DOWNLOAD_END&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_PAGES_START&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_PAGES_END&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_GRAPHS_START&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_GRAPHS_END &lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; The controller identifies all requests based on the IP address of the &lt;br /&gt;
&amp;nbsp;&amp;nbsp; generator which is automatically passed with every call. &lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; Deployment Requirement: &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Because it is technally possible for a DHCP generator to change it&#39;s IP &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; address while running a site, the enterprise deployment of this mechanism &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requires generators with Static IP addresses.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp; Example use:&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $controller_comunicator = Enotify::Generator::ControllerCommunicator::new();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $site_name = $controller_comunicator-&amp;gt;get_site_to_generate()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; print &quot;Site Name &quot; . $site_name;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt;Site Name foo&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $controller_comunicator-&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
=cut&lt;/div&gt;&lt;div style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;br /&gt;
=head2 ControllerCommunicator-&amp;gt;get_site_to_generate() {{{&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Purpose: This method requests a new site to generate from the&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;controller.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Expects: Nothing. Seriously, it is the controllers responcibility&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; to deal with generators that go crazy or ask for this &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; info multiple times.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Returns: (STRING) The short name of the site that is being updated. This&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; is also the last directory in the path to the &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; directory for the site.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print &quot;enotify/sites/&quot; . $controller_comunicator-&amp;gt;get_site_to_generate()&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; enotif/sites/foo&lt;br /&gt;
=cut&lt;/div&gt;&lt;div style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&lt;/div&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;=head2 ControllerCommunicator-&amp;gt;update_generation_progress() {{{&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Purpose: This method sends a status update to the controller.&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Valid Status messages:&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_START&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_END&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_BUG_LIST_DOWNLOAD_START&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_BUG_LIST_DOWNLOAD_END&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_PAGES_START&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_PAGES_END&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_GRAPHS_START&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GENERATION_RENDERING_GRAPHS_END&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Expects: The name of the update to send.&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Returns: (BOOLEAN) True if the update succeeded. False if there was a server error.&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print&amp;nbsp; $controller_comunicator-&amp;gt;get_site_to_generate(GENERATION_START)&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;gt; 1&lt;/span&gt;&lt;br style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot; /&gt;&lt;span style=&quot;color: #274e13; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;=cut&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6604994249681902071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6604994249681902071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6604994249681902071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6604994249681902071'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/generator-controller-communication.html' title='Generator Controller Communication'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-5703667161075180341</id><published>2009-02-21T01:54:00.000-05:00</published><updated>2009-02-21T01:54:07.968-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="activemq"/><category scheme="http://www.blogger.com/atom/ns#" term="config"/><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><category scheme="http://www.blogger.com/atom/ns#" term="messaging"/><category scheme="http://www.blogger.com/atom/ns#" term="rails convention"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><category scheme="http://www.blogger.com/atom/ns#" term="status"/><title type='text'>Development Status Update</title><content type='html'>The blog has been quiet because I&#39;m going flat out on development with a goal of finishing on March 1st.&lt;br /&gt;
&lt;br /&gt;
The following is a quick brain dump of my progress. No promises on spelling here. It&#39;s 1:30am on a Friday after a particularly long week.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Active MQ is Gone:&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;I&#39;ve eliminated ActiveMQ and replaced it with basic web service calls from the generators.&amp;nbsp; REST wasn&#39;t in rails the last time I developed a full app. I like what they&#39;ve done with the 2.0. It has a decidedly CRUD feel all the way through.&lt;br /&gt;
&lt;br /&gt;
The switch from AMQ to REST greatly simplified communications mechanism and got around a limitation in the way the rails plug-in for AMQ handles, or rather doesn&#39;t handle temporary queues.&lt;br /&gt;
&lt;br /&gt;
I&#39;ll post the communication message call flow as soon as I&#39;m done testing it (see generator perl below).&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;UI Update / Schema&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Most of the admin UI is built. I used Active Scaffold. It took a while, but I figured out how to organize the UI work flow so that it worked around Active Scaffold limitations.&lt;br /&gt;
&lt;br /&gt;
This did require a change to the schema, but it&#39;s a really good change. I was previously keeping team information in the owners table.&lt;br /&gt;
&lt;br /&gt;
The &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Owners&lt;/span&gt; table had the columns &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;project_id, person_id, manager_id&lt;/span&gt;. The applicaiton logic stated that if &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;person_id == manager_id&lt;/span&gt; then that person was the manager of the team.&lt;br /&gt;
&lt;br /&gt;
I found myself writing a lot of code to deal with this logical relationship and when I tried to make it work with active scaffold it really started to hurt. So I changed the schema.&lt;br /&gt;
&lt;br /&gt;
Now there is a &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Team&lt;/span&gt; table:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;class CreateTeams &amp;lt; ActiveRecord::Migration&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp; def self.up&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; create_table :teams do |t|&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.integer :project_id&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.integer :person_id&lt;/span&gt; (this is the manager)&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.timestamps&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And the &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;Owners&lt;/span&gt; Table now looks like this:&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;class CreateOwners &amp;lt; ActiveRecord::Migration&lt;br /&gt;
&amp;nbsp; def self.up&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; create_table :owners do |t|&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.integer :team_id&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.integer :person_id&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.timestamps&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp; end&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;I deleted a tun of code and acivescaffold just works!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;Convetion&amp;nbsp; over configuration every time!!!&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt; &lt;/span&gt;&lt;br /&gt;
&lt;b&gt;Giving Active Scaffold a Push - Dynamic action_links&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
For the sake of UI consistency I did make one hack on top of Active Scaffold. I needed a link at the top of the table that had a dynamic value in it. On the teams table I wanted a link to add a new team and I needed to pass the current project ID. That requires a fair rewrite of the way active scaffold passes parameters when creating action links. &lt;br /&gt;
&lt;br /&gt;
Instead of doing it the hard way I just replaced the links by modifying the resulting pages DOM with some JavaScript. &lt;a href=&quot;http://code.google.com/p/thesisdev/source/browse/trunk/controller/app/views/teams/for_project.html.erb&quot;&gt;http://code.google.com/p/thesisdev/source/browse/trunk/controller/app/views/teams/for_project.html.erb &lt;/a&gt;&lt;b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;CGI::Session::CookieStore::CookieOverflow&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;span style=&quot;font-size: small;&quot;&gt;Every project has a bug that just scares the crap out of me. Getting 500 server errors because of a Cookie overflow was that bug for me. It happened at random on certain pages. It turned out to be the way I was using Active Scaffold.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;I was rendering with this line&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;:active_scaffold =&amp;gt; &#39;teams&#39;,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;:constraints =&amp;gt; {:project_id =&amp;gt; @project}&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;Apparently Active Scaffold stores constrains in the session object. So after refreshing a few times and the leaving and returing to this page BOOOOOMM!!! All that project info was stored in the cookie and it overflowed its 4k limit.&lt;br /&gt;
&lt;br /&gt;
The fix was simple. Just change &lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;@project to @project.id&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt; so the new code is&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;:active_scaffold =&amp;gt; &#39;teams&#39;,&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: small;&quot;&gt;:constraints =&amp;gt; {:project_id =&amp;gt; @project.id}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;And that get&#39;s rid of the cookie overflows.&lt;/span&gt;&lt;b&gt; &lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Active Scaffold Sortable is a lie!&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
There&#39;s this amazing &lt;a href=&quot;http://tim.theenchanter.com/2008/05/activescaffoldsortable-updated-with.html&quot;&gt;screencast&lt;/a&gt; showing a rails plugin that allows you to drag and drop records to reorder them. When I install the plugin I can&#39;t even get the server to start. I&#39;ve tried every permutation of rails/active_scaffold version I can think of, posted emails on forums and even emailed the developer.&amp;nbsp; Result = silence.&lt;br /&gt;
&lt;br /&gt;
Based on the other forum posts it appears the code worked for a brief window when stars aligned and no one touched the active_scaffold code base. That time passed, and no one tagged the source tree, so it is lost forever.&amp;nbsp; Sadly I&#39;m giving up on sortable, and will&lt;b&gt; &lt;/b&gt;have to figure out some other way to order bug lists and table column headers. &lt;b&gt;&lt;br /&gt;
&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Generator Perl:&lt;/span&gt;&lt;br /&gt;
&lt;/b&gt;The perl package that enables the generator to talk to the controller via REST is written.&amp;nbsp; Testing with the controller commences tomorrow.&lt;br /&gt;
&lt;br /&gt;
I still have to integrate this with the generator, but I had a look through the generator logic and it&#39;s all neatly contained in a single well documented script. [Thank you me from 5 years ago!]&amp;nbsp; Once the controller is tested I&#39;ll be able to drop the communication package in, and add/edit a few simple lines, to make the controller the master of the generators workload.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Deployment:&lt;/span&gt;&lt;br /&gt;
&lt;/b&gt;Three Red Hat Linux Virtual Machines should be available early next week so I can test the system in a truly distributed fashion.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;What&#39;s Left in Development:&lt;/span&gt;&lt;/b&gt; &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Error checking logic for adding teams, owners and administrators&lt;/li&gt;
&lt;li&gt;Changing the generator to listen to the controller &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Controller / generator integration &lt;/li&gt;
&lt;li&gt;Controller UI for generators and generations&lt;/li&gt;
&lt;li&gt;Cloning Projects, Bug_Lists and Teams&lt;/li&gt;
&lt;li&gt;Lots of testing &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Deployment to the test bed&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
Once it&#39;s deployed I&#39;m going to start writing my paper. The applicaion will have 3 weeks of real life soak time while I&#39;m writing.&lt;br /&gt;
&lt;br /&gt;
While I don&#39;t plan to deploy it in production before I finish the thesis, it should be very obvious if there are any problems with the system.&amp;nbsp;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/5703667161075180341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/5703667161075180341' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/5703667161075180341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/5703667161075180341'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/development-status-update.html' title='Development Status Update'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-7069281091097750147</id><published>2009-02-09T23:14:00.003-05:00</published><updated>2009-02-09T23:23:26.709-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="activemq"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><title type='text'>Active MQ and the mysterious XTools</title><content type='html'>Tonight was a night of minor frustrations.  Working on my thesis was postponed by my daughter who decided bed time should be moved to 9:30pm. She&#39;s very cute, but I can&#39;t work on my thesis when she&#39;s around because she insists on my reading her books. If I try to develop while reading to her I end of with variable names like Bert and Ernie.&lt;br /&gt;&lt;br /&gt;Once she went to sleep:&lt;br /&gt;&lt;br /&gt;I installed ActiveMQ version 5.2&lt;br /&gt;&lt;ol&gt;&lt;li&gt;download&lt;/li&gt;&lt;li&gt;untar&lt;/li&gt;&lt;li&gt;cd [AMQ install director]/bin&lt;/li&gt;&lt;li&gt;chmod 755 activemq&lt;/li&gt;&lt;li&gt;cd ..&lt;/li&gt;&lt;li&gt;bin/activemq&lt;/li&gt;&lt;/ol&gt;And it just works.... It even has a web admin running at &lt;a href=&quot;http://localhost:8161/admin/&quot;&gt;http://localhost:8161/admin/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then I tried to get a simple perl script to connect via Net::Stomp.&lt;br /&gt;&lt;br /&gt;I tried to install Net::Stomp from using &lt;tt&gt;sudo -H cpan -i Net::Stomp&lt;/tt&gt; and it failed because &lt;tt&gt;make&lt;/tt&gt; was missing from my machine.&lt;br /&gt;&lt;br /&gt;For the next hour my brain didn&#39;t function as I search google for a way to install make on OS X. The search terms &quot;install make on OS X&quot; are not helpful...&lt;br /&gt;&lt;br /&gt;Eventually I found and was simultaneously directed to Apples XTools. Duh... I should have looked on apple&#39;s site first.&lt;br /&gt;&lt;br /&gt;I&#39;ve now downloaded the svelte 1GB XTools installer, but I&#39;m to tired to actually run it. That&#39;s a task for tomorrow.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/7069281091097750147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/7069281091097750147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/7069281091097750147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/7069281091097750147'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/active-mq-and-mysterious-xtools.html' title='Active MQ and the mysterious XTools'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6308540997744857163</id><published>2009-02-07T22:43:00.002-05:00</published><updated>2009-02-07T22:45:57.789-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><category scheme="http://www.blogger.com/atom/ns#" term="status"/><title type='text'>22 Days of Development Left</title><content type='html'>My thesis is due April 1st. That means the running code and thesis paper which is likely to run about 75 pages have to be done.&lt;br /&gt;&lt;br /&gt;I&#39;m giving myself till March 1st to finish the code...&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-lGtL-7typcOqf8wgJMH66yFuTsTe95OFgytcX9ef29KVU9ciu71gGHwXHI460spFRdCpbsSPcDUslDRg_DZ4bDdzTFra8CHkWxTJHziyLRmvsPCtzplEiexeH1fZhNSzkASQ1DNdR4XT/s1600-h/Picture+2.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 64px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-lGtL-7typcOqf8wgJMH66yFuTsTe95OFgytcX9ef29KVU9ciu71gGHwXHI460spFRdCpbsSPcDUslDRg_DZ4bDdzTFra8CHkWxTJHziyLRmvsPCtzplEiexeH1fZhNSzkASQ1DNdR4XT/s200/Picture+2.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5300267593014092994&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;And then it&#39;s on to the paper...</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6308540997744857163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6308540997744857163' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6308540997744857163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6308540997744857163'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/22-days-of-development-left.html' title='22 Days of Development Left'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-lGtL-7typcOqf8wgJMH66yFuTsTe95OFgytcX9ef29KVU9ciu71gGHwXHI460spFRdCpbsSPcDUslDRg_DZ4bDdzTFra8CHkWxTJHziyLRmvsPCtzplEiexeH1fZhNSzkASQ1DNdR4XT/s72-c/Picture+2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6365636681998049007</id><published>2009-02-07T21:58:00.008-05:00</published><updated>2009-02-07T22:39:05.364-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="config"/><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="graphing"/><category scheme="http://www.blogger.com/atom/ns#" term="import"/><category scheme="http://www.blogger.com/atom/ns#" term="postponed"/><category scheme="http://www.blogger.com/atom/ns#" term="status"/><title type='text'>Lots of progress</title><content type='html'>Since the last time I wrote about actual feature development a lot has happened.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-size:130%;&quot; &gt;application_id is no more&lt;/span&gt;&lt;br /&gt;Per my &lt;a href=&quot;http://thesisdev.blogspot.com/2009/01/rails-convention-and-my-silly.html&quot;&gt;previous post&lt;/a&gt; on application_ids I decided to get rid of them. They are now gone. That means updates to&lt;br /&gt;&lt;ul&gt;&lt;li&gt;migrations (removed all the application_id&lt;br /&gt;&lt;/li&gt;&lt;li&gt;model relationships (has_many and belongs_to are not straight forward)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;the legacy importer now looks up IDs and assigns them instead of using the application_id&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Fixtures&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;I&#39;d been using &lt;tt&gt;test/fixtures&lt;/tt&gt; via &lt;tt&gt;rake db:fixtures:load&lt;/tt&gt; to import some baseline data and constants into the dev and production DB.  Once I started writing tests this didn&#39;t make sense anymore because the test fixtures were clobbering the production DB.&lt;br /&gt;&lt;br /&gt;So I created a &lt;tt&gt;db/fixtures&lt;/tt&gt; directory and told the migrations to load those fixtures. Now the baseline data is imported into the DB when I run &lt;tt&gt;rake db:migrate:reset&lt;/tt&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Communication with the Generator&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;As I thought though the communication from the controller to the generator I realized that I was going to have to rewrite the generator property loaders in order to read whatever format I wrote the site properties in from the controller.&lt;br /&gt;&lt;br /&gt;Dreading that task I had a thought. Why not just have the controller render the site properties and other generator config data in the exact format the generator was expecting. So I did.&lt;br /&gt;&lt;br /&gt;Taking it one step further I realized there was no reason to send this info over ActiveMQ. Since the controller and all the generators are connected to the same file share, I simply told the controller where the site directory was and then had it write the property files needed by the generator.&lt;br /&gt;&lt;br /&gt;Arguably, this is going full circle. I just did all this work to import all that information out of the legacy files and into the DB, and now I&#39;m taking it out of the DB and putting it back into the files!&lt;br /&gt;&lt;br /&gt;But the benefit is a rapid development and test environment. It&#39;s trivial to bring the existing generator up and running since the site directory looks EXACTLY the way the generator expects. This allows me to focus on the main goal of the project. Centralizing control of the application and generation scheduling in the controller.&lt;br /&gt;&lt;br /&gt;At this point the controller knows how to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a site directory from scratch&lt;/li&gt;&lt;li&gt;publish site_properties.xml&lt;/li&gt;&lt;li&gt;publish queries.xml&lt;/li&gt;&lt;li&gt;publish the owner lists&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt; The upshot of this dev work is it forced me to build all the relationships between most of the Models in order to be able to generate the content of those files.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Skipping Projections&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;I did NOT publish projections yet. Graph generation is one of the few parts of the generate I&#39;m changing. I&#39;ll likely dynamically generate projections from the controller so they are always up to date. I&#39;m leaving projections until I tackel the graphing part.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-size:130%;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;thesis.next&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;It&#39;s time to get ActiveMQ up and running for communications between the controller and generators.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6365636681998049007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6365636681998049007' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6365636681998049007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6365636681998049007'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/lots-of-progress.html' title='Lots of progress'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-8378294598641071098</id><published>2009-02-07T10:11:00.002-05:00</published><updated>2009-02-07T10:19:13.894-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><title type='text'>Textmate +Mac = no time to write</title><content type='html'>Using Textmate, I find myself with no down time when I develop. With Apenta and Ruby on Windows I frequently found myself with entire minutes where my IDE or scripts were unresponsive...  During those times I made updates to this blog.&lt;br /&gt;&lt;br /&gt;With my new environment MAC + TextMate, there is no down time. As a result I have a big backlog of updates. Topics include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Changes to the communication workflow&lt;/li&gt;&lt;li&gt;Rendering generator understandable XML from the controller&lt;/li&gt;&lt;li&gt;Unit Testing&lt;/li&gt;&lt;li&gt;Separating test and production migration fixtures&lt;/li&gt;&lt;li&gt;Setting up the table relationships in the models&lt;/li&gt;&lt;li&gt;Deployment environment progress update&lt;/li&gt;&lt;/ul&gt;Details coming soon. Right now TextMate is calling...</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/8378294598641071098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/8378294598641071098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/8378294598641071098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/8378294598641071098'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/textmate-mac-no-time-to-write.html' title='Textmate +Mac = no time to write'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-5230883537965528085</id><published>2009-02-01T23:42:00.004-05:00</published><updated>2009-02-02T00:02:32.959-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><title type='text'>Switching to a Mac</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLuPd5iEc3DBSW-Hj5t63VRH7wp6gRqtdLrdONW-wLqV2uPFwR1G6wYWT1orW4l6i-pugESREiPkGxY8t5nQpppB9CQDUw4oW2ICjdRSuNxCNI3Q8xjKT5ydIikzMlUZCeyDgD9VVqOHwj/s1600-h/RailsApple.jpg&quot;&gt;&lt;img style=&quot;margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 107px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLuPd5iEc3DBSW-Hj5t63VRH7wp6gRqtdLrdONW-wLqV2uPFwR1G6wYWT1orW4l6i-pugESREiPkGxY8t5nQpppB9CQDUw4oW2ICjdRSuNxCNI3Q8xjKT5ydIikzMlUZCeyDgD9VVqOHwj/s200/RailsApple.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5298059699227299858&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;I&#39;ve been developing with RoR -v=2.02 on my winxp laptop and I&#39;m running a scripts very frequently.&lt;br /&gt;&lt;br /&gt;rake &lt;span style=&quot;font-family:courier new;&quot;&gt;db:migrate:reset&lt;/span&gt; and &lt;span style=&quot;font-family:courier new;&quot;&gt;ruby script/runner script/import/project.rb&lt;/span&gt; and most importantly &lt;span style=&quot;font-family:courier new;&quot;&gt;rake test:units&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Running these commands is slow.&lt;br /&gt;&lt;br /&gt;Painfully slow.&lt;br /&gt;&lt;br /&gt;So slow so that I took out a watch and timed it.&lt;br /&gt;&lt;br /&gt;It takes 29 seconds for the environment to spin up and then between 1 and 3 seconds to run the actual scripts. You can tell because the first thing most of these scripts do after requiring the framework is printing to standard out. But nothing prints for 29 seconds!!!&lt;br /&gt;&lt;br /&gt;So that is 29 seconds of nothing and then a flash of my program running. It got really tedious so I decided to investigate. I started with 2 premises:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The average developer would probably not put up with this and still say Rails was cool&lt;/li&gt;&lt;li&gt;I don&#39;t remember Rails being like this when I developed on linux.&lt;/li&gt;&lt;/ol&gt;Google showed me a pile of web pages where people were complaining about rails scripts being slow. They all had one thing in common... They were running windows.&lt;br /&gt;&lt;br /&gt;So I decided to burn an hour and try out my project on my wife&#39;s Mackbook Pro. And the scripts scream. That 29 second delay is eliminated.  And the added bonus is, TextMate is very slick and does not spike the CPU the way Aptana Studio does when I say, click on a tab.&lt;br /&gt;&lt;br /&gt;So I&#39;m switching to my wife&#39;s mac. I&#39;m assuming she&#39;ll like this because it means I&#39;ll finish my thesis about 3 years faster.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/5230883537965528085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/5230883537965528085' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/5230883537965528085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/5230883537965528085'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/02/switching-to-mac.html' title='Switching to a Mac'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLuPd5iEc3DBSW-Hj5t63VRH7wp6gRqtdLrdONW-wLqV2uPFwR1G6wYWT1orW4l6i-pugESREiPkGxY8t5nQpppB9CQDUw4oW2ICjdRSuNxCNI3Q8xjKT5ydIikzMlUZCeyDgD9VVqOHwj/s72-c/RailsApple.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-3363544307902004900</id><published>2009-01-31T07:48:00.003-05:00</published><updated>2009-01-31T08:17:33.726-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="config"/><category scheme="http://www.blogger.com/atom/ns#" term="rails convention"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><title type='text'>Rails Convention and my silly application_id</title><content type='html'>When I designed the schema a few of the tables were basically there to store constants. I thought it would be a good idea to add an &lt;tt&gt;application_id&lt;/tt&gt; column because it would allow me to explicitly set the value of that column.&lt;br /&gt;&lt;br /&gt;So I added an int column to &lt;tt&gt;site_update_frequencies, bug_tool_urls, bug_columns&lt;/tt&gt;, and a few other tables.  I used fixtures to set the values of the &lt;tt&gt;application_id&lt;/tt&gt; for each of these fields as incrementing, but consistent integers.&lt;br /&gt;&lt;br /&gt;For example the row with &lt;tt&gt;site_update_frequency.name = Daily&lt;/tt&gt; always has &lt;tt&gt;site_update_frequency.application_id = 2&lt;/tt&gt; no matter how many times I reset the DB. The &lt;tt&gt;site_update_frequency.id&lt;/tt&gt; field changes with each import.&lt;br /&gt;&lt;br /&gt;The idea was that I would tell project model, which has a foreign key to &lt;tt&gt;site_update_frequency&lt;/tt&gt;, to look at &lt;tt&gt;site_update_frequency.application_id&lt;/tt&gt; instead of &lt;tt&gt;site_update_frequency.id&lt;/tt&gt; and then I&#39;d be able to call.&lt;br /&gt;&lt;br /&gt;In the project model a little &lt;tt&gt;belongs_to :site_update_frequency&lt;/tt&gt; magic and when I call &lt;tt&gt;project.site_update_frequency.name&lt;/tt&gt; in the rails code I should get the name of the site update frequency.&lt;br /&gt;&lt;br /&gt;But I forgot that Rails was going link the objects together through the &lt;tt&gt;id&lt;/tt&gt; field of &lt;tt&gt;site_update_frequency&lt;/tt&gt;. So I spent an hour wondering why &lt;tt&gt;project.site_update_frequency == nil&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Now I know it&#39;s because the project is linked to &lt;tt&gt;site_update_frequency&lt;/tt&gt; through the &lt;tt&gt;id&lt;/tt&gt; column which has values kn the 10k range instead of the &lt;tt&gt;application_id&lt;/tt&gt; which has them in the 1-3 range. I&#39;m using the value of the wrong Foreign Key!!!&lt;br /&gt;&lt;br /&gt;SMACKS FOREHEAD.... Duh.&lt;br /&gt;&lt;br /&gt;I looked around for how to tell rails to link the tables through the &lt;tt&gt;application_id&lt;/tt&gt; and I have a few ideas, but after sleeping on it I started asking a different questions.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Q: Why am I trying to use configuration over convention with Rails?&lt;br /&gt;A: &quot;Ummmm I don&#39;t know.&quot;&lt;br /&gt;&lt;br /&gt;Q: Didn&#39;t I choose Rails because of the simplicity of its convention?&lt;br /&gt;A: &quot;Sure did!&quot;&lt;br /&gt;&lt;br /&gt;Q: And what does the &lt;tt&gt;application_id&lt;/tt&gt; give me?&lt;br /&gt;A: &quot;Not sure... The ability to behave in a sloth-like manner?&quot;&lt;/blockquote&gt;&lt;br /&gt;So I&#39;ve decided to get rid of the &lt;tt&gt;application_id&lt;/tt&gt; columns and simply rely on the rails standard &lt;tt&gt;id&lt;/tt&gt; columns.&lt;br /&gt;&lt;br /&gt;Mostly because &lt;tt&gt;application_id&lt;/tt&gt; seems to serve no purpose other than giving me a headache.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/3363544307902004900/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/3363544307902004900' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/3363544307902004900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/3363544307902004900'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/rails-convention-and-my-silly.html' title='Rails Convention and my silly application_id'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-3273337829128357651</id><published>2009-01-17T23:33:00.002-05:00</published><updated>2009-01-17T23:42:39.248-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="import"/><category scheme="http://www.blogger.com/atom/ns#" term="milestone"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><title type='text'>The Final Import Script COMPLETE!!! Ownership Changes</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtbDxBREhvLcyqrDKQrXE6FN9bBnWLY0cJM9iMQ-G7n9aXWeWxctdpPRGRLBT57qjzjHOBmu4YRUqIRj4i_b1ubEjeWqmsNHbAmowYTQEHQfApqBnSkCaVphm2NRttBLwQUVtusr_njc4s/s1600-h/happy_l.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtbDxBREhvLcyqrDKQrXE6FN9bBnWLY0cJM9iMQ-G7n9aXWeWxctdpPRGRLBT57qjzjHOBmu4YRUqIRj4i_b1ubEjeWqmsNHbAmowYTQEHQfApqBnSkCaVphm2NRttBLwQUVtusr_njc4s/s200/happy_l.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;There was a lot of persuading, but the import of&amp;nbsp; the legacy data is finally done!&lt;br /&gt;
&lt;br /&gt;
The final legacy data import task is to migrate all the bug_ownership_changes. The entire point of this application is that it applies ownership models to lists of bugs so that you know exactly who owns a bug (should be doing something about that bug). Ownership tends to change throughout the life-cycle of a bug.&lt;br /&gt;
&lt;br /&gt;
There are some edge cases but basically ownership works like this: When a bug is logged it&#39;s owned by a manager who needs to assign it. Once assigned it&#39;s owned by the engineer to whom it&#39;s been assigned. Once it&#39;s fixed it&#39;s owned by the person that submitted it because they need to verify the engineer that fixed it isn&#39;t (and this is a technical term) full-of-crap.&lt;br /&gt;
&lt;br /&gt;
Every once in a while someone comes up with a reason to violate the sanctity of the default ownership model behavior. They decide that the submitter shouldn&#39;t be the person to verify the full-of-crap-ness of the engineer, because they are on vacation, and they want to make someone else the owner of the bug.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I would have given my kingdom for a bug system that lets you save arbitrary data, but it was not to be. And so, in order to support the unfortunate, despicable, and some have claimed immoral practice of ownership changes, the legacy application is forced to store ownership change information.&lt;br /&gt;
&lt;br /&gt;
Apparently I forgot about this in my original schema, because there was no hint of a table for this information. Alas, it was easy to add and I have. The table looks like this&lt;br /&gt;
&lt;br /&gt;
Table: &lt;b&gt;&lt;tt&gt;bug_ownership_changes&lt;/tt&gt;&lt;/b&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;b&gt;&lt;tt&gt;bug_list_id&lt;/tt&gt;&lt;/b&gt; (integer): A foreign key to the &lt;tt&gt;id&lt;/tt&gt; for the the bug list to which this change should be applied.&lt;br /&gt;
&lt;b&gt;&lt;tt&gt;bugid&lt;/tt&gt;&lt;/b&gt; (string): This is the actual Bug ID, and not an ID from our schema. &lt;br /&gt;
&lt;b&gt;&lt;tt&gt;new_owner_id&lt;/tt&gt;&lt;/b&gt; (integer): This is the poor sap that has had the responsibility of dealing with this bug dumped on him/her.&lt;br /&gt;
&lt;b&gt;&lt;tt&gt;assigner_id&lt;/tt&gt;&lt;/b&gt; (integer): This is the person that unceremoniously dumped the bug in someone else&#39;s lap. I&#39;ve added this column because I may decided to embark on a campaign to publicly shame these people at some point in the future, and I want to make sure I have the data handy. :) &lt;/blockquote&gt;Here&#39;s the updated schema:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUywTd0lM7T6R1B2L8YSpXnOKVx4CnrzQ9esKsKbKVPzzSP1fhMdPahIN19gVhCf8U3z87TMGblIGrygQxbQ_i6u1f3VIR1t5I6O2IUg2JPypA8lH9ydJJVw1V4v4cNKR5CojvIBq1XO87/s1600-h/L.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUywTd0lM7T6R1B2L8YSpXnOKVx4CnrzQ9esKsKbKVPzzSP1fhMdPahIN19gVhCf8U3z87TMGblIGrygQxbQ_i6u1f3VIR1t5I6O2IUg2JPypA8lH9ydJJVw1V4v4cNKR5CojvIBq1XO87/s320/L.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
And with that and a little ruby scripting the final import is ready to go!&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;tt&gt;rake db:migrate:reset&lt;/tt&gt; &lt;tt&gt; &lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;rake db:fixtures:load&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;script/runner script/import/project.rb&lt;/tt&gt;&lt;/blockquote&gt;&lt;br /&gt;
The script ran. The data is in the DB. I&#39;m done with basic legacy data importing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: medium; font-weight: bold;&quot;&gt;What&#39;s Next&lt;/span&gt;?&lt;br /&gt;
Next step is to work out the communication between the controller and the generator. In other words, figure out how to take all the information I just stuck in the DB and send it back to the generator in a way the generator can understand it.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/3273337829128357651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/3273337829128357651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/3273337829128357651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/3273337829128357651'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/final-import-script-complete-ownership.html' title='The Final Import Script COMPLETE!!! Ownership Changes'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtbDxBREhvLcyqrDKQrXE6FN9bBnWLY0cJM9iMQ-G7n9aXWeWxctdpPRGRLBT57qjzjHOBmu4YRUqIRj4i_b1ubEjeWqmsNHbAmowYTQEHQfApqBnSkCaVphm2NRttBLwQUVtusr_njc4s/s72-c/happy_l.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-2696642932904318455</id><published>2009-01-14T20:59:00.009-05:00</published><updated>2009-01-14T21:43:37.386-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="graphing"/><category scheme="http://www.blogger.com/atom/ns#" term="import"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><title type='text'>Too many rows for history!</title><content type='html'>&lt;div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGfQCd_7RsRlkPNfbsorlcvBPeM5_P25_8FiuEs-QTLX4OrHn2JXQGSEi7U5jw-Re1ILZsQfruoYO9Ovsh-y4oMb5NqyEQ2Gc6Q4H6p07LEgIO3hx0cjp9FbfNhIe9QzCR7ovVx3DLRMu6/s1600-h/carl_sagan.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGfQCd_7RsRlkPNfbsorlcvBPeM5_P25_8FiuEs-QTLX4OrHn2JXQGSEi7U5jw-Re1ILZsQfruoYO9Ovsh-y4oMb5NqyEQ2Gc6Q4H6p07LEgIO3hx0cjp9FbfNhIe9QzCR7ovVx3DLRMu6/s200/carl_sagan.jpg&quot; /&gt;&lt;/a&gt;In the legacy system &quot;&lt;tt&gt; Histories&lt;/tt&gt;&quot; are used to store the bug count for the cross section of each owner, buglist and project each time the site is generated. This information is used in historical reporting to show how a person&#39;s, team&#39;s, or project&#39;s bug count for a given bug list has changed over time.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;I sat down to write the DB import code for bug count histories tonight and noticed I didn&#39;t have a table for it. Suspicious...&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;So I looked at my old notes and discovered a calcuation I did a while back to figure out the number of rows I&#39;d need in my DB.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;The Math&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Assuming 100 active sites/projects &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;tt&gt;&lt;/tt&gt;&lt;br /&gt;
&lt;tt&gt;&lt;blockquote&gt;(active project_people ~ 30,000) * (active bug lists ~ 1000) * (1 year of active data ~365 days) == 10,950,000,000 (Time to call Carl Sagan)&lt;/blockquote&gt;&lt;/tt&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
I did a few quick searches and &lt;a href=&quot;http://www.astahost.com/info.php/what-maximum-capacity-astahost-mysql-database_t14221.html&quot;&gt;found&lt;/a&gt; &lt;a href=&quot;http://www.phpbuilder.com/board/archive/index.php/t-612789.html&quot;&gt;answers&lt;/a&gt; suggesting there was no theoretical limit to DB size as long as you have a nudlear powered CPU, infinate memory and a heat sink liquid cooled by the nothern Atlantic ocean. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;BUT... They all talk about things in terms of millions of rows and keeping individual tables under 500 million rows to keep from encouraging Loki (god of fire and trickery) from laying waste to their application.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Additional review of my calculations shows:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;th&gt;row count&lt;/th&gt;&lt;th&gt;% of DB&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Sum of  all rows except bug counts:&lt;/td&gt;&lt;td&gt;428,058&lt;/td&gt;&lt;td&gt;0.003909%&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Sum of History Rows for 1 year:&lt;/td&gt;&lt;td&gt;10,950,000,000&lt;/td&gt;&lt;td&gt;99.9960909%&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;/center&gt;&lt;/div&gt;&lt;div&gt;The purpose of the Central Controller was to have a central point for site management. Not to act as a historical data repository that will&amp;nbsp;someday&amp;nbsp;rival amazon.com&#39;s.&lt;br /&gt;
&lt;br /&gt;
OK that&#39;s an&amp;nbsp;exaggeration, but it&amp;nbsp;occurs&amp;nbsp;to me that if I store histories in the DB I&#39;m leaving a ticking time bomb for whoever takes over the app. First it the central controller will start to slow down and about a 1.5 years after we deploy it will either crash the server or heat it up so hot that it will melt a hole through the outer mantle of the planet.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Either way, I&#39;m not doing anyone any favors writing this import code.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;The Solution&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-size: 18px;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;span style=&quot;font-size: 18px;&quot;&gt;&lt;b&gt;Given:&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Histories have only one purpose, graphing historical bug counts. &lt;/li&gt;
&lt;li&gt;I&#39;m planning on replacing the graphing tools using a javascript based graphing tool&lt;/li&gt;
&lt;li&gt;That graphing tool is going to want historical data in Javascript&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;b&gt;I&#39;m going to:&lt;/b&gt; &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Not import histories into the DB. Instead I&#39;ll store the historical data in JSON as flat files on the web server with the other generated site content. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;To do that I need to:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Figure out the best Object Notation for the graphing tool I&#39;m going to use.&lt;/li&gt;
&lt;li&gt;Write a one time script that writes converts the existing historical data into JSON files &lt;/li&gt;
&lt;li&gt;Teach the generator how to read and re-render those files each time it runs. &lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;So I&#39;m moving the histories import mechanism into the next phase when I work on the generator. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/2696642932904318455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/2696642932904318455' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/2696642932904318455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/2696642932904318455'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/too-many-rows-for-history.html' title='Too many rows for history!'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGfQCd_7RsRlkPNfbsorlcvBPeM5_P25_8FiuEs-QTLX4OrHn2JXQGSEi7U5jw-Re1ILZsQfruoYO9Ovsh-y4oMb5NqyEQ2Gc6Q4H6p07LEgIO3hx0cjp9FbfNhIe9QzCR7ovVx3DLRMu6/s72-c/carl_sagan.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-1476420402323057551</id><published>2009-01-11T00:11:00.002-05:00</published><updated>2009-01-11T00:37:43.502-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="catch-22"/><category scheme="http://www.blogger.com/atom/ns#" term="import"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><title type='text'>Projections... Done</title><content type='html'>I took friday night off, and tackled projections today. They are working, though I&#39;m getting a taste of how intertwined this data is... I mistakenly tried to import the projections after resetting the DB only to discover there were no projects or people to use as foreign keys.&lt;br /&gt;
&lt;br /&gt;
All the same, it&#39;s working! &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;What&#39;s Next&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;strike&gt;site projections from &lt;tt&gt;legacy\sites\[sitename]\output\projections\&lt;/tt&gt;&lt;/strike&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;bug list histories &lt;tt&gt;legacy\sites\[sitename]\output\history&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Ownership changes &lt;tt&gt;legacy\sites\[sitename]\output\ownership_change&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Another minor, but convoluted, schema change...&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
projections.project_person was simply a mistake. The column is there as a way to tie an expected bug count for a given date to a team.&amp;nbsp; The ideal way to deal with this concept is to have a &lt;tt&gt;Team&lt;/tt&gt; model. But I don&#39;t have one. In the legacy system &lt;tt&gt;Teams&lt;/tt&gt; are infered by grouping all the people that have the same manager. And projections were always tied to that manager. &lt;br /&gt;
&lt;br /&gt;
So the real relationship I want doesn&#39;t exist. I played with the idea of creating a &lt;tt&gt;Team&lt;/tt&gt; model, but per the legacy system, it serves only one purpose, that being something to tie the projections to. &lt;br /&gt;
&lt;br /&gt;
So I decided to skip creating a &lt;tt&gt;team&lt;/tt&gt; and go with something less &quot;right&quot; but more practical.  That gives me two choices&lt;br /&gt;
&lt;br /&gt;
1. &lt;tt&gt;Owners&lt;/tt&gt; This is the Model that links &lt;tt&gt;People&lt;/tt&gt; to their managers and to projects. (This is the model that project_persons turned into in a latter stage of the schema.)&lt;br /&gt;
&lt;br /&gt;
2. &lt;tt&gt;People&lt;/tt&gt; This is where people&#39;s username and full name are stored. A persson is connected to a &lt;tt&gt;Project&lt;/tt&gt; via the &lt;tt&gt;owners&lt;/tt&gt; table. &lt;br /&gt;
&lt;br /&gt;
So the most right way of these two practical (but technically incorrect) choices is to link to the &lt;tt&gt;Onwer&lt;/tt&gt;, but most of the time I&#39;m going to want to look up projections based on a &lt;tt&gt;manager_id&lt;/tt&gt; anyway, so it seems silly to store the &lt;tt&gt;Owner.id&lt;/tt&gt; just to have to use it to get the managers &lt;tt&gt;person.id&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
If you followed that you, I&#39;m very impressed.&lt;br /&gt;
&lt;br /&gt;
Needless to say, I decided to change &lt;tt&gt;projection.project_person&lt;/tt&gt; to &lt;tt&gt;projection.person_id&lt;/tt&gt; because that is what I&#39;m going to want to know when looking up projections. &lt;br /&gt;
&lt;br /&gt;
Here&#39;s the updated schema:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR0qw6nvNyIaoLVoE6bF_JaPEU4_JzVWitQT5XvxtHAvLH-I-HxQWnCyLWhTJ63GECR77AxwQ8mkbLwwVnXyzPj_oLZQ4FkGKC8wcBL0b3PiJftJbEq-7bATUez_WoL3hLJ8mmPy-LBn0Z/s1600-h/L.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR0qw6nvNyIaoLVoE6bF_JaPEU4_JzVWitQT5XvxtHAvLH-I-HxQWnCyLWhTJ63GECR77AxwQ8mkbLwwVnXyzPj_oLZQ4FkGKC8wcBL0b3PiJftJbEq-7bATUez_WoL3hLJ8mmPy-LBn0Z/s320/L.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;The Catch:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Because I elected not to create a &lt;tt&gt;Team&lt;/tt&gt; model that means that projections still reside with a person (the manager) instead of a team. That means when the manager of a team changes, I need to make sure to go through the projections and update them. It&#39;s a small price to pay for something that rarely happens and will make life easier the other 99.9% of the time.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/1476420402323057551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/1476420402323057551' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/1476420402323057551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/1476420402323057551'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/projections-done.html' title='Projections... Done'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR0qw6nvNyIaoLVoE6bF_JaPEU4_JzVWitQT5XvxtHAvLH-I-HxQWnCyLWhTJ63GECR77AxwQ8mkbLwwVnXyzPj_oLZQ4FkGKC8wcBL0b3PiJftJbEq-7bATUez_WoL3hLJ8mmPy-LBn0Z/s72-c/L.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-3880436486191038020</id><published>2009-01-08T23:28:00.005-05:00</published><updated>2009-01-08T23:58:16.340-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="import"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><title type='text'>Queries &amp;&amp; People &amp;&amp; Teams...  All Importing!</title><content type='html'>Queries, People and their relationships to managers and projects are all importing!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Queries&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
My decision to go to bed last night was a good one. The bug was as I suspected a silly one. I was calling &lt;tt&gt;element.elements[&#39;display-name&#39;].get_text&lt;/tt&gt; and there is no &lt;tt&gt;get_text&lt;/tt&gt; method... It&#39;s just &lt;tt&gt;text&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
In order to get queries working required another schema update. I changed &lt;tt&gt;bug_lists.expert_query&lt;/tt&gt; and &lt;tt&gt;bug_lists.description&lt;/tt&gt; to be of type :binary which is MySql equivalent of a &lt;tt&gt;blob&lt;/tt&gt;. The legacy data for those fields was to big for a column type &lt;tt&gt;string&lt;/tt&gt;.&lt;br /&gt;
&lt;br /&gt;
So here, once again is the updated schema:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggc1WwlSspt7oMSIVS_L33sOx3vrcxMP6j6Qe2F8eqL6QOePjz_lP-XQU_xqtvjXhszb1j_ceIdmV20021tGP8cvDK7Byo2oIeXeK4rYB3MdGYsp6m1hUSBLWyBg9OZ2rU5InfSnTCwZXH/s1600-h/L.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggc1WwlSspt7oMSIVS_L33sOx3vrcxMP6j6Qe2F8eqL6QOePjz_lP-XQU_xqtvjXhszb1j_ceIdmV20021tGP8cvDK7Byo2oIeXeK4rYB3MdGYsp6m1hUSBLWyBg9OZ2rU5InfSnTCwZXH/s320/L.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;People &amp;amp; Relationships&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Once that was working, I imported all the ownership files. That creates the person objects for everyone in the system and ties them to projects and their managers. &lt;br /&gt;
&lt;br /&gt;
I actually stumbled on code I wrote back in July when I was in upstate NY and didn&#39;y have an internet connection. It mostly worked but it was all brite force code. I did things like manually reading and parsing CSV files instead of using &lt;tt&gt;CSV::Reader.parse&lt;/tt&gt; and checking the DB for an existing user and creating one manually if they didnt exist instead of using &lt;tt&gt;Person.find_or_create_by_username&lt;/tt&gt;. So I just rewrote it tonight using a lot less code. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;What&#39;s Next&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
I&#39;m dangerously close to finishing the data migration. There are only three things left to import:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;site projections from &lt;tt&gt;legacy\sites\[sitename]\output\projections\&lt;/tt&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;bug list histories &lt;tt&gt;legacy\sites\[sitename]\output\history&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Ownership changes &lt;tt&gt;legacy\sites\[sitename]\output\ownership_change&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;I plan to tackle them all tomorrow night. Then its on to getting the legacy system talking to the new controller.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/3880436486191038020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/3880436486191038020' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/3880436486191038020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/3880436486191038020'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/queries-people-teams-all-importing.html' title='Queries &amp;&amp; People &amp;&amp; Teams...  All Importing!'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggc1WwlSspt7oMSIVS_L33sOx3vrcxMP6j6Qe2F8eqL6QOePjz_lP-XQU_xqtvjXhszb1j_ceIdmV20021tGP8cvDK7Byo2oIeXeK4rYB3MdGYsp6m1hUSBLWyBg9OZ2rU5InfSnTCwZXH/s72-c/L.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-6752877995015209348</id><published>2009-01-08T00:22:00.001-05:00</published><updated>2009-01-08T00:34:11.695-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="db"/><category scheme="http://www.blogger.com/atom/ns#" term="import"/><category scheme="http://www.blogger.com/atom/ns#" term="schema"/><title type='text'>Queries are almost importing...</title><content type='html'>Tonight we went out to dinner. On the way home the roads froze and it took u 40 minutes to get our car 20 feet up our street. We live on a steep hill.&lt;br /&gt;
&lt;br /&gt;
Once that was done and everyone was in bed I got queries importing for every project.&lt;br /&gt;
&lt;br /&gt;
This required some schema changes:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I added a scope filter table to store the constants data about scope filters&lt;/li&gt;
&lt;li&gt;In the bug_lists table scope_filter (string) was changed to scope_filter(integer) so it could be a foreign key to the scope_filters table.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;I added ownership_models.legacy_name (string) which gives me a way to reference the internal name the by which the legacy&amp;nbsp;generators&amp;nbsp;know the ownership models.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Once again &lt;tt&gt;rake db:migrate:reset&lt;/tt&gt; and &lt;tt&gt;rake db:fixtures:load&lt;/tt&gt; are my friends.&lt;br /&gt;
&lt;br /&gt;
The updated schema looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggL8CIPmC0a3Oa7AoO-h6CNfop-Ju3gMMWSt_DIgjmCTKqDMUn7-FcXnhbIv3U9Fn15Wa8CcakNjKXux2aFn19S_mGKwKjhi5HBPAmLhb7mfLYzduuxAb_V1OVBdryCQcz8UUJXH5t2YOF/s1600-h/L3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggL8CIPmC0a3Oa7AoO-h6CNfop-Ju3gMMWSt_DIgjmCTKqDMUn7-FcXnhbIv3U9Fn15Wa8CcakNjKXux2aFn19S_mGKwKjhi5HBPAmLhb7mfLYzduuxAb_V1OVBdryCQcz8UUJXH5t2YOF/s320/L3.jpg&quot; width=&quot;314&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Alas, queries are not properly importing yet. There&#39;s bug thesis_importer.rb in the code that parses display-name out of the legacy XML. It&#39;s probably very easy to fix, but it&#39;s also 12:22 AM and my eyes aren&#39;t focusing very well, so victory will have to wait till tomorrow night.</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/6752877995015209348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/6752877995015209348' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6752877995015209348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/6752877995015209348'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/queries-are-almost-importing.html' title='Queries are almost importing...'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggL8CIPmC0a3Oa7AoO-h6CNfop-Ju3gMMWSt_DIgjmCTKqDMUn7-FcXnhbIv3U9Fn15Wa8CcakNjKXux2aFn19S_mGKwKjhi5HBPAmLhb7mfLYzduuxAb_V1OVBdryCQcz8UUJXH5t2YOF/s72-c/L3.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8315047248038686888.post-2763168739128240126</id><published>2009-01-07T23:50:00.000-05:00</published><updated>2009-01-07T23:58:38.268-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="aptana"/><category scheme="http://www.blogger.com/atom/ns#" term="logistics"/><title type='text'>The Aptana Saga Continues</title><content type='html'>The developers over at Aptana are on the ball. They&#39;ve been looking into the bugs I logged &lt;a href=&quot;http://support.aptana.com/asap/browse/ROR-1097&quot;&gt;ROR-1097&lt;/a&gt; and &lt;a href=&quot;http://support.aptana.com/asap/browse/ROR-1098&quot;&gt;ROR-1098&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So far they haven&#39;t found the thing that&#39;s causing the CPU to spike on startup and when I mistakenly click on the Rake Tasks tab. But I&#39;m getting by. When the bug hits I just take a coffee break.&lt;br /&gt;&lt;br /&gt;I was having trouble being specific about the bug behavior since it manifests for 6 minutes and most of the time the behavior is spiked CPU and nothing else. So today while I was in a meeting and my PC was idol, I fired up Camtasia and made a screen recording of the bug.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: rgb(204, 0, 0); font-weight: bold; &quot;&gt;Warning! This is really boring to watch.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;center&gt;&lt;object width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/TPSIz5j2KNU&amp;amp;hl=en&amp;amp;fs=1&quot;&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;embed src=&quot;http://www.youtube.com/v/TPSIz5j2KNU&amp;amp;hl=en&amp;amp;fs=1&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;</content><link rel='replies' type='application/atom+xml' href='http://thesisdev.blogspot.com/feeds/2763168739128240126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/8315047248038686888/2763168739128240126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/2763168739128240126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8315047248038686888/posts/default/2763168739128240126'/><link rel='alternate' type='text/html' href='http://thesisdev.blogspot.com/2009/01/aptana-saga-continues.html' title='The Aptana Saga Continues'/><author><name>Russelldad</name><uri>http://www.blogger.com/profile/07287265380093689972</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>