<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Programming Gems (on GemStone)</title>
	<atom:link href="http://programminggems.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://programminggems.wordpress.com</link>
	<description>James's comments on programming GemStone/S, Seaside, and Smalltalk</description>
	<lastBuildDate>Fri, 27 Jan 2012 15:57:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='programminggems.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Programming Gems (on GemStone)</title>
		<link>http://programminggems.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://programminggems.wordpress.com/osd.xml" title="Programming Gems (on GemStone)" />
	<atom:link rel='hub' href='http://programminggems.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Creating a Private Cloud</title>
		<link>http://programminggems.wordpress.com/2012/01/26/creating-a-private-cloud/</link>
		<comments>http://programminggems.wordpress.com/2012/01/26/creating-a-private-cloud/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 22:09:42 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=823</guid>
		<description><![CDATA[In the previous post, I described how to use the vmc command-line tools to deploy a Ruby application to VMware&#8217;s cloud. In this post I will describe the steps I took to create and use a private cloud (based on the instructions found on github). If you have an account with Cloud Foundry, you can [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=823&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the previous <a href="http://programminggems.wordpress.com/2012/01/25/getting-started-with-cloud-foundry/">post</a>, I described how to use the vmc command-line tools to deploy a Ruby application to VMware&#8217;s cloud. In this post I will describe the steps I took to create and use a private cloud (based on the instructions found <a href="https://github.com/cloudfoundry/vcap">on github</a>). If you have an account with Cloud Foundry, you can download a pre-built <a href="https://my.cloudfoundry.com/micro">Micro Cloud Foundry</a>, but by following these instructions you will have an environment similar to what I used in this project.</p>
<h3>Creating a Micro Cloud Foundry</h3>
<p>On a clean MacBook Pro running Snow Leopard (10.6.8), I  downloaded an <a href="http://www.ubuntu.com/start-download?distro=server&amp;bits=64&amp;release=lts">ISO</a> to install 64-bit Ubuntu Server 10.4.3, then I installed VMware <a href="http://www.vmware.com/products/fusion/overview.html">Fusion</a> 4.1.1. I launched Fusion and started the process to create a new virtual machine:</p>
<ul>
<li>Introduction: I clicked the &#8220;continue without disk&#8221; button.</li>
<li>Installation Media: I chose the disk image for Ubuntu Server.</li>
<li>Operating System: I left the defaults of Linux and Ubuntu 64-bit.</li>
<li>Linux Easy Install: I accepted the default user and specified a password (&#8216;swordfish&#8217;).</li>
<li>Tools Download: I downloaded the tools.</li>
<li>Finish: I accepted the defaults (1 GB RAM, 20 GB hard disk, NAT networking).</li>
<li>Save As: I named the virtual machine &#8216;My Cloud&#8217;.</li>
<li>A few minutes later the server started and gave a login prompt.</li>
</ul>
<p>It seems that Fusion&#8217;s easy install of Ubuntu does not get the keyboard properly mapped, so I entered the following command:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">sudo dpkg-reconfigure console-setup</span></pre>
<p>I selected the &#8216;Dell 101-key PC&#8217; keyboard (pressing the &lt;D&gt; key repeatedly since the arrow keys didn&#8217;t work), and accepted the other default settings. I then entered the following commands (based in part on the instructions <a href="https://github.com/cloudfoundry/vcap">here</a>) to update and install a few needed packages:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">sudo apt-get update</span>
<span style="color:#800000;">sudo apt-get upgrade</span>
<span style="color:#800000;">sudo apt-get install vim</span>
<span style="color:#800000;">sudo apt-get install openssh-server</span>
<span style="color:#800000;">sudo apt-get install curl</span></pre>
<p>Next, I entered the command to setup this Ubuntu server as a VMware Cloud Application Platform (VCAP):</p>
<pre style="padding-left:30px;"><span style="color:#800000;">bash &lt; &lt;(curl -s -k -B \</span>
<span style="color:#800000;"> https://raw.github.com/cloudfoundry/vcap/master/dev_setup/bin/vcap_dev_setup)</span></pre>
<p>This process took some time (an hour?) and when it finished it showed a message describing how to start Cloud Foundry:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">~/cloudfoundry/vcap/dev_setup/bin/vcap_dev start</span></pre>
<p>We now have the confusion of dealing with two machines (one real and one virtual) and so need to be careful to identify which one we mean in the subsequent instructions:</p>
<ul>
<li><strong>Client</strong>: A MacBook Pro is my development machine, and a &#8220;client&#8221; with respect to &#8220;the cloud.&#8221; For this project, I interact with the client primarily using Terminal (using &#8220;a shell on the client&#8221;), but also using a web browser (Safari, Firefox, or Chrome) and the Finder.</li>
<li><strong>Server</strong>: VMware Cloud Application Platform (VCAP) runs on 64-bit Ubuntu in a Fusion virtual machine on the Mac, and provides &#8220;the cloud services&#8221; on a &#8220;Micro Cloud.&#8221; I interact with the server primarily using ssh in a Terminal session (&#8220;a shell on the server&#8221;), but occasionally using the console visible in Fusion. This micro cloud offers the same developer experience that a public cloud (such as <a href="http://appfog.com/">appfog.com</a>) should provide, so you can practice your deployment without making your application public.</li>
</ul>
<p>In order to interact with the server using ssh in a Terminal session, we need to know the server&#8217;s IP address. On the server console, I entered the following command:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">ifconfig eth0 | grep inet</span></pre>
<p>The first line gives the IPv4 address (in my case, 192.168.10.128). On the client, I then entered the following command:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">sudo vim /etc/hosts</span></pre>
<p>to edit the client&#8217;s hosts file and add the following line:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">192.168.10.128   mycloud</span></pre>
<p>You should, of course, use the IP address you got from the server. Then, from a client shell, I entered the following to get a shell on the server:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">ssh mycloud</span></pre>
<p>I entered &#8216;yes&#8217; to add the RSA key and then entered the password I defined when I built the server (&#8216;swordfish&#8217;). To simplify my server commands, I added an alias using the following commands on the server:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">echo "alias vcap='~/cloudfoundry/vcap/dev_setup/bin/vcap_dev \$1'" &gt;&gt; ~/.bashrc</span>
<span style="color:#800000;">source ~/.bashrc</span></pre>
<p>On the server, I entered the following command:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">vcap start</span></pre>
<p>This gave me some debugging information, and ended with a list of services that all show as &#8220;RUNNING.&#8221;</p>
<h3>Targeting the Micro Cloud</h3>
<p>From the client we interact with a cloud using vmc, the command-line interface in a client shell. When we were using the public cloud, the &#8220;target&#8221; was api.cloudfoundry.com; with the micro cloud we use api.vcap.me as the target. VMware has registered the domain vcap.me and configured the DNS servers to map that domain (and all its subdomains) to 127.0.0.1 (or localhost). Of course, the micro cloud is not at 127.0.0.1 from the perspective of the client, so we need to establish a tunnel from port 80 on the client to port 80 on the server. First, we need to ensure that port 80 is not in use. On my Mac, I opened System Preferences, selected Sharing, and then made sure that &#8216;Web Sharing&#8217; is unchecked. With port 80 available, I entered the following command in a client shell (replacing USER with the Ubuntu user defined during the initial setup):</p>
<pre style="padding-left:30px;"><span style="color:#800000;">sudo ssh -L 80:mycloud:80 USER@mycloud -N</span></pre>
<p>This command establishes a tunnel from port 80 on the client to port 80 on the server, and the shell hangs until the tunnel is terminated (e.g., with &lt;Ctrl&gt;+&lt;C&gt;). To show that the cloud is there and responding, I entered <a href="http://api.vcap.me/info">http://api.vcap.me/info</a> in a client web browser and observed the JSON data returned. In another client shell, I entered the following vmc commands (you should provide your own email!):</p>
<pre style="padding-left:30px;"><span style="color:#800000;">vmc target api.vcap.me</span>
<span style="color:#800000;">vmc info</span>
<span style="color:#800000;">vmc add-user --email jfoster@vmware.com --passwd swordfish</span>
<span style="color:#800000;">vmc info</span></pre>
<p>With the micro cloud up and running, I tried deploying my trivial Ruby application (described <a href="http://programminggems.wordpress.com/2012/01/25/getting-started-with-cloud-foundry/">here</a>) using the following client commands:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">cd ~/env</span>
<span style="color:#800000;">vmc push</span></pre>
<p>In response to the questions, I named the application &#8216;jfoster-env&#8217; and asked for 2 instances; otherwise I accepted the defaults. At this point (see notes below) I was able to see the application in a web browser at <a href="http://jfoster-env.vcap.me/">http://jfoster-env.vcap.me/</a> and <a href="http://jfoster-env.vcap.me/env">http://jfoster-env.vcap.me/env</a> and I tried the various vmc commands at the end of <a href="http://programminggems.wordpress.com/2012/01/25/getting-started-with-cloud-foundry/">this</a> post. The behavior was generally consistent with the public cloud.</p>
<p style="padding-left:30px;">Note 1: The first time I tried a push the response was &#8220;Error: Application [jfoster-env] failed to start, logs information below. Error 306: Error retrieving file &#8216;/logs/err.log.&#8221; I believe that this means that the application failed to start <em>in time</em>, and that when the system went to look for an error log, there wasn&#8217;t one. The application actually was running and responded to HTTP requests. Also, &#8216;vmc apps&#8217; and &#8216;vmc stats jfoster-env&#8217; showed the application running and &#8216;vmc restart jfoster-env&#8217; reported success.</p>
<p style="padding-left:30px;">Note 2: The response to &#8216;vmc logs jfoster-env&#8217; included &#8220;Error 306: Error retrieving file &#8216;logs/startup.log.&#8221; I found someone who <a href="http://support.cloudfoundry.com/entries/20298433-error-306-error-retrieving-file-logs-startup-log">said</a>, &#8220;The file &#8216;logs/startup.log&#8217; isn&#8217;t always generated, so the error returned by vmc can be a red herring.&#8221;</p>
<h3>Conclusion</h3>
<p>We have built an Ubuntu server and configured it as a private micro cloud. We used it as a target for our application and were able to use it in place of the public cloud. Next we will investigate adding a new runtime and framework to Cloud Foundry.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/823/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/823/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/823/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/823/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/823/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/823/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/823/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/823/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=823&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2012/01/26/creating-a-private-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Started with Cloud Foundry</title>
		<link>http://programminggems.wordpress.com/2012/01/25/getting-started-with-cloud-foundry/</link>
		<comments>http://programminggems.wordpress.com/2012/01/25/getting-started-with-cloud-foundry/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 01:31:35 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=820</guid>
		<description><![CDATA[As you may be aware, VMware&#8217;s Cloud Foundry is an open source &#8220;Platform as a Service&#8221; (PaaS) on which you can &#8220;deploy and scale your application in seconds.&#8221; In anticipation of my presentation at STIC 2012, I have been learning about Cloud Foundry and this blog post describes my initial steps, using material from cloudfoundry.com [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=820&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As you may be aware, VMware&#8217;s <a href="http://www.cloudfoundry.com/about">Cloud Foundry</a> is an open source &#8220;Platform as a Service&#8221; (PaaS) on which you can &#8220;deploy and scale your application in seconds.&#8221; In anticipation of my <a href="http://www.stic.st/conferences/stic12/stic12-abstracts/smalltalk-in-the-cloud/">presentation</a> at <a href="http://www.stic.st/conferences/stic12/">STIC 2012</a>, I have been learning about Cloud Foundry and this blog post describes my initial steps, using material from <a href="http://start.cloudfoundry.com/tools/vmc/installing-vmc.html">cloudfoundry.com</a> and from <a href="https://github.com/cloudfoundry/vcap">github.com</a>.</p>
<p>I started by <a href="https://my.cloudfoundry.com/signup">registering for an account</a> because I wanted to try deploying on VMware&#8217;s cloud (this step is not necessary for our later deployment on a private cloud). The confirmation email took several hours to come, and I&#8217;ve read of others who waited for days, so if you register don&#8217;t be surprised if it takes a while to hear back.</p>
<p>On a clean install of Snow Leopard (Mac 10.6), I started by creating a very simple <a href="http://www.sinatrarb.com/">Sinatra</a> application in Ruby. (Of course, the goal of this project is to deploy Smalltalk to the cloud, but we will start with things that Cloud Foundry understands, and go from there!) In a Terminal, I entered the following commands (providing my password when prompted):</p>
<pre style="padding-left:30px;"><span style="color:#800000;">sudo gem install mime-types</span>
<span style="color:#800000;">sudo gem install rubyzip</span>
<span style="color:#800000;">sudo gem install uuidtools</span>
<span style="color:#800000;">sudo gem install sinatra</span>
<span style="color:#800000;">mkdir env; cd env</span></pre>
<p>In ~/env/ I created a file, env.rb, consisting of the following text:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">require 'rubygems'</span>
<span style="color:#800000;">require 'sinatra'</span></pre>
<pre style="padding-left:30px;"><span style="color:#800000;">get '/' do</span>
<span style="color:#800000;">    host = ENV['VMC_APP_HOST']</span>
<span style="color:#800000;">    port = ENV['VMC_APP_PORT']</span>
<span style="color:#800000;">    "&lt;h1&gt;XXXXX Hello from the Cloud! via: #{host}:#{port}&lt;/h1&gt;"</span>
<span style="color:#800000;">end</span></pre>
<pre style="padding-left:30px;"><span style="color:#800000;">get '/env' do</span>
<span style="color:#800000;">    res = ''</span>
<span style="color:#800000;">    ENV.each do |k, v|</span>
<span style="color:#800000;">        res &lt;&lt; "#{k}: #{v}&lt;br/&gt;"</span>
<span style="color:#800000;">    end</span>
<span style="color:#800000;">    res</span>
<span style="color:#800000;">end</span></pre>
<p>Then, from the Terminal, I entered the following command:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">ruby env.rb</span></pre>
<p>This told me that Sinatra was running a web server on port 4567, so I opened a web browser on <a href="http://localhost:4567/env">http://localhost:4567/env</a> and verified that my application ran and returned the expected values. I used &lt;Ctrl&gt;+&lt;C&gt; in the Terminal to terminate the application.</p>
<p>The next task was to install the command-line tools (vmc) used to interact with Cloud Foundry. In the Terminal I entered the following command:</p>
<pre style="padding-left:30px;"></pre>
<pre style="padding-left:30px;"><span style="color:#800000;">sudo gem install vmc --pre</span></pre>
<p>The &#8216;&#8211;pre&#8217; option tells ruby to install the pre-release version of vmc. Next, I specified the target cloud for deployment, I logged in using the email address and the password I got when I registered (see above), and I pushed the application to the cloud:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">vmc target api.cloudfoundry.com</span>
<span style="color:#800000;">vmc login</span>
<span style="color:#800000;">vmc push</span></pre>
<p>The push command prompts a series of questions. I accepted the default (Y) to deploy from the current directory. I gave a unique name for the application (&#8216;jfoster-env&#8217;). I accepted the default to confirm that this is a Sinatra application and it can be deployed in 128M of RAM. I specified two (2) instances so I could see the application run on two machines. Finally, I accepted the default to confirm that I did not need any services and I did not need to save the configuration. The tools then proceeded to confirm that the application was pushed and started successfully. In a web browser, I went to the designated location, http://jfoster-env.cloudfoundry.com/, and found that my application was indeed running. I refreshed the page a few times and confirmed that the application was running on two machines (showing different internal IP addresses and ports).</p>
<p>I tried a number of commands to explore what was available through the vmc command-line tools:</p>
<pre style="padding-left:30px;"><span style="color:#800000;">vmc help</span>
<span style="color:#800000;">vmc user</span>
<span style="color:#800000;">vmc target</span>
<span style="color:#800000;">vmc info</span>
<span style="color:#800000;">vmc runtimes</span>
<span style="color:#800000;">vmc frameworks</span>
<span style="color:#800000;">vmc apps</span>
<span style="color:#800000;">vmc instances jfoster-env +2</span>
<span style="color:#800000;">vmc apps</span>
<span style="color:#800000;">vmc instances jfoster-env -2</span>
<span style="color:#800000;">vmc stats jfoster-env</span>
<span style="color:#800000;">vmc logs jfoster-env</span>
<span style="color:#800000;">vmc files jfoster-env</span>
<span style="color:#800000;">vmc files jfoster-env app</span>
<span style="color:#800000;">vmc files jfoster-env logs</span>
<span style="color:#800000;">vmc env jfoster-env</span>
<span style="color:#800000;">vmc stop jfoster-env</span>
<span style="color:#800000;">vmc apps</span>
<span style="color:#800000;">vmc delete jfoster-env</span>
<span style="color:#800000;">vmc apps</span>
<span style="color:#800000;">vmc logout</span></pre>
<p>In all of this, we have been interacting with the VMware public cloud. The next blog post will explore creating and using a private development cloud.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/820/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/820/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/820/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=820&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2012/01/25/getting-started-with-cloud-foundry/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Indexing for a Date Range</title>
		<link>http://programminggems.wordpress.com/2012/01/11/indexing-for-a-date-range/</link>
		<comments>http://programminggems.wordpress.com/2012/01/11/indexing-for-a-date-range/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 06:15:42 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=610</guid>
		<description><![CDATA[A recent discussion on the GLASS mailing list presented an interesting problem. Say you have a collection of domain model objects that each have a start date and an stop date, and you want to find all the objects that are within a date range. I was first exposed to this problem 25 years ago [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=610&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A recent <a href="http://forum.world.st/Solving-some-Garbage-Collection-issues-td4000484i20.html#a4278181" target="_blank">discussion</a> on the <a href="http://forum.world.st/GLASS-f1460844.html" target="_blank">GLASS mailing list</a> presented an interesting problem. Say you have a collection of domain model objects that each have a start date and an stop date, and you want to find all the objects that are within a date range. I was first exposed to this problem 25 years ago in a healthcare system tracking patient admit and discharge dates, but it applies to many common situations (from hotels to video or car rentals).</p>
<p>For this discussion we will consider the following example: from the collection of [A-H] we want to get the subset from begin to end, or [D-F].</p>
<p><a href="http://programminggems.files.wordpress.com/2012/01/screen-shot-2012-01-11-at-9-27-20-am.png"><img class="size-full wp-image" src="http://programminggems.files.wordpress.com/2012/01/screen-shot-2012-01-11-at-9-27-20-am.png?w=529" alt="Image" /></a></p>
<p>Of course, one could iterate over the entire collection and test each object, but this will be inefficient for large collections. At the other extreme would be to have an end-of-day job that create a collection for that date and add items to the day&#8217;s collection. This would give very quick lookup, but would have a cost in storage.</p>
<p>A typical attempt to solve this problem would be to create an index on the start date and the stop date and then build a result set of items that start before the end point and stop after the begin point. The problem with this approach is that it likely creates two intermediate results, [A-F] and [D-H], that together are larger than the original collection (before returning the intersection of those intermediate results). In GemStone, this can generally be done in such a way that the intermediate results hold the object IDs (or OOPs), but the objects are not actually read from disk. This is typically a good solution, but others are possible.</p>
<p>Decades ago my good friend, Carl Zimmerman, came up with another approach that uses one index and avoids the large intermediate results. The following is adapted from his design to work with GemStone&#8217;s indexing system.</p>
<p>Each object has an &#8216;indexableDateRange&#8217; instance variable (with an equality index defined) that encodes the duration (in days) and the start point (a Date after 1900) as a SmallInteger. The value is set as follows:</p>
<pre>  indexableDateRange := start isNil
    ifTrue: [0]
    ifFalse: [stop isNil
      ifTrue: [start asDays]
      ifFalse: [(stop subtractDate: start) + 1 * 100000 + start asDays]].</pre>
<p>Note a few things about this expression. If the value is zero, then the activity has not started. If the value is less than 100000, then the activity is ongoing. If the value is greater than 100000, then the activity has finished. Note that this design handles dates from 1901 to 2173. Handling dates outside that range or other units, such as minutes, is left as an exercise for the reader (or an opportunity for consulting!).</p>
<p>Let&#8217;s start by creating some test data. The following creates 1000 objects that have a start date from 2000 through most of 2009 and durations of up to 10 days (or still in progress).</p>
<pre style="padding-left:30px;">| set random origin |
set := UserGlobals at: #'James' put: IdentitySet new.
set createEqualityIndexOn: #'key' withLastElementClass: SmallInteger.
System commitTransaction.
random := Random new.
origin := Date newDay: 1 monthNumber: 1 year: 2000.
1000 timesRepeat: [
  | start stop key |
  start := origin addDays: (random integerBetween: 1 and: 3650).
  stop := start addDays: (random integerBetween: 0 and: 10).
  stop = start ifTrue: [stop := nil].
  key := start isNil
    ifTrue: [0]
    ifFalse: [stop isNil
      ifTrue: [start asDays]
      ifFalse: [(stop subtractDate: start) + 1 * 100000 + start asDays]].
 set add: key -&gt; (Array with: start with: stop).
].
System commitTransaction.</pre>
<p>The following demonstrates a &#8220;brute-force&#8221; search that tests every object:</p>
<pre style="padding-left:30px;">| start stop set resultSet |
set := UserGlobals at: #'James'.
start := (Date newDay: 1 monthNumber: 1 year: 2005) asDays.
stop := start + 6.
resultSet := set select: [:each |
  each value first asDays &lt;= stop and: [each value last isNil or: [start &lt;= each value last asDays]].
].
resultSet</pre>
<p>The following code demonstrates the Zimmerman search algorithm:</p>
<pre style="padding-left:30px;">| start stop set resultSet duration |
set := UserGlobals at: #'James'.
start := (Date newDay: 1 monthNumber: 1 year: 2005) asDays.
stop := start + 6.
resultSet := IdentitySet new.
resultSet addAll: (set select: {:each | each.key &lt;= stop}).    "Items that are in-progress"
duration := 100000.    "start at one-day duration"
[true] whileTrue: [
  | low high stream |
  low := duration + start - (duration // 100000).
  high := duration + stop.
  resultSet addAll: (set select: {:each | (each.key &gt;= low) &amp; (each.key &lt;= high)}).
  duration := duration + 100000.
  stream := set selectAsStream: {:each | each.key &gt;= duration}.
  stream atEnd ifTrue: [^resultSet].
  duration := stream next key // 100000 * 100000.
].
resultSet</pre>
<p>This approach starts with all the events that started before the stop point and are still in progress. Then it iterates over the completed items starting with those that have a one-day duration. A range of keys is computed based on the start, stop, and current duration, and the equality index is used to get the matching items for that duration. For domains in which there are a limited number of durations (such as video rentals), there are relatively few intermediate result sets and none have any unneeded objects. Given GemStone&#8217;s efficient handling of IdentitySets and intersection operations, I suspect that this is not worth the trouble, but it is an interesting approach. This approach does fault in one extra object for each duration after 1, but since the needed information is actually in the indexing data structures, this could be avoided.</p>
<p>Anyway, it is something to think about (and measure).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/610/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=610&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2012/01/11/indexing-for-a-date-range/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>

		<media:content url="http://programminggems.files.wordpress.com/2012/01/screen-shot-2012-01-11-at-9-27-20-am.png?w=529" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>
	</item>
		<item>
		<title>Maintenance Gem Overhead</title>
		<link>http://programminggems.wordpress.com/2011/10/05/maintenance-gem-overhead/</link>
		<comments>http://programminggems.wordpress.com/2011/10/05/maintenance-gem-overhead/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 16:44:23 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=509</guid>
		<description><![CDATA[The default GLASS setup starts a &#8216;maintenance gem&#8217; that performs two tasks: (1) expiring Seaside sessions and (2) performing repository-wide garbage collection (&#8216;mark for collection&#8217; or MFC). This maintenance gem is configured to use up to 200 MB for temporary object space and with other memory allocations, such as for persistent objects, the total memory [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=509&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The default GLASS setup starts a &#8216;maintenance gem&#8217; that performs two tasks: (1) expiring Seaside sessions and (2) performing repository-wide garbage collection (&#8216;mark for collection&#8217; or MFC). This maintenance gem is configured to use up to 200 MB for temporary object space and with other memory allocations, such as for persistent objects, the total memory usage can be twice that amount. It remains logged in continually expires sessions every minute and doing an MFC every hour.</p>
<p>The original no-cost license allowed for up to 1 GB shared page cache (SPC) and up to 4 GB for the total repository size. In a busy system where you could have at least 25% of the object space in memory (and had adequate memory for each of the Gems) doing an hourly MFC was important (to avoid having excess garbage) and not too expensive.</p>
<p>In some situations, however, the maintenance gem may be causing excess overhead. If you are running GLASS in the &#8220;cloud&#8221; (e.g., on SliceHost or some other virtual server), then the cost of RAM may provide a significant constraint on your SPC. Also, if your system is not used heavily, then there might not be enough garbage (primarily from expired sessions) to justify frequent MFC. Finally, since the no-cost license now allows for unlimited repository size, the consequence of running out of space is not so dire.</p>
<p>This is important because MFC is a comparatively heavy-weight operation and can take a lot of time. On some larger customer databases, it can take many days and the user experience often suffers. The size of the database is really not the most important factor; more important is the percent of the database that can fit in the SPC. If you are running in the cloud with  512 MB of RAM and are allowed only 1/8th of a CPU, then a 2 GB database in a 256 MB SPC could see a significant decrease in performance during an MFC.</p>
<p>To determine the necessary MFC frequency, take a look at the maintenance gem log. This will show the number of sessions expired each minute and the number of possible dead objects found during each MFC. You can go through the log and add up the possible dead during a 24-hour period. The next step is to go to the admingcgem log and look for an entry labeled &#8220;Starting doSweepWsUnion&#8221; with a timestamp shortly after the MFC completed. This should show a &#8220;PD size&#8221; that is approximately the number reported by the MFC. A few lines down will be a couple entries showing a count of objects removed from the possibleDead. Just before the next &#8220;Starting doSweepWsUnion&#8221; will be a final (and generally lower) &#8220;possible dead size&#8221;. You can take the total of these final sizes to get an estimate of the useful work done by the MFC.</p>
<p>In one case, we saw hourly MFCs take about 10 minutes each and over the course of a day the repository garbage collection process found 1.5 million dead objects. If each object is about 120 bytes, this is less than 200 MB. In this case it was worthwhile to switch to a daily MFC and do it during off-peak time when it would not affect the users.</p>
<p>To implement this change required an edit to $GEMSTONE/seaside/bin/runSeasideGems[30] to comment out the lines to start the maintenance gem. Instead, you can create a new script modeled on $GEMSTONE/seaside/bin/startMaintenance[30] that does not have an endless loop for expiring sessions and doing an MFC but does the work once then exits. You can then set up a cron job to call your new script.</p>
<p>I realize that I&#8217;m not providing all the details of the new setup here. The goal is more to provide an exploration of alternatives.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/509/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/509/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/509/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/509/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/509/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/509/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/509/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/509/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=509&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/10/05/maintenance-gem-overhead/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Don&#8217;t serve WAFileLibrary subclasses from Seaside</title>
		<link>http://programminggems.wordpress.com/2011/10/04/wafilelibrary/</link>
		<comments>http://programminggems.wordpress.com/2011/10/04/wafilelibrary/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 20:48:30 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=507</guid>
		<description><![CDATA[Most of us recognize that static files do not need to be served from Seaside, but it is a step that can be easily overlooked. I was recently helping someone analyze performance for a Seaside application and we found that serving the initial page made 20 Seaside requests, all but one of them for something [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=507&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Most of us recognize that static files do not need to be served from Seaside, but it is a step that can be easily overlooked. I was recently helping someone analyze performance for a Seaside application and we found that serving the initial page made 20 Seaside requests, all but one of them for something in /files (i.e., a subclass of WAFileLibrary). In this case it was Scriptaculous, but it could be anything.</p>
<p>The first step to fix this is to find out which files are being served from Seaside. You can do this by looking at your web server logs or by looking at requests made by the browser (in Firefox, use Firebug). If you see SUDevelopmentLibrary being requested, then look for references to that class. Typically the class will be the argument to an #&#8217;addLibrary:&#8217; message following a #&#8217;register:asApplicationAt:&#8217; message. Remove the #&#8217;addLibrary:&#8217; call and re-register your application.</p>
<p>Second, create operating system files containing the material previously served by Seaside. You can copy the text from the methods or you can obtain the files elsewhere. For example, to replace SUDevelopmentLibrary, go to the <a href="http://script.aculo.us/downloads">Scriptaculous downloads page</a>. Note, however, that SUDevelopmentLibrary has an additional method, #&#8217;treePatchJs&#8217;, that is not included in the download. Typically these files would be placed in your web server&#8217;s /scripts directory.</p>
<p>Finally, add references to the static file(s) to your component. Typically this is done in #&#8217;updateRoot:&#8217; on your component. For example:</p>
<pre>	#('prototype.js' 'scriptaculous.js' 'treePatch.js') do: [:each |
		anHtmlRoot script
			beJavascript;
			url: '/scripts/scriptaculous/' , each;
			yourself.
	].</pre>
<p>With this, we reduced by 95% the number of pages served by Seaside!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/507/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=507&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/10/04/wafilelibrary/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Photos from Edinburgh and ESUG 2011</title>
		<link>http://programminggems.wordpress.com/2011/08/29/photos-from-edinburgh-and-esug-2011/</link>
		<comments>http://programminggems.wordpress.com/2011/08/29/photos-from-edinburgh-and-esug-2011/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 13:29:14 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=505</guid>
		<description><![CDATA[&#160; &#160; Arriving in Edinburgh on Friday Around Edinburgh on Saturday Scottish Highlands Bus Tour on Sunday ESUG 2011 on Monday and Tuesday Social Event on Wednesday Web Frameworks Panel on Thursday WebTools Presentation on Friday<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=505&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>&nbsp;</p>
<ul>
<li><a href="https://www.facebook.com/media/set/?set=a.2215223173924.2121713.1047914752&amp;l=48e9deb1fd&amp;type=1">Arriving in Edinburgh on Friday</a></li>
<li><a href="https://www.facebook.com/media/set/?set=a.2215289895592.2121723.1047914752&amp;l=a61d0f6c9b&amp;type=1">Around Edinburgh on Saturday</a></li>
<li><a href="https://www.facebook.com/media/set/?set=a.2215396498257.2121732.1047914752&amp;l=1791279f2a&amp;type=1">Scottish Highlands Bus Tour on Sunday</a></li>
<li><a href="https://www.facebook.com/media/set/?set=a.2220685950490.2121984.1047914752&amp;l=b782cf4d04&amp;type=1">ESUG 2011 on Monday and Tuesday</a></li>
<li><a href="https://www.facebook.com/media/set/?set=a.2223558622305.2122085.1047914752&amp;l=a57367bbeb&amp;type=1">Social Event on Wednesday</a></li>
<li><a href="https://www.facebook.com/media/set/?set=a.2225405268470.2122161.1047914752&amp;l=4aa5121ed8&amp;type=1">Web Frameworks Panel on Thursday</a></li>
<li><a href="https://www.facebook.com/media/set/?set=a.2228222098889.2122269.1047914752&amp;l=f418d309f0&amp;type=1">WebTools Presentation on Friday</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/505/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=505&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/08/29/photos-from-edinburgh-and-esug-2011/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>GemStone/S 64 Bit 3.0 Released</title>
		<link>http://programminggems.wordpress.com/2011/07/15/gemstones-64-bit-3-0-released/</link>
		<comments>http://programminggems.wordpress.com/2011/07/15/gemstones-64-bit-3-0-released/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 15:36:59 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=501</guid>
		<description><![CDATA[[Update: Download from ftp://ftp.gemstone.com/pub/GemStone64/3.0.0/] VMware vFabric GemStone/S  3.0.0 is now live on vmware.com. Highlights of what&#8217;s new in the GemStone/S 64 Bit 3.0.0 release: Significant performance improvements and scalability features, including a redesigned Smalltalk virtual machine with just-in-time (JIT) compilation to native code, and parallelized, load-balancing garbage collection and repository scan operations. Internal redesign for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=501&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>[Update: Download from <a href="ftp://ftp.gemstone.com/pub/GemStone64/3.0.0/">ftp://ftp.gemstone.com/pub/GemStone64/3.0.0/</a>]</p>
<p>VMware vFabric GemStone/S  3.0.0 is now live on <a href="http://vmware.com/">vmware.com</a>.</p>
<p>Highlights of what&#8217;s new in the GemStone/S 64 Bit 3.0.0 release:</p>
<ul>
<li>Significant performance improvements and scalability features, including a redesigned Smalltalk virtual machine with just-in-time (JIT) compilation to native code, and parallelized, load-balancing garbage collection and repository scan operations.</li>
</ul>
<ul>
<li>Internal redesign for compatibility and portability, including new features supporting the Seaside web framework, and improved support for the ANSI Smalltalk standard and for portability to other Smalltalk dialects.</li>
</ul>
<ul>
<li>Various other features, such as Foreign Function Interface (FFI), simplifying the interface to third-party run-time libraries.</li>
</ul>
<p><strong>GA date:</strong> 07/14/2011</p>
<p>Download portal: <a href="http://downloads.vmware.com/d/info/datacenter_downloads/vmware_gemstone_s/3.0">http://downloads.vmware.com/d/info/datacenter_downloads/vmware_gemstone_s/3.0</a></p>
<p><strong>Release Notes &amp; documentation for GemStone/S</strong>:  <a href="http://community.gemstone.com/display/GSS64/GemStoneS+64+Documentation">http://community.gemstone.com/display/GSS64/GemStoneS+64+Documentation</a></p>
<p><strong>No-cost License Key:</strong> <a href="http://seaside.gemstone.com/etc/">http://seaside.gemstone.com/etc/</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/501/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/501/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/501/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=501&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/07/15/gemstones-64-bit-3-0-released/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Authentication in Seaside 3.0</title>
		<link>http://programminggems.wordpress.com/2011/07/07/authentication-in-seaside-3-0/</link>
		<comments>http://programminggems.wordpress.com/2011/07/07/authentication-in-seaside-3-0/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 23:08:12 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=499</guid>
		<description><![CDATA[In Chapter 12 of my Seaside Tutorial I give an example of rendering different content for a web site based on whether the user is known or not. This allows you to provide a public view (for un-authenticated users) and appropriate private views (for authenticated users), but requires you to to manage your own login [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=499&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://seaside.gemstone.com/tutorial/chapter12.pdf">Chapter 12</a> of my <a href="http://seaside.gemstone.com/tutorial.html">Seaside Tutorial</a> I give an example of rendering different content for a web site based on whether the user is known or not. This allows you to provide a public view (for un-authenticated users) and appropriate private views (for authenticated users), but requires you to to manage your own login dialog.</p>
<p>Seaside has the built-in ability to use HTTP Authentication to restrict an application to a specific user/password. The method WAAdmin class&gt;&gt;#&#8217;register:asApplicationAt:user:password:&#8217; registers the application with WAAuthenticationFilter as a filter and provides a single user and password that must be provided in order to view the initial page. This provides some password security, but does not differentiate among allowed users (e.g., everyone will use the same &#8216;admin&#8217; user name).</p>
<p>If you have an application that will always require authentication but should differentiate among multiple users, you can use WAAuthenticationFilter as well. For example, if you have a subclass of WAComponent named HelloComponent, you could provide a class-side initialization method as follows:</p>
<pre><span style="color:#333333;">initialize</span>
<span style="color:#333333;">"</span><span style="color:#333333;">HelloComponent initialize.</span><span style="color:#333333;">"</span>
<span style="color:#333333;"> | application filter |</span>
<span style="color:#333333;"> application := WAAdmin </span>
<span style="color:#333333;"> register: self</span>
<span style="color:#333333;"> asApplicationAt: 'hello'.</span>
<span style="color:#333333;"> filter := WAAuthenticationFilter new</span>
<span style="color:#333333;"> authenticator: self;</span>
<span style="color:#333333;"> yourself.</span>
<span style="color:#333333;"> application addFilter: filter.</span></pre>
<p>Like Seaside&#8217;s default authentication approach, this method adds a WAAuthenticationFilter as a filter, but provides an override to the default authenticator (here the component class itself). The authenticator must implement #&#8217;verifyPassword:forUser:&#8217;. The class side of HelloComponent could have something more sophisticated than the following:</p>
<pre><span style="color:#333333;">verifyPassword: password forUser: username</span>
<span style="color:#333333;"> username = 'bert' ifTrue: [^password = 'ernie'].</span>
<span style="color:#333333;"> ^false.</span></pre>
<p>At this point your render code can assume that a valid user has been properly authenticated and can vary the content based on the user. For example, the following instance-side method in HelloComponent would show what user was authenticated:</p>
<pre><span style="color:#333333;">renderContentOn: html</span>
<span style="color:#333333;"> html text: 'Hello ' , self requestContext request user , '!'.</span></pre>
<p>Now you have basic HTTP authentication for multiple users. Of course, you are now subject to the limitations of basic HTTP authentication, including the fact that logout is somewhat awkward. You can provide a logout link:</p>
<pre><span style="color:#333333;">renderContentOn: html</span>
<span style="color:#333333;"> html text: 'Hello ' , self requestContext request user , '!';</span><span style="color:#333333;"> break.</span>
<span style="color:#333333;"> html anchor</span>
<span style="color:#333333;"> callback: [self doLogout];</span>
<span style="color:#333333;"> with: 'Logout'.</span></pre>
<p>The logout method informs the user how to complete the logout and then adds a field to let the verification method know to fail:</p>
<pre>doLogout
	| url |
	self inform: 'When the login dialog appears, click the Cancel button then close your browser.'.
	url := self requestContext request url copy.
	url addField: 'logout'.
	self requestContext redirectTo: url.</pre>
<p>The verification method would then check for the new field:</p>
<pre><span style="color:#333333;">verifyPassword: password forUser: username</span>
<span style="color:#333333;"> (WACurrentRequestContext value request url queryFields includesKey: 'logout') ifTrue: [^false].</span>
<span style="color:#333333;"> username = 'bert' ifTrue: [^password = 'ernie'].</span>
<span style="color:#333333;"> ^false.</span></pre>
<p><a href="http://charliemeyer.net/blog/2011/04/integrating-ldap-authentication-with-seaside/">Charlie Meyer</a> has an explanation of how he used a similar approach with LDAP authentication.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/499/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/499/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/499/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=499&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/07/07/authentication-in-seaside-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Migrating to Seaside 3.0</title>
		<link>http://programminggems.wordpress.com/2011/07/01/migrating-to-seaside-30/</link>
		<comments>http://programminggems.wordpress.com/2011/07/01/migrating-to-seaside-30/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 23:19:07 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=496</guid>
		<description><![CDATA[Earlier I described how to migrate to a Metacello-based Seaside 2.8. The process involves removing many packages and loading things as if you were in a new repository. Because of the extensive package restructuring and class changes, the process of moving from Seaside 2.8 to 3.0 is largely the same. I&#8217;ve found that the same [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=496&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://programminggems.wordpress.com/2011/01/02/migrating-to-metacello-based-seaside-2-8/">Earlier</a> I described how to migrate to a Metacello-based Seaside 2.8. The process involves removing many packages and <a href="http://programminggems.wordpress.com/2011/07/01/loading-seaside-3-0-into-gemstone-2-4-4-4/">loading</a> things as if you were in a new repository. Because of the extensive package restructuring and class changes, the process of moving from Seaside 2.8 to 3.0 is largely the same. I&#8217;ve found that the same <a href="http://programminggems.wordpress.com/2011/01/02/migrating-to-metacello-based-seaside-2-8/">instructions</a> work with one change: In step #13, evaluate &#8216;UpgradeTool new updateProjects; updateGLASS; loadSeaside30&#8242; in a workspace to load Seaside.</p>
<p>After doing the load, I found a few packaging issues:</p>
<ul>
<li>&#8216;Metacello-MC&#8217; was marked dirty but had no changes. I reloaded it to clear the dirty flag.</li>
<li>&#8216;Seaside2&#8242; existed but had no repositories or versions. I unloaded the package.</li>
<li>&#8216;Seaside-Core.gemstone&#8217; was missing WAAuthConfiguration. I reloaded the package.</li>
<li>&#8216;Seaside-Component&#8217; was dirty but had no changes. I reloaded it to clear the dirty flag.</li>
<li>&#8216;Seaside-Tools-Core&#8217; was dirty but had no changes. I reloaded it to clear the dirty flag.</li>
<li>&#8216;VB-Regex&#8217; existed but was replaced by &#8216;Regex-Core&#8217; and &#8216;Regex-Tests-Core&#8217;. I unloaded it.</li>
</ul>
<p>With this, I have Seaside 3.0 loaded (but not running). There are a substantial number of changes between Seaside 2.8 and Seaside 3.0, so much work remains to be done&#8211;but at least we have the code loaded!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/496/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=496&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/07/01/migrating-to-seaside-30/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
		<item>
		<title>Loading Seaside 3.0 into GemStone 2.4.4.4</title>
		<link>http://programminggems.wordpress.com/2011/07/01/loading-seaside-3-0-into-gemstone-2-4-4-4/</link>
		<comments>http://programminggems.wordpress.com/2011/07/01/loading-seaside-3-0-into-gemstone-2-4-4-4/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 20:33:38 +0000</pubDate>
		<dc:creator>James Foster</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://programminggems.wordpress.com/?p=493</guid>
		<description><![CDATA[There are instructions for loading Seaside 3.0 into GemStone 2.4.4.1, but there are a couple bugs (including #259 and #278) that get in the way when loading Seaside 3.0.5 into GemStone 2.4.4.4. I&#8217;ve found that the following Smalltalk code (used in Topaz or a workspace) allows a successful load: ConfigurationOfGLASS project updateProject. ConfigurationOfGofer project updateProject. ConfigurationOfGoferProjectLoader [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=493&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There are <a href="http://code.google.com/p/glassdb/wiki/Seaside30Configuration">instructions</a> for loading Seaside 3.0 into GemStone 2.4.4.1, but there are a couple bugs (including <a href="http://code.google.com/p/glassdb/issues/detail?id=259">#259</a> and <a href="http://code.google.com/p/glassdb/issues/detail?id=278">#278</a>) that get in the way when loading Seaside 3.0.5 into GemStone 2.4.4.4. I&#8217;ve found that the following Smalltalk code (used in Topaz or a workspace) allows a successful load:</p>
<pre>ConfigurationOfGLASS project updateProject.
ConfigurationOfGofer project updateProject.
ConfigurationOfGoferProjectLoader project updateProject.
ConfigurationOfGsCore project updateProject.
ConfigurationOfGsMisc project updateProject.
ConfigurationOfGsMonticello project updateProject.
ConfigurationOfGsOB project updateProject.
ConfigurationOfMetacello project updateProject.
System commitTransaction.

MCPlatformSupport autoMigrate: true.
ConfigurationOfMetacello project latestVersion load.
ConfigurationOfGoferProjectLoader project load: #stable.
MCPlatformSupport autoMigrate: false.
System commitTransaction.

MCPlatformSupport commitOnAlmostOutOfMemoryDuring: [
	[
		ConfigurationOfGLASS project load: #stable.
	] on: Warning do: [:ex | ex resume ].
].
System commitTransaction.

MCPlatformSupport commitOnAlmostOutOfMemoryDuring: [
	[
		Gofer project load: 'Seaside30' version: '3.0.5'.
	] on: Warning do: [:ex | ex resume ].
].
System commitTransaction.</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/programminggems.wordpress.com/493/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/programminggems.wordpress.com/493/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/programminggems.wordpress.com/493/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/programminggems.wordpress.com/493/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/programminggems.wordpress.com/493/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/programminggems.wordpress.com/493/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/programminggems.wordpress.com/493/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/programminggems.wordpress.com/493/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=programminggems.wordpress.com&amp;blog=4742635&amp;post=493&amp;subd=programminggems&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://programminggems.wordpress.com/2011/07/01/loading-seaside-3-0-into-gemstone-2-4-4-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/631f05ac3a6ed798c66034d408aceeaf?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">James Foster</media:title>
		</media:content>
	</item>
	</channel>
</rss>
