<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Ivan Zuzak</title>
 <link href="http://ivanzuzak.info/atom.xml" rel="self"/>
 <link href="http://ivanzuzak.info"/>
 <link href="http://pubsubhubbub.appspot.com/" rel="hub"/>
 <updated>2013-05-18T09:55:24-07:00</updated>
 <id>http://ivanzuzak.info/</id>
 <author>
   <name>Ivan Zuzak</name>
   <email>izuzak@gmail.com</email>
 </author>

 
 <entry>
   <title>Experimenting with HTTP services - UrlEcho and UrlReq</title>
   <link href="http://ivanzuzak.info/2013/03/19/experimenting-with-http-services-urlecho-urlreq.html"/>
   <updated>2013-03-19T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2013/03/19/experimenting-with-http-services-urlecho-urlreq</id>
   <content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/izuzak/urlecho&quot;&gt;UrlEcho&lt;/a&gt; and &lt;a href=&quot;https://github.com/izuzak/urlreq&quot;&gt;UrlReq&lt;/a&gt; are two HTTP services I built a few years ago when I started learning about the Web's architecture.
The services are fairly generic and might be useful to other people experimenting, testing and debugging Web-based systems.
They are hosted on AppEngine and free to use.&lt;/p&gt;

&lt;p&gt;Both services receive an HTTP request which contains a &lt;strong&gt;definition of another HTTP message in the URL of the received request&lt;/strong&gt;, and then do something with that message.&lt;/p&gt;

&lt;h3&gt;The UrlEcho service&lt;/h3&gt;

&lt;p&gt;Requests to the UrlEcho service should contain the &lt;strong&gt;definition of a HTTP response message in the URL&lt;/strong&gt; (i.e. the status, headers and body of the response).
Upon receiving the request, UrlEcho responds to the requestor with the HTTP response defined in the URL of the request.
Here's an example request URL (clickable link &lt;a href=&quot;http://urlecho.appspot.com/echo?status=200&amp;amp;Content-Type=text%2Fhtml&amp;amp;body=Hello%20world!&quot;&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://urlecho.appspot.com/echo?status=200&amp;amp;Content-Type=text%2Fhtml&amp;amp;body=Hello%20world!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and the corresponding HTTP response which is defined in the URL and will be echoed back to the requestor:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: text/html

Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As shown in the example, the API for the service is simple (split into multiple lines for clarity):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://urlecho.appspot.com/echo
  ?status=&amp;lt;HTTP_STATUS&amp;gt;
  &amp;amp;&amp;lt;HEADER1_NAME&amp;gt;=&amp;lt;HEADER1_VALUE&amp;gt;
  &amp;amp;&amp;lt;HEADER2_NAME&amp;gt;=&amp;lt;HEADER2_VALUE&amp;gt;
  &amp;amp;body=&amp;lt;BODY_STRING&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where the strings for header names and values, and for the body must be URL encoded.&lt;/p&gt;

&lt;h3&gt;The UrlReq service&lt;/h3&gt;

&lt;p&gt;On the other hand, requests to the UrlReq service should contain the &lt;strong&gt;definition of another HTTP request message in the URL&lt;/strong&gt; (i.e. the method, url, headers and body of the request).
Upon receiving the request, UrlReq performs the request defined in the URL, and forwards the received response back to the requestor.
Here's an example request URL for requesting HTML rendering of Markdown input using GitHub's API (clickable link &lt;a href=&quot;http://urlreq.appspot.com/req?method=POST&amp;amp;url=https%3A%2F%2Fapi.github.com%2Fmarkdown%2Fraw&amp;amp;Content-Type=text%2Fplain&amp;amp;body=**Hello**%20_World_!&quot;&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://urlreq.appspot.com/req?method=POST&amp;amp;url=https%3A%2F%2Fapi.github.com%2Fmarkdown%2Fraw&amp;amp;
Content-Type=text%2Fplain&amp;amp;body=**Hello**%20_World_!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;the corresponding HTTP request hosted in the URL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;POST /markdown/raw 
Host: api.github.com
Content-Type: text/plain

**Hello** _World_!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and the response received from the service:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
...

&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;Hello&amp;lt;/strong&amp;gt; &amp;lt;em&amp;gt;World&amp;lt;/em&amp;gt;!&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As shown in the example, the API for the service is simple (split into multiple lines for clarity):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://urlreq.appspot.com/req
  ?method=&amp;lt;HTTP_METHOD&amp;gt;
  &amp;amp;url=&amp;lt;TARGET_URL&amp;gt;
  &amp;amp;&amp;lt;HEADER1_NAME&amp;gt;=&amp;lt;HEADER1_VALUE&amp;gt;
  &amp;amp;&amp;lt;HEADER2_NAME&amp;gt;=&amp;lt;HEADER2_VALUE&amp;gt;
  &amp;amp;body=&amp;lt;BODY_STRING&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where the strings for header names and values, for the target URL, and for the body must be URL encoded.&lt;/p&gt;

&lt;h3&gt;URL builders and debug mode&lt;/h3&gt;

&lt;p&gt;To make the construction of such URLs easier, simple &lt;strong&gt;URL builder forms&lt;/strong&gt; are available for both services: &lt;a href=&quot;http://izuzak.github.com/urlecho&quot;&gt;UrlEcho URL builder&lt;/a&gt; and &lt;a href=&quot;http://izuzak.github.com/urlreq&quot;&gt;UrlReq URL builder&lt;/a&gt; (scroll down when you get to the project page).&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;UrlEcho URL builder&quot; src=&quot;http://ivanzuzak.info/images/urlecho/urlbuilder.png&quot; alt=&quot;&quot; width=&quot;40%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Also, both services have support for &lt;strong&gt;debug mode&lt;/strong&gt; by appending &lt;code&gt;&amp;amp;debugMode=1&lt;/code&gt; to the end of the URLs.
When in debug mode, the services return a &lt;code&gt;text/plain&lt;/code&gt; version of the HTTP response that would be returned if the service was not in debug mode.
So, it's basically a text log output of the intended HTTP response.&lt;/p&gt;

&lt;h3&gt;Why build these services?&lt;/h3&gt;

&lt;p&gt;In a way, both services change/break the default way of using HTTP -- the &lt;strong&gt;URL is used for more than identifying a resource&lt;/strong&gt; and the services are just stateless shells that either echo requests or responses.
They could be thought of a special kind of HTTP intermediaries.&lt;/p&gt;

&lt;p&gt;UrlEcho permits the requestor to completely define the response it wants to receive, thus giving it the &lt;strong&gt;ability to &quot;host&quot; static HTTP resources within URLs themselves&lt;/strong&gt;.
Why is this cool/useful?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don't need a Web server to host a simple resource -- you just construct a URL and you're set to go.&lt;/li&gt;
&lt;li&gt;Since resources are cheap to create and throw away, you can create as many URLs as you want, when you want them.&lt;/li&gt;
&lt;li&gt;This is especially useful for testing -- you don't want to configure many server-side resources to return hard-coded responses in order to test correct handling of that response.
For example, imagine you need many simple iframes to test a JavaScript library, and you don't want to modify the server hosting the iframes each time you add or change tests.
Since you already know what the responses will be, why not define them in the requests and have a simpler testing process?
It makes tests easier to maintain (no need to modify the server) and understand (due to response visibility in the tests).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;UrlEcho lets the requestor to &lt;strong&gt;wrap any HTTP request (any method, with headers and body) into a simple GET request with only an URL defined&lt;/strong&gt;.
Why is this cool/useful?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can make any HTTP request in situations where only a simple GET is possible, or where you can only define just the URL.
For example, most systems that provide Web hook callbacks only let you define the callback URL only (not the method, headers or body structure).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In general, the reasons behind using URLs to &quot;host&quot; HTTP messages (versus choosing headers or the body) is that it has &lt;strong&gt;the widest possible applicability&lt;/strong&gt;.
The URL is often the only thing you can define for a request -- e.g. in &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; HTML elements, and when defining Web hook callbacks.
You can't set HTTP headers or the body in such situations, the URL is all you have access to.
The example I gave above for UrlReq, the one for rendering Markdown text to HTML using GitHub's API -- isn't it cool how you can give a simple link to someone, that makes a POST request behind the scenes?
It is.&lt;/p&gt;

&lt;p&gt;Note also that &lt;strong&gt;the services don't respond just to HTTP GET requests, but also to HEAD, POST, PUT, DELETE and OPTIONS requests&lt;/strong&gt;.
This means that, for example, you can make an HTTP DELETE request to UrlReq and make it do an HTTP POST or HTTP PUT request in the background, just by playing with the URL.&lt;/p&gt;

&lt;h3&gt;Other nits and bits&lt;/h3&gt;

&lt;p&gt;The main issue with using URLs for passing data is that &lt;strong&gt;URLs have limited length&lt;/strong&gt;.
You just can't put 10 MB in there.&lt;/p&gt;

&lt;p&gt;Long, ugly URLs make you go &lt;em&gt;Meh.&lt;/em&gt;?
Just use an &lt;strong&gt;URL shortening service&lt;/strong&gt; on the long URL, like so: &lt;a href=&quot;http://goo.gl/UOQPy&quot;&gt;http://goo.gl/UOQPy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A few notes about security-related issues.
After successfully using UrlEcho for over a year, I noticed it stopped working for me in Chrome.
Turns out, using UrlEcho for &lt;strong&gt;echoing back HTML documents with JavaScript scripts makes browsers think there is an XSS attack happening&lt;/strong&gt;.
For example, the following URL (clickable link &lt;a href=&quot;http://urlecho.appspot.com/echo?status=200&amp;Content-Type=text%2Fhtml&amp;body=%3Chtml%3E%0A%20%20%3Chead%3E%0A%20%20%3C%2Fhead%3E%0A%20%20%3Cbody%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20console.log(%22Hello%20world!%22)%3B%0A%20%20%20%20%3C%2Fscript%3E%0A%20%20%3C%2Fbody%3E%0A%3C%2Fhead%3E&quot;&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://urlecho.appspot.com/echo?status=200&amp;amp;Content-Type=text%2Fhtml&amp;amp;body=%3Chtml%3E%0A%20%20%3C
head%3E%0A%20%20%3C%2Fhead%3E%0A%20%20%3Cbody%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20
console.log(%22Hello%20world!%22)%3B%0A%20%20%20%20%3C%2Fscript%3E%0A%20%20%3C%2Fbody%3E%0A%3C%2F
head%3E
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;echoes back a simple HTML document with a &lt;code&gt;console.log(&quot;Hello world!&quot;)&lt;/code&gt; script.
However, the script will not get executed and Chrome will log the following error to the console: &lt;em&gt;&quot;Refused to execute a JavaScript script. Source code of script found within request.&quot;&lt;/em&gt;
I suppose security hackers can find a way to trick Chrome and get around this, by tweaking the request content.
But, this is something you should be aware of.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;cross-origin calls to both services are enabled via &lt;a href=&quot;http://en.wikipedia.org/wiki/Cross-origin_resource_sharing&quot;&gt;CORS headers&lt;/a&gt;&lt;/strong&gt;, both &lt;strong&gt;services are accessible over HTTPS&lt;/strong&gt;, and the &lt;strong&gt;UrlEcho service responds on arbitrary subdomains&lt;/strong&gt;, e.g. &lt;code&gt;http://mysubdomain.urlecho.appspot.com/echo?...&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;More information about &lt;a href=&quot;http://ivanzuzak.info/urlecho/&quot;&gt;UrlEcho&lt;/a&gt; and &lt;a href=&quot;http://ivanzuzak.info/urlreq/&quot;&gt;UrlReq&lt;/a&gt; is available on their Web sites.
Let me know if you like the services, think they're an abomination of the Web, or have any other cool ideas for HTTP services.&lt;/p&gt;

&lt;p&gt;As for me, I really learned to appreciate nice and simple HTTP services with generic applicability.
There is a nice list of other such services in my blog post &lt;a href=&quot;http://ivanzuzak.info/2012/11/18/the-web-engineers-online-toolbox.html&quot;&gt;The Web Engineer's online toolbox&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google Scholar pointed me to a plagiarism of my paper</title>
   <link href="http://ivanzuzak.info/2012/12/03/google-scholar-points-to-plagiarized-paper.html"/>
   <updated>2012-12-03T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2012/12/03/google-scholar-points-to-plagiarized-paper</id>
   <content type="html">&lt;p&gt;I love &lt;a href=&quot;http://scholar.google.com/schhp?hl=en&quot;&gt;Google Scholar&lt;/a&gt;, especially the recently introduced &lt;a href=&quot;http://googlescholar.blogspot.com/2012/08/scholar-updates-making-new-connections.html&quot;&gt;Updates feature&lt;/a&gt;. In a nutshell, this feature continuously searches for and &lt;strong&gt;recommends new articles relevant to your research&lt;/strong&gt; based on a statistical model that incorporates your publications and citations. And it works really well! Google Scholar already recommended me dozens of relevant papers and, because Google keeps a good watch over the Web, it recommends papers soon after they are put online.&lt;/p&gt;

&lt;p&gt;However, two weeks ago something special happened. As I opened and glanced one of the papers recommended by Google Scholar, I realized that the &lt;strong&gt;recommended paper was a plagiarism of one of the papers I co-authored&lt;/strong&gt; and was published two and a half years ago. Yes, I'm 100% certain that the paper is a plagiarism; 80%-90% of the text and 100% figures were just copy/pasted. Only the abstract and title of the paper have been significantly changed since the authors probably thought this was the only way to detect foul play (since the title and abstract are usually the only parts of papers that are available for free and indexed by search engines). The original paper I co-authored is &lt;a href=&quot;http://ivanzuzak.info/papers/2010_SIPWS_middleware.pdf&quot;&gt;here&lt;/a&gt; (link to publisher site with the paper is &lt;a href=&quot;http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=5533443&quot;&gt;here&lt;/a&gt;) while the plagiarized paper is &lt;a href=&quot;http://www.ijcta.com/documents/volumes/vol3issue6/ijcta2012030610.pdf&quot;&gt;here&lt;/a&gt; (link to publisher site with the paper is &lt;a href=&quot;http://www.ijcta.com/vol3issue6.php&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I don't want to turn this blog post into a long rant about honesty, but I do want to highlight two points. First, without going into who plagiarized the paper, where they &lt;a href=&quot;http://www.gprec.ac.in/cse_staff.asp&quot;&gt;work&lt;/a&gt; or &lt;a href=&quot;https://maps.google.com/maps?q=Kurnool,+Andhra+Pradesh,+India&amp;amp;hl=en&amp;amp;ll=15.792254,78.046875&amp;amp;spn=26.504561,53.569336&amp;amp;sll=15.749963,78.09082&amp;amp;sspn=26.509892,53.569336&amp;amp;oq=KURNOOL,+india&amp;amp;hnear=Kurnool,+Andhra+Pradesh,+India&amp;amp;t=m&amp;amp;z=5&quot;&gt;live&lt;/a&gt;, and in which &lt;a href=&quot;http://www.ijcta.com/vol3issue6.php&quot;&gt;journal the plagiarism was published&lt;/a&gt; -- this is just &lt;a href=&quot;http://retractionwatch.wordpress.com/2012/08/24/korean-plant-compound-researcher-faked-email-addresses-so-he-could-review-his-own-studies/&quot;&gt;another&lt;/a&gt; piece of evidence of the corruption and apathy that's more and more present in all segments of academia and higher education.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;Google Scholar kicks ass&lt;/strong&gt;! I've made no effort whatsoever in finding this plagiarism, it was all Google Scholar. While the service didn't really tell me that it was a plagiarism of my paper (just that it was relevant material), that's just a tiny step from here. Imagine what other things the service could do if Google made a stronger effort. Imagine publishers partnering with Google to help them find plagiarisms. Or imagine Google creating an open, Web-based platform for academic publishing and relevance/impact computation. &lt;em&gt;(Google, I know you're reading this. If you need help -- call me. You know my number.)&lt;/em&gt; Anyway, good things are on their way, I'm sure of it. That's why I'm happy to see people boycotting academic publishers that lock-in research papers behind paywalls. And that's why I'm glad that companies like &lt;a href=&quot;https://www.coursera.org/&quot;&gt;Coursera&lt;/a&gt;, &lt;a href=&quot;http://www.udacity.com/&quot;&gt;Udacity&lt;/a&gt; and &lt;a href=&quot;http://www.khanacademy.org/&quot;&gt;Khan Academy&lt;/a&gt; and services like &lt;a href=&quot;http://scholar.google.com/schhp?hl=en&quot;&gt;Google Scholar&lt;/a&gt; are transforming university-level education and shaking up everyone in academia.&lt;/p&gt;

&lt;p&gt;We reported everything to the publisher of the journal which contains the plagiarism, but haven't received any real response for more than 12 days. If anyone has been in a similar situation - let me know if you pursued the issue in other ways and how that turned out (e.g. through institutions or legal suits).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Web engineer's online toolbox</title>
   <link href="http://ivanzuzak.info/2012/11/18/the-web-engineers-online-toolbox.html"/>
   <updated>2012-11-18T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2012/11/18/the-web-engineers-online-toolbox</id>
   <content type="html">&lt;p&gt;I wanted to compile a list of online, Web-based tools that Web engineers can use for their work in development, testing, debugging and documentation.
The requirements for a tool to make the list are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;must be a live Web application (no extensions or apps you have to host yourself),&lt;/li&gt;
&lt;li&gt;free to use (some kind of free plan available),&lt;/li&gt;
&lt;li&gt;generic applicability (not usable only for a specific application/platform),&lt;/li&gt;
&lt;li&gt;and must be useful to Web engineers (not just for Web site design)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The current version of the list is shown below and is based on tools which I use or have used.
Two of my personal favorites are &lt;a href=&quot;http://requestb.in/&quot;&gt;RequestBin&lt;/a&gt; and &lt;a href=&quot;http://hurl.it&quot;&gt;Hurl&lt;/a&gt; which I use regularly for almost every project.
A few of the tools I haven't used in real projects but just played with them and thought they were really cool.&lt;/p&gt;

&lt;p&gt;Since I've probably forgotten some excellent tools, and because new tools will be made in the future - the list will be a &quot;live list&quot;, updated as the set of available tools changes.
I didn't categorize the tools in the list since many tools may be used in many phases of software development.&lt;/p&gt;

&lt;p&gt;Want to suggest a new tool or help me write better short descriptions of the tools? Add a comment below or make a &lt;a href=&quot;https://github.com/izuzak/izuzak.github.com&quot;&gt;pull request&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Web engineer's online toolbox&lt;/strong&gt; &lt;em&gt;(last edited on May 18 2013)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://requestb.in/&quot;&gt;RequestBin&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Lets you create a URL that will collect requests made to it, then let you inspect them in a human-friendly way.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://hurl.it&quot;&gt;Hurl&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Makes HTTP requests. Enter a URL, set some headers, view the response, then share it with others.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://resttesttest.com/&quot;&gt;REST test test&lt;/a&gt;, &lt;a href=&quot;https://apigee.com/console/others&quot;&gt;Apigee console&lt;/a&gt;, &lt;a href=&quot;http://web-sniffer.net/&quot;&gt;Web-Sniffer&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.runscope.com/&quot;&gt;Runscope&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A proxy for inspecting API calls, providing several features of Hurl and RequestBin.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://httpbin.org/&quot;&gt;httpbin&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A HTTP request &amp;amp; response service that covers all kinds of HTTP scenarios (e.g. different HTTP verbs, status codes and redirects).&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://hang.nodester.com/&quot;&gt;Hang&lt;/a&gt;, &lt;a href=&quot;http://ivanzuzak.info/urlecho/&quot;&gt;UrlEcho&lt;/a&gt;, &lt;a href=&quot;http://www.mocky.io/&quot;&gt;Mocky&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://redbot.org/&quot;&gt;REDbot&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A robot that checks HTTP resources to see how they'll behave, pointing out common problems and suggesting improvements.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://zamez.org/httplint&quot;&gt;HTTP lint&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://webgun.io/&quot;&gt;WebGun&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;API for creating templated webhooks.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;https://github.com/izuzak/urlreq&quot;&gt;UrlReq&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.webscript.io/&quot;&gt;Webscript&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Webscripts are short and hosted scripts, written in Lua. They can respond to HTTP requests or run as cron jobs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.clickhooks.com/&quot;&gt;ClickHooks&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A URL shortener service that provides callbacks via HTTP POST when people go to a shortened link.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://mailhooks2.appspot.com/&quot;&gt;MailHooks&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Lets you receive emails via HTTP POST (aka webhooks). You can create many hooks that will give you an e-mail address that, when e-mailed, parses and POSTs the message to the URL you specify.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://a.quil.la/&quot;&gt;Quilla&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Provides short-links where people can contact you, where each submission on your short-link will send you an email. A kind of a HTTP-&gt;SMTP proxy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://apify.heroku.com&quot;&gt;Apify&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Exposes datasets locked within HTML documents for which there are no APIs. APIfy extracts data from structured markups and converts it to JSON APIs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://validator.w3.org/unicorn/&quot;&gt;Unicorn&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;W3C's unified validator, which performs a variety of checks from the popular HTML and CSS validators, as well as other useful services.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://lint.brihten.com/html/&quot;&gt;HTML lint&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://infohound.net/tidy/&quot;&gt;HTML tidy&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;HTML Tidy is a tool for checking and cleaning up HTML source files.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://validator.w3.org/feed/&quot;&gt;Feed validator&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;W3C's validator for RSS and ATOM syndicated feeds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://jsonlint.com/&quot;&gt;JSONLint&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;JSON validator.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://validator.w3.org/checklink&quot;&gt;Link checker&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Extracts links (recursively) from a Web site and checks that no link is defined twice, that all the links are dereferenceable and warns about HTTP redirects.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.host-tracker.com/&quot;&gt;Host tracker&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Website monitoring service with distributed ping/trace check, periodic monitoring, email/sms/IM notifications and statistics.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://www.downforeveryoneorjustme.com/&quot;&gt;Down for everyone or just me&lt;/a&gt;, &lt;a href=&quot;http://tools.pingdom.com/ping/&quot;&gt;Pingdom ping service&lt;/a&gt;, &lt;a href=&quot;http://isitup.org/&quot;&gt;IsItUp&lt;/a&gt;, &lt;a href=&quot;https://www.pingbrigade.com/&quot;&gt;Ping brigade&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.viewdns.info/&quot;&gt;ViewDNS&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Collection of DNS and network-level tools, such as reverse IP lookup, DNS record lookup and traceroute.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.necrohost.com/&quot;&gt;Necrohost&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;List of URLs that simulate a variety of network connectivity issues e.g. slow response, unresolvable DNS and 404.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://code.google.com/p/mirrorrr/&quot;&gt;Mirrorrr&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Application that mirrors the content of URLs you supply. Rewrites the fetched page to mirror all content, including images, Flash, Javascript, CSS, and even favicons.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://certlogik.com/ssl-checker/&quot;&gt;SSL Checker&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Test SSL certificates of online sites and helps with identifying any problems.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://certlogik.com/decoder/&quot;&gt;CSR/Cert decoder&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Decode and check your CSRs and SSL certificates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.ssllabs.com/ssltest/index.html&quot;&gt;SSL Server Test&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Performs a deep analysis of the configuration of any SSL web server on the public Internet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://loadzen.com/&quot;&gt;Loadzen&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Cloud-powered load testing service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://tools.pingdom.com/fpt/&quot;&gt;Pingdom Full page test&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Enables users to test the load time of a page, analyze it, monitor, find bottlenecks and export results in HAR format.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://www.webpagetest.org/&quot;&gt;Web page test&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://developers.google.com/speed/pagespeed/insights&quot;&gt;Google PageSpeed Insights&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Analyzes the content of a web page, then generates suggestions to make that page faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.softwareishard.com/har/viewer/&quot;&gt;HAR viewer&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Visualizes HTTP Archive (HAR) log files created by HTTP tracking tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://pcapperf.appspot.com/&quot;&gt;PCAP Web Performance Analyzer&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Converts a PCAP file to HAR, provides a HTTP waterfall view using HarViewer and Page Speed suggestions for your network trace.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.corsproxy.com/&quot;&gt;CORS proxy&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Allows JavaScript code on your site to access resources on other domains that would normally be blocked due to the same-origin policy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://browserling.com/&quot;&gt;Browserling&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Interactive cross-browser testing using all major browsers and versions. Browsers within your browser.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.websocket.org/echo.html&quot;&gt;WebSocket Echo Test&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Test a WebSocket connection from your browser against our WebSocket echo server.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://developer.yahoo.com/yql/&quot;&gt;YQL&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;An expressive SQL-like language that lets you query, filter, and join data across Web services.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://webshell.io/&quot;&gt;Webshell&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;An API which allow accessing any data on the programmable Web using APIs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://pipes.yahoo.com/pipes/&quot;&gt;Yahoo Pipes&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A graphical user interface for building data mashups that aggregate web feeds, web pages, and other services.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://apiary.io/&quot;&gt;Apiary&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Language and tool for generating REST API documentation with an interactive inspector.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://swagger.wordnik.com/&quot;&gt;Swagger&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://jsfiddle.net/&quot;&gt;JSFiddle&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A playground for Web site developers: code editor and repository for snippets built from HTML, CSS and JavaScript.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://jsbin.com/&quot;&gt;JSBin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://developers.google.com/feed/v1/jsondevguide&quot;&gt;Google Feed API&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Enables looking up feed URLs for a site (&lt;a href=&quot;http://ajax.googleapis.com/ajax/services/feed/lookup?v=1.0&amp;amp;q=http://ivanzuzak.info/&quot;&gt;example&lt;/a&gt;), searching for feeds by keywords (&lt;a href=&quot;https://ajax.googleapis.com/ajax/services/feed/find?v=1.0&amp;amp;q=ivan%20zuzak&quot;&gt;example&lt;/a&gt;) and returning a JSON representation of a feed (&lt;a href=&quot;https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&amp;amp;q=http://ivanzuzak.info/atom.xml&quot;&gt;example&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://aboutmybrowser.com/?nr&quot;&gt;About My Browser&lt;/a&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Extracts and displays browser info (browser, version, OS, cookies, JS, screen resolution, etc) and stores this info as a shareable Web page.&lt;/li&gt;
&lt;li&gt;Similar tools: &lt;a href=&quot;http://browserspy.dk/&quot;&gt;http://browserspy.dk/&lt;/a&gt;, &lt;a href=&quot;http://supportdetails.com/&quot;&gt;SupportDetails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Forgotten TODOs: ideas for contributing to open-source projects</title>
   <link href="http://ivanzuzak.info/2012/03/03/todos-ideas-for-contributing-to-open-source-projects.html"/>
   <updated>2012-03-03T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2012/03/03/todos-ideas-for-contributing-to-open-source-projects</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT (March 08 2012)&lt;/strong&gt;:&lt;/em&gt; This post got a lot of feedback on &lt;a href=&quot;http://news.ycombinator.com/item?id=3660137&quot;&gt;Hacker News&lt;/a&gt; and &lt;a href=&quot;http://www.reddit.com/r/programming/comments/qg3nz/ideas_for_contributing_to_opensource_projects/&quot;&gt;Reddit&lt;/a&gt;.
I'd like to thank all the people on their positive and constructive thoughts and address some of the feedback.&lt;/p&gt;

&lt;p&gt;First, there was some really good advice on advanced usage of TODOs, such as using tools for tracking them systematically and using different TODO tags (such as TODO, FIXME, TBD, and XXX) to indicate the relevance/urgency of the TODO.
Since a lot of people mentioned that they also use FIXMEs, I've also included their count in the table in the post.&lt;/p&gt;

&lt;p&gt;However, the comments I liked the most were the ones that suggested other generic ideas for contributing to open-source projects, especially the ones that mentioned writing documentation and unit tests.
I can't stress enough how good advice this is.&lt;/p&gt;

&lt;p&gt;There's also been some negative feedback, mainly focused on explaining that newcomers should not target TODOs because they are usually either very hard to fix, will have little value if fixed, or are not meant to be fixed by someone who is not the project maintainer.
In addition, some comments say that newcomers should focus on fixing bugs that they have experienced themselves and implementing features that mean something to them (&quot;scratch your own itch&quot;).
While I agree with these points and have tried to make them clearer in the post, I have to stress that the main point of this post is to help people get ideas when they don't have ideas of their own.
Therefore, regardless of their programming skills and the impact of fixing a TODO, I do think that looking through TODOs will help in generating ideas.&lt;/p&gt;

&lt;hr/&gt;


&lt;p&gt;I often talk to students that want to contribute to open-source projects, but just don't have an idea what to work on.
Here's a tip if you're in a similar situation (e.g. you want to apply for &lt;a href=&quot;http://code.google.com/soc/&quot;&gt;GSOC&lt;/a&gt;) :&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; git clone repository_url_of_some_open_source_project target_directory
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; grep -RIn TODO target_directory/*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So, &lt;strong&gt;find the URL of the repository project you want to contribute to, checkout the repository using git/mercurial/svn and then find all the TODOs in the source code using grep&lt;/strong&gt;.
The &lt;code&gt;-RIn&lt;/code&gt; flags will tell grep to do a recursive search (-R), skip binary files (-I) and include line numbers (-n) for results.
And that's it!
Go through the results and pick whatever you find interesting and within your skill range.&lt;/p&gt;

&lt;p&gt;Most open-source projects have issue trackers for organizing bug reports and feature requests that need to be worked on.
However, some projects don't use issue trackers, and there's an important difference between issues in these trackers and what you'll find by digging through the source code.
Issues are commonly a result of &lt;em&gt;using&lt;/em&gt; a system or library, they are created by users, and focus on bugs and features.
TODOs on the other hand are a result of &lt;em&gt;system development&lt;/em&gt; and are created by developers.
Software developers often make notes (TODOs) of things that should be fixed or could be done in a better way, but don't have the time to do it right away.&lt;/p&gt;

&lt;p&gt;These notes are focused more on improving the internal operation of the system and code quality, rather than on externally observable features, and include anything from checking specific algorithm edge-cases to larger refactoring ideas.
And as time goes by, these &lt;strong&gt;TODOs are often forgotten since they are not systematically tracked and more effort is put into developing new features and fixing bugs&lt;/strong&gt;.
So, if you really want to get your hands dirty, TODOs are a good place to start looking for work.
At first, project owners and maintainers will often be cautious about letting you hack into system internals and refactor, but will generally be very grateful if you really want to fix those forgotten TODOs.
In a way, it's often a bit harder to start working on a TODO than on an tracked issue.&lt;/p&gt;

&lt;p&gt;Here's the number of TODOs and FIXMEs for the top 15 watched projects on GitHub:&lt;/p&gt;

&lt;table border=&quot;1&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Project name&lt;/th&gt;
      &lt;th&gt;Number of TODOs + FIXMEs&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;bootstrap&lt;/td&gt;
      &lt;td&gt;7+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;nodejs&lt;/td&gt;
      &lt;td&gt;904+278 (many of these are v8 TODOs)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;rails&lt;/td&gt;
      &lt;td&gt;77+55&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;jquery&lt;/td&gt;
      &lt;td&gt;7+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;html5-boilerplate&lt;/td&gt;
      &lt;td&gt;2+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;homebrew&lt;/td&gt;
      &lt;td&gt;22+6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;spoon-knife&lt;/td&gt;
      &lt;td&gt;0+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;impress.js&lt;/td&gt;
      &lt;td&gt;0+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;backbone&lt;/td&gt;
      &lt;td&gt;4+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;diaspora&lt;/td&gt;
      &lt;td&gt;16+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;three20&lt;/td&gt;
      &lt;td&gt;25+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;devise&lt;/td&gt;
      &lt;td&gt;2+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;jquery-mobile&lt;/td&gt;
      &lt;td&gt;60+0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;three.js&lt;/td&gt;
      &lt;td&gt;43+6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;express&lt;/td&gt;
      &lt;td&gt;3+0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;Of course, in some projects you won't find any TODOs, in others you'll find false positives and TODOs from 3rd party libraries, but in general - forgotten TODOs are a cool way of finding ideas for contributing to open-source projects.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Back to blogging</title>
   <link href="http://ivanzuzak.info/2012/02/24/back-to-blogging.html"/>
   <updated>2012-02-24T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2012/02/24/back-to-blogging</id>
   <content type="html">&lt;p&gt;Forgive me, InterWebs, for it has been a year since my &lt;a href=&quot;http://ivanzuzak.info/2011/02/18/github-hosted-comments-for-github-hosted-blogs.html&quot;&gt;last blog post&lt;/a&gt;.
2011 was a very busy+wonderful year for me, and I've had the opportunity to meet many nice people, visit many cool places and work on many interesting projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I gave &lt;a href=&quot;http://ivanzuzak.info/#talks&quot;&gt;a talk&lt;/a&gt; at the &lt;a href=&quot;http://kmi.open.ac.uk/&quot;&gt;Knowledge Media Institute&lt;/a&gt; of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Open_University&quot;&gt;Open University, UK&lt;/a&gt; about inter-widget communication based on &lt;a href=&quot;http://arxiv.org/abs/1108.4770&quot;&gt;the work&lt;/a&gt; that &lt;a href=&quot;https://plus.google.com/105493585317824062514/&quot;&gt;Marko&lt;/a&gt; and I did in this field.
I've had the pleasure of meeting &lt;a href=&quot;http://kmi.open.ac.uk/people/member/fridolin-wild&quot;&gt;Fridolin Wild&lt;/a&gt;, who organized the talk, and his research group at the KMI.
I also published &lt;a href=&quot;http://ivanzuzak.info/#talks&quot;&gt;two papers&lt;/a&gt; on inter-widget communication and the &lt;a href=&quot;https://github.com/izuzak/pmrpc&quot;&gt;pmrpc library&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I published &lt;a href=&quot;http://ivanzuzak.info/#talks&quot;&gt;two papers&lt;/a&gt; on the FSM-based formalism for modeling RESTful systems and presented one of the papers at the &lt;a href=&quot;http://icwe2011.webengineering.org/&quot;&gt;ICWE conference&lt;/a&gt; (held in Paphos, Cyprus).
I've also had the pleasure of meeting &lt;a href=&quot;http://www.fernuni-hagen.de/dvt/en/team/silvia.schreier.shtml&quot;&gt;Silvia Schreier&lt;/a&gt;, discussing many REST-related ideas with her and starting work on &lt;a href=&quot;https://github.com/izuzak/feral&quot;&gt;Feral&lt;/a&gt; (a framework for developing RESTful systems).&lt;/li&gt;
&lt;li&gt;For the &lt;a href=&quot;http://www.fer.unizg.hr/en/course/plt&quot;&gt;Programming Language Translation course&lt;/a&gt; at the University of Zagreb (where I work as a teaching assistant), I've implemented an &lt;a href=&quot;http://ivanzuzak.info/FRISCjs/webapp/&quot;&gt;assembler and simulator for a simple RISC processor, in pure JavaScript&lt;/a&gt;, which can be used in Web browsers and in NodeJS apps.&lt;/li&gt;
&lt;li&gt;I also played with &lt;a href=&quot;http://ivanzuzak.info/cro_lotto_analysis/index.html&quot;&gt;randomness analyses for two lotto systems in Croatia&lt;/a&gt;, but since statistics isn't my strongest side, I'm quite far from interesting results.
Something similar to the &lt;a href=&quot;http://www.lottery.co.uk/statistics/&quot;&gt;statistics for UK lotteries&lt;/a&gt;.
And yes, I do know that lotto really &lt;strong&gt;is&lt;/strong&gt; random.&lt;/li&gt;
&lt;li&gt;Finally, I'm nearing the deadline for finishing my Ph.D.
I'm nearly done with my last seminar, and I'm working on my thesis and thinking about what the future will bring.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://thisweekinrest.wordpress.com/&quot;&gt;This Week In REST&lt;/a&gt; is still alive and popular, but I update it less frequently due to lack of time.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So, over the next few months I'll (hopefully) be writing blog posts about some of these things, especially REST.
I've already updated a few of my &lt;a href=&quot;http://ivanzuzak.info/2011/02/18/github-hosted-comments-for-github-hosted-blogs.html&quot;&gt;old&lt;/a&gt; &lt;a href=&quot;http://ivanzuzak.info/2009/08/27/how-to-supercharge-your-free-appengine-quota.html&quot;&gt;posts&lt;/a&gt; that continuously generate interest.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>GitHub hosted comments for GitHub hosted blogs</title>
   <link href="http://ivanzuzak.info/2011/02/18/github-hosted-comments-for-github-hosted-blogs.html"/>
   <updated>2011-02-18T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2011/02/18/github-hosted-comments-for-github-hosted-blogs</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT (January 25 2011): A while back, the GitHub team has updated the GitHub API to v3 which is now even more cool. Since the &lt;a href=&quot;http://developer.github.com/v3/&quot;&gt;new API&lt;/a&gt; supports fetching both the Markdown source and the HTML rendering of a comment, this eliminates the need for rendering the comments on the client-side using the Showdown library as it was done before. I've updated the blog post to reflect this and some other minor API changes.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recently &lt;a href=&quot;http://ivanzuzak.info/2011/01/02/enabling-pubsubhubbub-for-github-hosted-blogs.html&quot;&gt;switching&lt;/a&gt; from a Wordpress.com-hosted blog to a GitHub hosted blog made me curious if blog comments could also be somehow hosted on GitHub. Why host comments on GitHub? Other than it being cool, open and hackable, it would enable that &lt;em&gt;all&lt;/em&gt; content for the blog be hosted on GitHub.&lt;/p&gt;

&lt;p&gt;So, here's what I wanted from the future commenting system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;must be hosted completely on GitHub.&lt;/li&gt;
&lt;li&gt;must be tied to the GitHub repository which hosts the blog.&lt;/li&gt;
&lt;li&gt;must provide user login, tie each comment with the user who made the comment, and give both blog owners and users control over their comments.&lt;/li&gt;
&lt;li&gt;must be possible to pull the comments for a post from the system and show them on the post's Web page.&lt;/li&gt;
&lt;li&gt;should be easy to set-up by the blog owner and easy to use by blog readers.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;These requirements ruled out using &lt;a href=&quot;https://gist.github.com&quot;&gt;Gists&lt;/a&gt;, asking users to fork the repository and submit pull-request to a special comments file (heh, this was actually the first thing that I thought of) or using any external service for comment creation and/or hosting.&lt;/p&gt;

&lt;p&gt;The solution I came up with is to use the &lt;a href=&quot;https://github.com/blog/411-github-issue-tracker&quot;&gt;GitHub issue tracker&lt;/a&gt; for creating and hosting comments and the &lt;a href=&quot;http://developer.github.com/v3/&quot;&gt;GitHub API&lt;/a&gt; for pulling comments from the issues into the blog's Web page &lt;del&gt;and &lt;a href=&quot;http://github.github.com/github-flavored-markdown/&quot;&gt;GitHub Flavored Markdown&lt;/a&gt; for rendering comments within the Web page using JavaScript&lt;/del&gt;. Here's how all of this works.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;GitHub hosted comments for GitHub hosted blogs&quot; src=&quot;http://ivanzuzak.info/images/github_issues.png&quot; alt=&quot;&quot; width=&quot;90%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;First, for each blog post you plan to publish, create an issue in your blog's GitHub repository issue tracker. For example, here's &lt;a href=&quot;https://github.com/izuzak/izuzak.github.com/issues/12&quot;&gt;the issue for this blog posts&lt;/a&gt;. Notice that all issues have a common base URL (&lt;code&gt;https://github.com/izuzak/izuzak.github.com/issues/&lt;/code&gt; in my example) and a unique id (&lt;code&gt;12&lt;/code&gt; in my example). Readers of your blog will use the issue tracker if they want to leave a comment.&lt;/p&gt;

&lt;p&gt;Second, add a link to each of your blog posts pointing to the Web page of the issue you created for comments. Since, you're probably using &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt; to generate your blog, a simple way of doing this is to add the above mentioned id of the issue to the &lt;a href=&quot;https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter&quot;&gt;YAML front matter&lt;/a&gt; block of each blog post and then add a &lt;a href=&quot;https://github.com/mojombo/jekyll/wiki/Liquid-Extensions&quot;&gt;Liquid template&lt;/a&gt; in your &lt;a href=&quot;https://github.com/mojombo/jekyll/wiki/Usage&quot;&gt;layout file&lt;/a&gt; to retrieve the id and generate the full issue URL. For example, here's the YAML front matter for the blog post your reading (&lt;code&gt;commentIssueId&lt;/code&gt; is the id of the post's issue in the repository Issue tracker):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;post&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;GitHub hosted comments for GitHub hosted blogs&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;github, blog, comments, hosting&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;commentIssueId&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And here's the snippet of the layout file for generating blog posts (&lt;code&gt;page.commentIssueId&lt;/code&gt; part surrounded with curly braces is the Liquid template which pulls the &lt;code&gt;commentIssueId&lt;/code&gt; of the post):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;comments&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt;   &lt;span class=&quot;nt&quot;&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Comments&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;header&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;     Want to leave a comment? Visit &lt;span class=&quot;nt&quot;&gt;&amp;lt;a&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;https://github.com/izuzak/izuzak.github.com/issues/{{page.commentIssueId}}&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt; this post&amp;#39;s issue page on GitHub&lt;span class=&quot;nt&quot;&gt;&amp;lt;/a&amp;gt;&lt;/span&gt; (you&amp;#39;ll need a GitHub account. What? Like you already don&amp;#39;t have one?!).
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt;   &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Third, add a JavaScript script to each blog posts which pulls the post's comments from the issue using the GitHub API. The &lt;a href=&quot;http://developer.github.com/v3/issues/&quot;&gt;GitHub issues API&lt;/a&gt; is exactly what we need here - make an &lt;del&gt;JSONP&lt;/del&gt; XHR request to the API endpoint and you'll receive all the comments for a specific issue. For each comment you get the GitHub user id and gravatar id of the person who made the comment, the comment id in the issue, created and updated timestamps and the body of the comment. Again, since you're probably using Jekyll, it's easiest if you put the code in the layout file for blog posts. For example, here's the code for pulling in the comments for this blog post, using &lt;a href=&quot;http://api.jquery.com/jQuery.ajax/&quot;&gt;jQuery&lt;/a&gt; (notice again that you need a Liquid template to specify the URL of the issue for which you want to pull the comments):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;loadComments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;https://api.github.com/repos/izuzak/izuzak.github.com/issues/12/comments&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Accept&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;application/vnd.github.full+json&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;       &lt;span class=&quot;nx&quot;&gt;loadComments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But wait, doesn't the &lt;a href=&quot;http://en.wikipedia.org/wiki/Same_origin_policy&quot;&gt;same-origin policy&lt;/a&gt; (SOP) apply when making an XHR request to the GitHub API endpoint from the blog's page? Yes, yes it does. And until recently, the only way to get around SOP for accessing the GitHub API was to use &lt;a href=&quot;http://en.wikipedia.org/wiki/JSONP&quot;&gt;JSONP&lt;/a&gt;. However, using JSONP disables the possibility of setting HTTP request headers which we need to correctly set the desired API response media type via the &lt;code&gt;Accept&lt;/code&gt; header (see code above). However, as of recently, GitHub supports the &lt;a href=&quot;http://www.w3.org/TR/cors/&quot;&gt;CORS specification&lt;/a&gt; which enables cross-origin requests. The &lt;a href=&quot;http://developer.github.com/v3/#cross-origin-resource-sharing&quot;&gt;way in which GitHub enables CORS for its API&lt;/a&gt; is by requiring API users to register the Web sites that access the API as OAuth applications. Therefore, in order to enable CORS for a GitHub-hosted blog, you need to go to the &lt;a href=&quot;https://github.com/account/applications/new&quot;&gt;GitHub form for registering OAuth applications&lt;/a&gt; and create a new application by specifying your blog's URL in the Main URL field and the Callback URL field. Notice that this approach works (and is the same) both for blogs on GitHub subdomains (e.g. &lt;code&gt;izuzak.github.com&lt;/code&gt;) and for blogs hosted on GitHub that have a &lt;a href=&quot;http://pages.github.com/#custom_domains&quot;&gt;custom domain&lt;/a&gt; (e.g. &lt;code&gt;http://ivanzuzak.info&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;GitHub OAuth application registration form&quot; src=&quot;http://ivanzuzak.info/images/github_oauth.png&quot; alt=&quot;&quot; width=&quot;90%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Fourth, insert the pulled comment data into the blog post's HTML &lt;del&gt;and render the body of the comments using &lt;a href=&quot;http://github.github.com/github-flavored-markdown/&quot;&gt;GitHub Flavored Markdown&lt;/a&gt;. Inserting the comment data into the DOM is easy once you decide which data you want to display. However, since issue comments may be written in GitHub Flavored Markdown, some JavaScrip code is needed to translate the comment to HTML. Fortunately, GitHub has a &lt;a href=&quot;https://github.com/github/github-flavored-markdown&quot;&gt;JavaScript library&lt;/a&gt; for that also - a modified version of the &lt;a href=&quot;https://github.com/coreyti/showdown&quot;&gt;Showdown library&lt;/a&gt; for converting Markdown into HTML.&lt;/del&gt; Since the pulled data contains a HTML rendering of the comment's Markdown source, there's no need to do any processing of the comment text. Again, it's easiest if you put the code in the layout file for blog posts. For example, here's the code which I use for inserting comments:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://datejs.googlecode.com/svn/trunk/build/date-en-US.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;loadComments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;       &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cuser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;       &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cuserlink&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;https://www.github.com/&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;       &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;clink&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;https://github.com/izuzak/izuzak.github.com/issues/12#issuecomment-&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lastIndexOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;       &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cbody&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;body_html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;       &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cavatarlink&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;avatar_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;       &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cdate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;created_at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;yyyy-MM-dd HH:mm:ss&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;       &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;#comments&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;div class=&amp;#39;comment&amp;#39;&amp;gt;&amp;lt;div class=&amp;#39;commentheader&amp;#39;&amp;gt;&amp;lt;div class=&amp;#39;commentgravatar&amp;#39;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;lt;img src=&amp;quot;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cavatarlink&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;quot; alt=&amp;quot;&amp;quot; width=&amp;quot;20&amp;quot; height=&amp;quot;20&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/div&amp;gt;&amp;lt;a class=&amp;#39;commentuser&amp;#39; href=\&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cuserlink&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;\&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cuser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/a&amp;gt;&amp;lt;a class=&amp;#39;commentdate&amp;#39; href=\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;clink&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;\&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cdate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;#39;commentbody&amp;#39;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cbody&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Also notice that I use the &lt;a href=&quot;http://www.datejs.com/&quot;&gt;DateJS library&lt;/a&gt; to pretty-print the comment dates and that I fetch the Gravatar images of users who made the comments.&lt;/p&gt;

&lt;p&gt;Finally, add CSS rules to make the comments look pretty. And if you're extra geeky and love GitHub like me, make the comments look like GitHub code comments:&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;GitHub hosted comments for GitHub hosted blogs&quot; src=&quot;http://ivanzuzak.info/images/github_comments.png&quot; alt=&quot;&quot; width=&quot;90%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And that's it! Creating the system was really easy - GitHub already had all the pieces necessary (Issue tracker, API, OAuth application registration form&lt;del&gt;, Markdown JavaScript library&lt;/del&gt;) and all I needed was a bit of glue to tie all of them together. I'm using this as the commenting system for my blog until some serious problem turns up. I like how the system integrates with GitHub login, how all blog comments are visible on the issue page and the overall simplicity of using the system. What I didn't find an easy way of doing is creating issue comments directly from the a blog post's Web page, without making the user navigate to the Issue tracker page (really hard to do without an external service since the blog is a static site). Other than that, I'm not sure what will happen when spam bots start invading GitHub issue trackers.&lt;/p&gt;

&lt;p&gt;You can see the complete code I'm using for the commenting system in the following files: &lt;a href=&quot;https://github.com/izuzak/izuzak.github.com/blob/master/_layouts/post.html#L24-L55&quot;&gt;general layout for blog posts&lt;/a&gt; and &lt;a href=&quot;https://github.com/izuzak/izuzak.github.com/blob/master/css/screen.css#L228-L395&quot;&gt;CSS rules&lt;/a&gt;. Let me know if you find a better system for hosting blog comments on GitHub or improving this one. &lt;a href=&quot;http://www.twitter.com/izuzak&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Enabling PubSubHubBub for GitHub hosted blogs</title>
   <link href="http://ivanzuzak.info/2011/01/02/enabling-pubsubhubbub-for-github-hosted-blogs.html"/>
   <updated>2011-01-02T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2011/01/02/enabling-pubsubhubbub-for-github-hosted-blogs</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT (August 20 2012)&lt;/strong&gt;:&lt;/em&gt; &lt;a href=&quot;https://github.com/sergeylukin&quot;&gt;Sergey Lukin&lt;/a&gt; has been doing some digging and discovered two very interesting things which make some of the claims in my post no longer valid.&lt;/p&gt;

&lt;p&gt;First, GitHub now allows URL query parameters in post-commit Web hooks. Although this isn't mentioned in &lt;a href=&quot;https://help.github.com/articles/post-receive-hooks&quot;&gt;the official docs&lt;/a&gt;, it just works. In other words, you can specify a Web hook URL like &lt;code&gt;http://your.server.com/web_hook_resource?param1=value1&amp;amp;param2=value2&lt;/code&gt; and GitHub will make a POST request to the full URL, without discarding the query parameters, as before.&lt;/p&gt;

&lt;p&gt;Second, the reference PubSubHubBub hub at http://pubsubhubbub.appspot.com doesn't strictly follow the &lt;a href=&quot;http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#anchor9&quot;&gt;PSHB specification with regard to the parameters passed in the new content notification HTTP POST request&lt;/a&gt;. Specifically, the spec says that the hub will read the notification parameters from the HTTP request &lt;em&gt;body&lt;/em&gt;. However, the notification request will be correctly processed even if the parameters are specified as URL query parameters, not in the message body. The reason why this works is that the reference hub is hosted on Google's AppEngine and implemented using the webapp2 Python framework. This framework &lt;a href=&quot;http://webapp-improved.appspot.com/guide/request.html&quot;&gt;parses parameters both from the message body and URL query part and exposes them as a single object&lt;/a&gt;, making it irrelevant how a parameter was actually passed.&lt;/p&gt;

&lt;p&gt;The result of these two discoveries is that you no longer need to use a proxy server to ping a PSHB hub using GitHub post-commit hooks, as described in the blog post below. You can just use a direct Web Hook to the reference hub. For example, I would specify this URL as the Web Hook to ping the hub when my blog's ATOM feed is updated: &lt;code&gt;http://pubsubhubbub.appspot.com/publish?hub.mode=publish&amp;amp;hub.url=http%3A%2F%2Fivanzuzak.info%2Fatom.xml&lt;/code&gt;. Just replace the value of the hub.url parameter with your blog's ATOM/RSS feed URL and that's it!&lt;/p&gt;

&lt;p&gt;However, again, notice that this works only because the reference PSHB hub is not strictly following the PSHB specification. If you are using another PSHB hub, check that it can accept parameters passed in the URL query part.&lt;/p&gt;

&lt;p&gt;Great work, Sergey!!&lt;/p&gt;

&lt;hr/&gt;


&lt;p&gt;I've recently switched from a &lt;a href=&quot;http://izuzak.wordpress.com/&quot;&gt;Wordpress.com hosted blog&lt;/a&gt; to a &lt;a href=&quot;http://ivanzuzak.info&quot;&gt;GitHub hosted blog&lt;/a&gt; on a custom domain using &lt;a href=&quot;http://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;. And one of the first things I wanted to enable for the new blog was &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot;&gt;PubSubHubBub&lt;/a&gt; (PSHB) support. Generally, in order to enable PSHB for a blog, two things need to be done:&lt;/p&gt;

&lt;p&gt;1) add a &lt;code&gt;&amp;lt;link rel=&quot;hub&quot; href=&quot;http://url.of.a.pshb.hub&quot; /&amp;gt;&lt;/code&gt; to the blog's ATOM feed, linking to a PSHB hub, e.g. the reference hub running on appengine &lt;code&gt;http://pubsubhubbub.appspot.com&lt;/code&gt; (see &lt;a href=&quot;http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#discovery&quot;&gt;PSHB specification Section 5. - Discovery&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;2) every time a new blog post is created or an old blog post is updated - notify the hub from step 1) by making a HTTP POST request with the body containing the blog's ATOM feed URL (see &lt;a href=&quot;http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#anchor9&quot;&gt;PSHB specification Section 7.1. - New Content Notification&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;For GitHub hosted blogs, step 1) isn't a problem as it only requires you to insert one line of text into your blog's ATOM XML feed. However, step 2) is a problem. The good news is that &lt;strong&gt;each GitHub Pages site is also a GitHub repository and GitHub supports service hooks&lt;/strong&gt;, predefined services which GitHub notifies each time the repository is pushed to. The bad news is that, although many services like Twitter and Campfire are supported, PubSubHubBub hubs are not supported. So basically, you need to make a custom service. Now, a special type of service hooks are &lt;strong&gt;generic &lt;a href=&quot;http://help.github.com/post-receive-hooks/&quot;&gt;post-receive hooks&lt;/a&gt;, user-specified URLs (also called &lt;a href=&quot;http://wiki.webhooks.org/&quot;&gt;webhooks&lt;/a&gt;)&lt;/strong&gt; to which GitHub makes a HTTP POST request each time the repository is pushed to. And now for more bad news. First, HTTP POST requests made to post-receive hook URLs have a predefined and non-changeable message body. Therefore, because a PSHB notify request must contain certain parameters in the body of the HTTP POST request, there is no way of specifying these parameters since the body is predefined by GitHub. Second, requests made to post-receive hook URLs are stripped from the URL query part. Therefore, even if PSHB supported passing notification parameters through the query part of the request URL, GitHub wouldn't allow that either. I've asked about this issue on the GitHub forum and &lt;a href=&quot;http://support.github.com/discussions/post-receive-issues/149-the-query-part-of-post-receive-urls-is-disregarded-before-making-the-post-request&quot;&gt;got a semi-satisfying response&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Until there's a better solution, here's an ugly-hack solution&lt;/strong&gt;. I created an AppEngine proxy service, to be used as a post-receive hook, which makes PSHB notifications only to the &lt;a href=&quot;http://pubsubhubbub.appspot.com/&quot;&gt;reference PSHB hub&lt;/a&gt; when a POST request is made to the service. Since GitHub doesn't allow query parameters in the URL, the proxy service will expect the blog's ATOM feed URL to be passed as &lt;em&gt;the suffix of the path part of the URL&lt;/em&gt; (e.g. instead of making a request to &lt;code&gt;http://www.service.com?blogUrl=http://some.url.com&lt;/code&gt;, a request would be made to &lt;code&gt;http://www.service.com/http://some.url.com&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;So, here's a &lt;strong&gt;step-by-step guide for enabling PubSubHubBub for your GitHub hosted blog&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;1) Add the following lines to your blog's ATOM feed XML:&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;link href=&quot;http://url.of.your.blogs.atom.feed.xml&quot; rel=&quot;self&quot;/&amp;gt;
&amp;lt;link href=&quot;http://pubsubhubbub.appspot.com/&quot; rel=&quot;hub&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;where &lt;code&gt;http://url.of.your.blogs.atom.feed.xml&lt;/code&gt; is what it says it is - the URL of your blog's ATOM feed (e.g. mine is &lt;code&gt;http://ivanzuzak.info/atom.xml&lt;/code&gt;). If this line is already present in your blog's ATOM feed, you don't have to add it again. Naturally, you will perform this step by editing your atom.xml source file and push it to the GitHub repository hosting your blog. You can see my atom.xml source &lt;a href=&quot;https://github.com/izuzak/izuzak.github.com/blob/master/atom.xml&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;2) Open the admin page for the GitHub project hosting your blog and navigate to the Service hooks tab. Now, add a new post-receive hook with the following URL:&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;http://urlreq.appspot.com/pshbpinggae/http://url.of.your.blogs.atom.feed.xml
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;

&lt;p&gt;where, &lt;code&gt;urlreq.appspot.com&lt;/code&gt; is the AppEngine proxy service I mentioned earlier and, again, &lt;code&gt;http://url.of.your.blogs.atom.feed.xml&lt;/code&gt; is what it says it is - the URL of your blog's ATOM feed. For example, the post-receive hook URL for my blog is &lt;code&gt;http://urlreq.appspot.com/pshbpinggae/http://ivanzuzak.info/atom.xml&lt;/code&gt;. Passing parameters this way is really ugly, but currently there's no better way of doing it.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;PubSubHubBub support for GitHub hosted blogs&quot; src=&quot;http://ivanzuzak.info/images/pshb_github_gae_ss.png&quot; alt=&quot;&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now every time you push a new blog post to the blog's GitHub repository, GitHub will make a POST request to the urlreq AppEngine proxy service, the service will notify the reference PSHB hub, the hub will fetch your blog's ATOM feed and notify all subscribers of the new feed entry. And if you make a commit the the repository which doesn't contain a new blog post, the service will still notify the hub, but the hub is smart enough to detect that no new entries are present in the ATOM feed so no subscribers will be notified.&lt;/p&gt;

&lt;p&gt;GitHub pages are really cool for hosting blogs and GitHub should do more in supporting them - it would be cool if a PubSubHubBub service hook was added to the list of Service hooks or if generic post-receive hooks supported specifying custom parameters for the hooks (either through the URL query part or through the HTTP request body). &lt;a href=&quot;http://www.twitter.com/izuzak&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Pmrpc discovery and publish-subscribe support + systematization of cross-context browser communication systems</title>
   <link href="http://ivanzuzak.info/2010/06/15/pmrpc-discovery-and-publish-subscribe-support-systematization-of-cross-context-browser-communication-systems.html"/>
   <updated>2010-06-15T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2010/06/15/pmrpc-discovery-and-publish-subscribe-support-systematization-of-cross-context-browser-communication-systems</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT 29 August 2011: I've published two papers on concepts presented in this blog post. First, I've published a paper about the Pmrpc library, its architecture and benefits over other libraries, at the MIPRO 2011 conference. Also, I've published a paper about the classification framework for cross-context communication in Web browsers. The paper presents a more detailed and advanced analysis of cross-context communication than the one addressed in the second part of this blog post. Furthermore, a few moths ago I gave a talk on inter-widget communication at the Open University, UK. Since inter-widget communication significantly overlaps with cross-context communication, the talk touches on many concepts from the cross-context communication framework. Links for downloading the papers and presentation slides are in the &lt;a href=&quot;http://ivanzuzak.info/#talks&quot;&gt;talks and papers section&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://code.google.com/p/pmrpc/&quot; target=&quot;_blank&quot;&gt;pmrpc&lt;/a&gt; cross-context browser communication library has grown from the &lt;a href=&quot;http://wp.me/poYaf-44&quot; target=&quot;_blank&quot;&gt;last time I blogged about it&lt;/a&gt;. Last time I wrote about adding support for RPC-style communication for &lt;a href=&quot;http://www.whatwg.org/specs/web-workers/current-work/&quot; target=&quot;_blank&quot;&gt;WebWorkers&lt;/a&gt;. Today I'll first introduce two new features - dynamic &lt;strong&gt;discovery of remote procedures&lt;/strong&gt; and a&lt;strong&gt; publish-subscribe communication model&lt;/strong&gt;. Also, I'll write about our &lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/IWCProjects&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;systematization of existing systems for cross-context browser communication&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Discovery and publish subscribe&lt;/h2&gt;


&lt;p&gt;Up until now, pmrpc supported only &lt;a href=&quot;http://en.wikipedia.org/wiki/Remote_procedure_call&quot; target=&quot;_blank&quot;&gt;remote procedure call&lt;/a&gt; as the communication model for inter-window and WebWorker communication. This model of communication is based on a client-server interaction where the client both a) has an object reference of the destination window/webworker context and b) knows the name of the remote procedure it wants to call. Here's an example of a pmrpc RPC call:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// server [window object A] exposes a procedure in it&amp;#39;s window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// client [window object B] calls the exposed procedure remotely, from its own window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;myIframe&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This works well for cases when the client knows how to obtain a reference of the server context object. However, it turns out that in many &lt;a href=&quot;http://groups.google.com/group/pmrpc/browse_thread/thread/1a63a34971fd816e#&quot; target=&quot;_blank&quot;&gt;real-world&lt;/a&gt; &lt;a href=&quot;http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-September/022940.html&quot; target=&quot;_blank&quot;&gt;cases&lt;/a&gt; &lt;strong&gt;the client &lt;/strong&gt;&lt;strong&gt;does not know which window/iframe/worker implements the procedure it wants to call&lt;/strong&gt;. Mashups and widget portals are the best example. Imagine that both the client and the server are widgets on &lt;a href=&quot;http://www.google.com/ig&quot; target=&quot;_blank&quot;&gt;iGoogle&lt;/a&gt;. Although you may be in control of both the client and server iframe contents, in most cases you will not know the names of iframe elements which contain them and which are located on the top container page. And you need the values of the name attributes so that you can obtain a reference to the iframe object which you could then use to call postMessage.&lt;/p&gt;

&lt;p&gt;This referencing problem was the motivation for implementing both the discovery and publish-subscribe features. Both features enable clients to call a remote procedure without a-priori knowing which destination object implements the  procedure. First, the&lt;strong&gt; publish-subscribe feature&lt;/strong&gt; enables clients to perform a remote call without specifying the destination context object reference. If a publish-subscribe call is made, the pmrpc infrastructure will make a RPC call for the specified procedure to all window, iframe and WebWorker object it can find (thus simulating a &quot;publish&quot; event on a channel named by the remote procedure name). The API for using the publish-subscribe feature is simple; it reuses the &lt;em&gt;pmrpc.call&lt;/em&gt; method and instead of passing the reference of the destination context object, a &quot;publish&quot; string parameter is passed instead:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// server [window object A] exposes a procedure in it&amp;#39;s window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// client [window object B] calls the exposed procedure remotely, from its own window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;publish&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Under the hood, the publish-subscribe feature uses the discovery feature to discover all window, iframe and WebWorker context objects and retrieves their references. Also, the publish-subscribe feature may be used with &lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcApiDocs&quot; target=&quot;_blank&quot;&gt;other pmrpc features&lt;/a&gt;, like access control and retries.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;discovery feature&lt;/strong&gt; enables dynamic discovery of procedures registered at remote contexts and their filtering using various optional criteria. Discovered procedures may be filtered by the destination window/iframe/webworker context object, destination context origin (specified as a regular expression) and destination procedure name (also specified as a regular expression). For each discovered procedure that wasn't filtered out, the procedure name, origin of the destination context, the access control rules specified for the procedure and the destination context object. The feature is implemented as a &lt;strong&gt;new pmrpc method&lt;/strong&gt; - &lt;em&gt;pmrpc.discover&lt;/em&gt;. The method is asynchronous and accepts a parameter object which specifies the filters and a callback method which will be called when all registered procedures are discovered. Here's an example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// server [window object A] exposes a procedure in it&amp;#39;s window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// client [window object B] discovers and calls the exposed procedure remotely, from its own window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoCallback&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoveredProcedures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoveredProcedures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoveredProcedures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoveredProcedures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;destinationOrigin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoveredProcedures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;procedureACL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;       &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;discoveredProcedures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;       &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;       &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discover&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;someiFrameName&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;myIframe&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;origin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;.*goodOrigin.*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;.*Hello.*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;discoCallback&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The implementation of the discover method is based on &lt;strong&gt;recursively visiting every iframe in the window.frames object starting from window.top&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;The method fetches a reference to the top window object (window.top), adds the reference to the result array and repeats the procedure for each nested iframe (by iterating through the window.frames object). This way, all iframes in the current window are visited. This process is depicted by the figure below.&lt;/li&gt;
    &lt;li&gt;The method adds all local web worker objects to the result array.&lt;/li&gt;
    &lt;li&gt;On each context object in the result array, a special pmrpc infrastructure method is invoked to obtain a list of registered procedures.&lt;/li&gt;
    &lt;li&gt;The list of all obtained procedures is filtered by the specified criteria.&lt;/li&gt;
    &lt;li&gt;The method invokes the callback, passing the list of discovered procedures as a parameter.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;It's not an ideal way of discovering remote contexts, but it's better than nothing and works with the latest versions of all major browsers.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Discovery architecture&quot; src=&quot;/images/discoarchitecture-1.png&quot; alt=&quot;&quot; width=&quot;100%&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Systematization of cross-context browser communication systems&lt;/h2&gt;


&lt;p&gt;It's evident that the WWW is becoming ever more componentized as almost every web site is a mashup, contains widgets or uses WebWorkers. As a result, there has been a increase in development of systems that enable communication between these different browser contexts - windows, iframes and WebWorkers. Pmrpc is only one example of such system and lots of other systems exist. However, as the number of these systems increases, the&lt;strong&gt; understanding of each systems' capabilities and their comparison and evaluation becomes a more difficult task&lt;/strong&gt; since no effort is being made to systematize this ecosystem.&lt;/p&gt;

&lt;p&gt;This is why &lt;a href=&quot;http://twitter.com/ivankovic_42&quot; target=&quot;_blank&quot;&gt;Marko&lt;/a&gt; and I are trying to create a &lt;strong&gt;systematization of existing cross-context communication systems&lt;/strong&gt;. Our work on this systematization is in its early stages but is openly available to anyone at a &lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/IWCProjects&quot; target=&quot;_blank&quot;&gt;pmrpc wiki page&lt;/a&gt;. At the moment we are trying to do the following:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Make a list of all mechanisms for cross-context communication. We are including both in-browser mechanisms like the postMessage API, cookies and URL fragment, and 3rd party libraries like &lt;a href=&quot;http://easyxdm.net/&quot; target=&quot;_blank&quot;&gt;easyXDM&lt;/a&gt; and pmrpc.&lt;/li&gt;
    &lt;li&gt;Define &lt;strong&gt;dimensions for classifying the gathered systems&lt;/strong&gt;. Each dimension defines a system characteristic whereas values along each dimension define a set of possible design choices.  Currently, we have defined about a dozen dimension and are still thinking some through. Here are some examples: &lt;em&gt;Type of system&lt;/em&gt; (browser built-in, pure client-side framework, server-mediated initialization framework, server-mediated communication framework), &lt;em&gt;Transport mechanism&lt;/em&gt; (cookies, URL fragment, postMessage, ...), &lt;em&gt;Programming model&lt;/em&gt; (message-oriented, shared memory, RPC, publish-subscribe).&lt;/li&gt;
    &lt;li&gt;Evaluate the listed systems according to the defined dimensions.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I'd &lt;a href=&quot;http://groups.google.com/group/pmrpc&quot; target=&quot;_blank&quot;&gt;love to hear&lt;/a&gt; what you think of the new pmrpc features and the systematization (see more examples at our &lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcApiDocs&quot; target=&quot;_blank&quot;&gt;API docs page&lt;/a&gt;)! Do you know of any cross-context communication systems that are not listed? Do you think some other system characteristic should be included in the classification? &lt;a href=&quot;http://twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why understanding REST is hard and what we should do about it - systematization, models and terminology for REST</title>
   <link href="http://ivanzuzak.info/2010/04/03/why-understanding-rest-is-hard-and-what-we-should-do-about-it-systematization-models-and-terminology-for-rest.html"/>
   <updated>2010-04-03T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2010/04/03/why-understanding-rest-is-hard-and-what-we-should-do-about-it-systematization-models-and-terminology-for-rest</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT 29 August 2011: I've published a paper on the FSM-based formalism for describing RESTful systems at the &lt;a href=&quot;http://icwe2011.webengineering.org/&quot;&gt;ICWE 2011 conference&lt;/a&gt;. The formalism presented in the paper is a more detailed and advanced version of the one presented in the second part of this blog post. Links for downloading the paper and presentation slides are in the &lt;a href=&quot;http://ivanzuzak.info/#talks&quot;&gt;talks and papers section&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT 25 January 2012: I've published another paper on the FSM-based formalism for RESTful systems, this time in the &lt;a href=&quot;http://www.rintonpress.com/journals/jwe/&quot;&gt;Journal of Web Engineering&lt;/a&gt;. This paper is again a revised and extended version of the previous paper. Furthermore, the paper explores the practical challenges and benefits of using the presented formalism. Again, for more details see the &lt;a href=&quot;http://ivanzuzak.info/#talks&quot;&gt;talks and papers section&lt;/a&gt;.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is going to be another long post, so I'm using the introduction as an overview again.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;span style=&quot;font-family:Verdana;font-style:normal;line-height:normal;&quot;&gt; &lt;/span&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3 style=&quot;font-size:12pt;text-align:left;&quot;&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/h3&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;This post is about &lt;strong&gt;understanding &lt;/strong&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Representational_State_Transfer&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;/a&gt;, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Software_architecture&quot; target=&quot;_blank&quot;&gt;software architectural&lt;/a&gt; &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/software_arch.htm#sec_1_5&quot; target=&quot;_blank&quot;&gt;style&lt;/a&gt; behind the &lt;a href=&quot;http://en.wikipedia.org/wiki/WWW&quot; target=&quot;_blank&quot;&gt;World Wide Web&lt;/a&gt;. My Ph.D. research, which I'll write about some other time, pushed me on the road of REST and over the last year I've been reading &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm&quot; target=&quot;_blank&quot;&gt;lots&lt;/a&gt; &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=1367606&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://www.vs.inf.ethz.ch/res/papers/dguinard_09_WOTMashups.pdf&quot; target=&quot;_blank&quot;&gt;research&lt;/a&gt; &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=1287624.1287660&quot; target=&quot;_blank&quot;&gt;papers&lt;/a&gt;, &lt;a href=&quot;http://www.amundsen.com/blog/&quot; target=&quot;_blank&quot;&gt;lots&lt;/a&gt; &lt;a href=&quot;http://www.nordsc.com/blog/&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://roy.gbiv.com/untangled/&quot; target=&quot;_blank&quot;&gt;blogs&lt;/a&gt;, &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/&quot; target=&quot;_blank&quot;&gt;lots&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/public-lod/&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/www-tag/&quot; target=&quot;_blank&quot;&gt;mailing&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/ietf-http-wg/&quot; target=&quot;_blank&quot;&gt;lists&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/mamund/status/10672950825&quot; target=&quot;_blank&quot;&gt;lots&lt;/a&gt; &lt;a href=&quot;http://twitter.com/dret/status/9930545464&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://twitter.com/stilkov/status/9029759744&quot; target=&quot;_blank&quot;&gt;tweets&lt;/a&gt;, &lt;a href=&quot;http://www.youtube.com/watch?v=YCcAE2SCQ6k&quot; target=&quot;_blank&quot;&gt;lots&lt;/a&gt; &lt;a href=&quot;http://www.davidgiard.com/2010/03/15/MikeAmundsenOnHTTPAndREST.aspx&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://www.infoq.com/interviews/Restfulie&quot; target=&quot;_blank&quot;&gt;videos&lt;/a&gt;, &lt;a href=&quot;http://rest.blueoxen.net/cgi-bin/wiki.pl&quot; target=&quot;_blank&quot;&gt;wikis&lt;/a&gt;, &lt;a href=&quot;http://www.softwarearchitecturebook.com/&quot; target=&quot;_blank&quot;&gt;books&lt;/a&gt; and &lt;a href=&quot;http://rest.hackyhack.net/&quot; target=&quot;_blank&quot;&gt;IRC transcripts&lt;/a&gt; on REST and I've also recently started the &lt;em&gt;This Week in REST&lt;/em&gt; &lt;a href=&quot;http://rest.blueoxen.net/cgi-bin/wiki.pl?RESTWeekly&quot; target=&quot;_blank&quot;&gt;wiki&lt;/a&gt; and &lt;a href=&quot;http://thisweekinrest.wordpress.com/&quot; target=&quot;_blank&quot;&gt;blog&lt;/a&gt;. In other words, I've read almost everything I could find on REST. So, in the first part of this post I'll write about several thoughts which stuck with me while researching REST:&lt;/p&gt;




&lt;ol style=&quot;text-align:justify;&quot;&gt;
    &lt;li&gt;&lt;strong&gt;REST is and will continue to be important&lt;/strong&gt; - it's the foundation of the WWW and will be the foundation of its future stages and dimensions, like the &lt;a href=&quot;http://en.wikipedia.org/wiki/Semantic_Web&quot; target=&quot;_blank&quot;&gt;Semantic Web&lt;/a&gt; and the &lt;a href=&quot;http://en.wikipedia.org/wiki/Web_of_Things&quot; target=&quot;_blank&quot;&gt;Web of Things&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Understanding REST is hard&lt;/strong&gt; - the material on REST is fragmented and there is no clearly defined and systematized terminology or formal models used in discussions.&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;&lt;strong&gt;We can and should fix the problem&lt;/strong&gt; - there are enough motivated and smart people who can, through an open and collaborative process, create a better way of fully understanding REST.&lt;/li&gt;
&lt;/ol&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;In the second part of the post I'll add to the pile of scattered fragments on understanding RESTful systems and &lt;strong&gt;describe an abstract model of a simplified REST user-agent using &lt;/strong&gt;&lt;strong&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Finite_state_machine&quot; target=&quot;_blank&quot;&gt;finite state machines&lt;/a&gt;&lt;/strong&gt;. It's a very basic model but serves the purpose of showing that it is both possible and useful to develop such formal models.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;I hope this post will motivate people involved and interested in REST to contribute to a process for improving the understanding of REST. I was planing to write my thoughts as a paper for the &lt;a href=&quot;http://www.ws-rest.org/&quot; target=&quot;_blank&quot;&gt;First International Workshop on RESTful Design (WS-REST 2010)&lt;/a&gt; but didn't have enough time. Nevertheless, I hope that people who are going to the workshop will talk about this issue. I'll start a thread on the REST mailing list for following up on these ideas, so please comment there if you want to join the discussion (&lt;strong&gt;&lt;em&gt;EDIT: thread is &lt;/em&gt;&lt;/strong&gt;&lt;strong&gt;&lt;em&gt;&lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/messages/15200?threaded=1&amp;amp;m=e&amp;amp;var=1&amp;amp;tidx=1&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;span style=&quot;font-weight:normal;&quot;&gt;&lt;span style=&quot;font-style:normal;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h2 style=&quot;text-align:justify;&quot;&gt;Representational State Transfer and why it's important&lt;/h2&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;Although this post is about understanding the REpresentational State Transfer (REST) software architectural style, I'm not going to write another REST introduction. If you don't know anything about REST, start from the &lt;a href=&quot;http://en.wikipedia.org/wiki/Representational_State_Transfer&quot; target=&quot;_blank&quot;&gt;wikipedia article&lt;/a&gt; and go from there.&lt;/p&gt;


&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/psd/2918889380/&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;http://farm4.static.flickr.com/3175/2918889380_994055f2f9_b.jpg&quot; width=&quot;202&quot; height=&quot;256&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p style=&quot;text-align:justify;&quot;&gt;What's more important for this post is that &lt;strong&gt;REST is and will continue to be an essential part of the WWW&lt;/strong&gt;.  First, through the &lt;a href=&quot;http://tools.ietf.org/html/rfc3986&quot; target=&quot;_blank&quot;&gt;Web's&lt;/a&gt; &lt;a href=&quot;http://tools.ietf.org/id/draft-fielding-http-p&quot; target=&quot;_blank&quot;&gt;core&lt;/a&gt; &lt;a href=&quot;http://dev.w3.org/html5/spec/Overview.html&quot; target=&quot;_blank&quot;&gt;technologies&lt;/a&gt;, REST is responsible for most of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Representational_State_Transfer#Key_goals&quot; target=&quot;_blank&quot;&gt;good properties of the current Web&lt;/a&gt; as a large-scale network-based system. Second, REST principles guide the development of both the next &quot;major&quot; generations of the Web, like the &lt;a href=&quot;http://en.wikipedia.org/wiki/Semantic_Web&quot; target=&quot;_blank&quot;&gt;Semantic Web&lt;/a&gt;, the &lt;a href=&quot;http://en.wikipedia.org/wiki/Web_of_Things&quot; target=&quot;_blank&quot;&gt;Web of Things&lt;/a&gt; and the &lt;a href=&quot;http://en.wikipedia.org/wiki/Real_time_web&quot; target=&quot;_blank&quot;&gt;Real-time Web&lt;/a&gt;, and the &quot;minor&quot; incremental &lt;a href=&quot;http://tools.ietf.org/html/draft-nottingham-site-meta-05&quot; target=&quot;_blank&quot;&gt;changes&lt;/a&gt; &lt;a href=&quot;http://tools.ietf.org/html/draft-duerst-iri-bis&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://tools.ietf.org/html/draft-hammer-discovery&quot; target=&quot;_blank&quot;&gt;continuous&lt;/a&gt; &lt;a href=&quot;http://www.w3.org/2001/tag/group/track/issues/31&quot; target=&quot;_blank&quot;&gt;evolution&lt;/a&gt;. Whereas the Semantic Web is about &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Description_Framework&quot; target=&quot;_blank&quot;&gt;exposing&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Linked_Data&quot; target=&quot;_blank&quot;&gt;interlinking&lt;/a&gt; data on the WWW, the Web of Things is about &lt;a href=&quot;http://www.slideshare.net/misterdom/web-of-things-connecting-people-and-objects-on-the-web-3425316&quot; target=&quot;_blank&quot;&gt;connecting and exposing&lt;/a&gt; every physical thing to it and the Real-time Web is about &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot; target=&quot;_blank&quot;&gt;real-time access&lt;/a&gt; to that data and things. Therefore, understanding the &lt;a href=&quot;http://www.w3.org/TR/webarch/&quot; target=&quot;_blank&quot;&gt;Web today&lt;/a&gt;, it's &lt;a href=&quot;http://journal.webscience.org/146/&quot; target=&quot;_blank&quot;&gt;future evolution&lt;/a&gt; and the &lt;a href=&quot;http://bitworking.org/projects/atom/rfc5023.html&quot; target=&quot;_blank&quot;&gt;whole&lt;/a&gt;&lt;a href=&quot;http://tools.ietf.org/html/draft-nottingham-http-link-header&quot; target=&quot;_blank&quot;&gt; technology&lt;/a&gt; &lt;a href=&quot;http://www.w3.org/TR/rdf-sparql-query/&quot; target=&quot;_blank&quot;&gt;jungle&lt;/a&gt; &lt;a href=&quot;http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol&quot; target=&quot;_blank&quot;&gt;on&lt;/a&gt; &lt;a href=&quot;http://wiki.webhooks.org/&quot; target=&quot;_blank&quot;&gt;top&lt;/a&gt; is based on the understanding of REST. Third, REST is important as a research subject on its own (although some people &lt;a href=&quot;http://www.subbu.org/blog/2009/07/is-this-restful&quot; target=&quot;_blank&quot;&gt;think it isn't&lt;/a&gt; &lt;strong&gt;&lt;em&gt;EDIT: Subbu elaborated on this misunderstanding below in the comment section&lt;/em&gt;&lt;/strong&gt;) and will be &lt;a href=&quot;http://www2009.org/proceedings/pdf/p911.pdf&quot; target=&quot;_blank&quot;&gt;analyzed&lt;/a&gt; and built upon to define &lt;a href=&quot;http://www.erenkrantz.com/CREST/&quot; target=&quot;_blank&quot;&gt;new&lt;/a&gt; &lt;a href=&quot;http://www.ics.uci.edu/~rohit/Khare-Thesis-FINAL.pdf&quot; target=&quot;_blank&quot;&gt;architectural&lt;/a&gt; &lt;a href=&quot;http://homepages.cwi.nl/~arie/papers/spci/spiar-jss.pdf&quot; target=&quot;_blank&quot;&gt;styles&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;Understanding REST&lt;/h2&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;In my experience, &lt;strong&gt;understanding REST is far from easy&lt;/strong&gt;. Of course, not everyone needs to understand REST and different people may want or need to understand REST at different levels and depths. However, despite it being a highly technical and academic concept not everyone should easily and fully grasp, I think it's hard even for people aimed at - computer scientists, software engineers and web architects. After reading everything I could find on REST and the WWW, here are the problems I believe are responsible for this:&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;

&lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3_1&quot;&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;http://www.codeproject.com/KB/aspnet/NoteOnWebApplications/Figure2.gif&quot; width=&quot;320&quot; height=&quot;145&quot; /&gt;&lt;/a&gt;

First, &lt;strong&gt;the REST master reference&lt;/strong&gt;, &lt;a href=&quot;http://www.ics.uci.edu/~fielding/&quot; target=&quot;_blank&quot;&gt;Roy Fielding's&lt;/a&gt; &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm&quot; target=&quot;_blank&quot;&gt;doctoral dissertation&lt;/a&gt; (and subsequent &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=514183.514185&quot; target=&quot;_blank&quot;&gt;academic&lt;/a&gt; &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=337228&quot; target=&quot;_blank&quot;&gt;papers&lt;/a&gt;), &lt;strong&gt;is not completely suitable for fully understanding REST&lt;/strong&gt;. For a doctoral dissertation, it's severely lacks images explaining important concepts in the two &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_2&quot; target=&quot;_blank&quot;&gt;key&lt;/a&gt; &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3&quot; target=&quot;_blank&quot;&gt;sections&lt;/a&gt; on REST. However, I bet everyone knows the single image in those sections almost by heart from how much it's being repeated everywhere (for those who don't, that's the image on the right). The same could be said for the lack of (formal) models to describe specific properties, elements or views of REST, like &lt;a href=&quot;http://en.wikipedia.org/wiki/HATEOAS&quot; target=&quot;_blank&quot;&gt;HATEOAS&lt;/a&gt;. It's as if the very clean and systematic approach of explaining &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/software_arch.htm&quot; target=&quot;_blank&quot;&gt;software architecture&lt;/a&gt; and &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/net_arch_styles.htm&quot; target=&quot;_blank&quot;&gt;network-based architectural styles&lt;/a&gt; present in the first few chapters of his Ph.D. somehow vanished in those two sections. I am aware that there are no formal models for defining architectural styles as a whole (at least, &lt;a href=&quot;http://csse.usc.edu/~mehta/phd/dissertation.pdf&quot; target=&quot;_blank&quot;&gt;there weren't any then&lt;/a&gt;), but using models like &lt;a href=&quot;http://en.wikipedia.org/wiki/Finite-state_machine&quot; target=&quot;_blank&quot;&gt;state machines&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Petri_net&quot; target=&quot;_blank&quot;&gt;Petri nets&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Process_calculus&quot; target=&quot;_blank&quot;&gt;process calculi&lt;/a&gt; to describe and explain parts of it would have definitely been of great benefit. It's that absolute clarity of formal models that helps when you need to have a complete grasp of a concept. Furthermore, since models are abstract methods for explaining specific problems, people only need to research the underlying model after which the specific use of the model is unambiguously clear. And just to be clear, I think Roy's dissertation is overall well written and has had a big impact on both the academia and industry, and I very well know that making everyone on the planet happy with a research paper is idiotic (looking for a good Ph.D. comics reference for this), but I still wish those two sections were a bit more thorough and polished.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;Second, since Roy's dissertation doesn't have clear answers for all questions, people start discussions over understanding specific parts of REST all over the Web. &lt;strong&gt;Relevant discussions are scattered&lt;/strong&gt; over many mailing lists, blogs, Twitter accounts, wikis, academic papers, videos and even IRC transcripts (see the introduction for links to some of these). More often than not these &lt;strong&gt;discussion are not focused on REST&lt;/strong&gt; per se, but &lt;a href=&quot;http://derivadow.com/2010/02/18/the-problem-with-breadcrumb-trails/&quot; target=&quot;_blank&quot;&gt;on&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/www-tag/2010Feb/0002.html&quot; target=&quot;_blank&quot;&gt;anything&lt;/a&gt; &lt;a href=&quot;http://www.mail-archive.com/public-lod@w3.org/msg04387.html&quot; target=&quot;_blank&quot;&gt;related&lt;/a&gt; &lt;a href=&quot;http://masinter.blogspot.com/2010/03/resources-are-angels-urls-are-pins.html&quot; target=&quot;_blank&quot;&gt;to&lt;/a&gt; &lt;a href=&quot;http://www.webofthings.com/2010/02/02/sharing-in-a-web-of-things/&quot; target=&quot;_blank&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;http://highscalability.com/blog/2010/3/26/strategy-caching-404s-saved-the-onion-66-on-server-time.html&quot; target=&quot;_blank&quot;&gt;Web&lt;/a&gt;, various &lt;a href=&quot;http://lists.w3.org/Archives/Public/public-lod/2010Mar/0203.html&quot; target=&quot;_blank&quot;&gt;specifics&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/www-tag/2010Mar/0045.html&quot; target=&quot;_blank&quot;&gt;concerning&lt;/a&gt; &lt;a href=&quot;http://www.mnot.net/cache_docs/&quot; target=&quot;_blank&quot;&gt;current&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/www-tag/2009Dec/0070.html&quot; target=&quot;_blank&quot;&gt;and&lt;/a&gt; &lt;a href=&quot;http://www.kimchy.org/rest_and_web_sockets/&quot; target=&quot;_blank&quot;&gt;future&lt;/a&gt; &lt;a href=&quot;http://lists.w3.org/Archives/Public/ietf-http-wg/2010JanMar/0337.html&quot; target=&quot;_blank&quot;&gt;standards&lt;/a&gt; and so on. And even more often, the &lt;strong&gt;discussions unnecessarily repeat previous discussions&lt;/strong&gt; probably because the authors are unaware that the same discussion exists elsewhere or it's that those are too difficult to search for. For example, the HATEOAS constraint is getting &lt;a href=&quot;http://weblogs.java.net/blog/mkarg/archive/2010/02/14/what-hateoas-actually-means&quot; target=&quot;_blank&quot;&gt;a&lt;/a&gt; &lt;a href=&quot;http://www.amundsen.com/blog/archives/1005&quot; target=&quot;_blank&quot;&gt;lot&lt;/a&gt; &lt;a href=&quot;http://www.slideshare.net/skillsmatter/hydras-and-hypermedia&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://www.infoq.com/articles/mark-baker-hypermedia&quot; target=&quot;_blank&quot;&gt;attention&lt;/a&gt; &lt;a href=&quot;http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven&quot; target=&quot;_blank&quot;&gt;everywhere&lt;/a&gt;. So there's lots of unorganized, scattered, duplicated and mutually disconnected fragments on REST and it's unclear where and how to find the ones that answer your questions. No, &lt;a href=&quot;http://www.google.com/search?hl=en&amp;amp;q=REST&quot; target=&quot;_blank&quot;&gt;Googling&lt;/a&gt; won't help as often as you'd like, no, a &lt;a href=&quot;http://www.infoq.com/minibooks/emag-03-2010-rest&quot; target=&quot;_blank&quot;&gt;series of unrelated articles&lt;/a&gt; piled up together won't either (though &lt;a href=&quot;http://twitter.com/mamund&quot; target=&quot;_blank&quot;&gt;Mike Amundsen's tweets&lt;/a&gt; often will), and yes, a-big-unorganized-mess is kind of the point of the Web in general, however it's not the optimal methodology for &lt;strong&gt;systematizing knowledge in a way required&lt;/strong&gt;&lt;strong&gt; for understanding complex concepts like REST&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;http://images.ctv.ca/archives/CTVNews/img2/20080516/450_messy1_080516.jpg&quot; width=&quot;325&quot; height=&quot;225&quot; /&gt;&lt;/p&gt;

&lt;p style=&quot;text-align:justify;&quot;&gt;Third, these &lt;strong&gt;fragments on REST often use mutually different terminology, same terminology with different meaning&lt;/strong&gt;&lt;strong&gt; or terminology which is not explicitly defined&lt;/strong&gt;. My favorite example is the word &quot;state&quot; which is overloaded with unexplained and overlapping meaning. &quot;Resource state&quot;, &quot;session state&quot;, &quot;control state&quot;, &quot;client state&quot;, &quot;server state&quot;, &quot;application state&quot;, &quot;transaction state&quot;, &quot;steady state&quot; and &quot;transient state&quot; are some of the terms used and it is not completely clear what some of those mean, how they are related and which REST elements use, change and transfer them and when. For example, &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/message/14671&quot; target=&quot;_blank&quot;&gt;what is client state&lt;/a&gt;? Is it something related to the client connector type? Is it something stored on the client component? If so, then &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/message/15074&quot; target=&quot;_blank&quot;&gt;why is it not called user agent&lt;/a&gt; state? Is client state a union of session and application state? Or is application state a synonym for session state? Which states does a &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/message/14643&quot; target=&quot;_blank&quot;&gt;steady state relate to&lt;/a&gt; - client, session or application? Which entities may change session state and when? Yes, some of these concepts are completely clear, &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/message/15116&quot; target=&quot;_blank&quot;&gt;but some are not&lt;/a&gt; and different people use them with different meaning. Still, the most entertaining situations are the ones in which people write only &quot;state&quot; and then you have to figure out which state they are referring to. Yeah, good luck. And there are other both simple and complex examples, from stating that REST methods are to be executed over representations instead of resources and discussing if ATOM is &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/message/15061&quot; target=&quot;_blank&quot;&gt;RESTful&lt;/a&gt; &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/message/14718&quot; target=&quot;_blank&quot;&gt;or not&lt;/a&gt; to explaining just what is an &lt;em&gt;application &lt;/em&gt;in terms of REST. Lastly, similar to Roy's dissertation, these discussion rarely use diagrams or formal models to explain anything.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;These problems confuse people trying to learn REST on a basic level and make it hard to discuss REST on deeper levels.&lt;/p&gt;




&lt;h2&gt;What we should do about it&lt;/h2&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;Now, I'm not implying that these problems will cause the apocalypse if we don't solve them, but I'd sure like it if they go away (and lots of other people would also). So here are my suggestions:&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;First, &lt;strong&gt;a mess is still better than nothing&lt;/strong&gt;. Everyone should at least continue with thinking, writing and talking about REST and create more fragments. Chances are that those fragments will help a fair amount of people interested in REST. I definitely learned a lot from &lt;a href=&quot;http://www.markbaker.ca/blog/&quot; target=&quot;_blank&quot;&gt;reading&lt;/a&gt; &lt;a href=&quot;http://amundsen.com/blog/&quot; target=&quot;_blank&quot;&gt;excellent&lt;/a&gt; &lt;a href=&quot;http://www.nordsc.com/blog/&quot; target=&quot;_blank&quot;&gt;blogs&lt;/a&gt;, &lt;a href=&quot;http://www.twibes.com/group/rest?id=817190&quot; target=&quot;_blank&quot;&gt;tweets&lt;/a&gt;, &lt;a href=&quot;http://dret.net/netdret/publications&quot; target=&quot;_blank&quot;&gt;papers&lt;/a&gt; and &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/messages/14643?threaded=1&amp;amp;m=e&amp;amp;var=1&amp;amp;tidx=1&quot; target=&quot;_blank&quot;&gt;mailing list posts&lt;/a&gt; (Ryan's &lt;a href=&quot;http://tomayko.com/writings/rest-to-my-wife&quot; target=&quot;_blank&quot;&gt;explanation of REST to his wife&lt;/a&gt; is especially entertaining, besides educational).&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;Second, I think this problem can and &lt;strong&gt;should be solved collaboratively and openly&lt;/strong&gt;, not by single person (not even Roy Fielding) or as just another academic paper. If there's going to be agreement over terminology, it's meaning, models, and other ways of making understanding REST easier, this agreement must be backed by people who have relevant REST experience and must be open to comments from everyone else. Furthermore, untangling the mess will require a lot of work. So, in my opinion, the REST community (whatever that is) should:&lt;/p&gt;




&lt;div id=&quot;_mcePaste&quot;&gt;
&lt;ol&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;Agree that there is a problem worth fixing - do we think that we can create a better, clearer and more systematized way of understanding and discussing about REST?&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;Express interest in fixing it - is this something people want to contribute their time to?&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;Agree on how to fix it - what should be our output (a RESTopedia, a document, video tutorials) and how would we all contribute to and moderate the process?&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;Do it - spend time discussing and developing the output.&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;Eat our dogfood - use whatever we produce. If we don't use the terminology and models we agree upon, the the mess has only gotten bigger.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;


&lt;p&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;http://farm4.static.flickr.com/3199/3330670980_dab9f6b5c8.jpg&quot; width=&quot;320&quot; height=&quot;213&quot; /&gt;&lt;/p&gt;

&lt;p style=&quot;text-align:justify;&quot;&gt;&lt;a href=&quot;http://twitter.com/distobj&quot; target=&quot;_blank&quot;&gt;There&lt;/a&gt; &lt;a href=&quot;http://twitter.com/sallamar&quot; target=&quot;_blank&quot;&gt;are&lt;/a&gt; &lt;a href=&quot;http://twitter.com/guilhermecaelum&quot; target=&quot;_blank&quot;&gt;more&lt;/a&gt; &lt;a href=&quot;http://twitter.com/iansrobinson&quot; target=&quot;_blank&quot;&gt;than&lt;/a&gt; &lt;a href=&quot;http://twitter.com/mamund&quot; target=&quot;_blank&quot;&gt;enough&lt;/a&gt; &lt;a href=&quot;http://twitter.com/algermissen&quot; target=&quot;_blank&quot;&gt;smart&lt;/a&gt; &lt;a href=&quot;http://twitter.com/stilkov&quot; target=&quot;_blank&quot;&gt;and&lt;/a&gt; &lt;a href=&quot;http://twitter.com/dret&quot; target=&quot;_blank&quot;&gt;motivated&lt;/a&gt; &lt;a href=&quot;http://twitter.com/andrewwahbe&quot; target=&quot;_blank&quot;&gt;people&lt;/a&gt; with different backgrounds and experience with REST and RESTful HTTP to make this happen and it would have a big impact if done (even more if done right). I myself am not sure what the best output would be and how to achieve it, but would like it to be a hypermedia document available freely on the WWW, contain a systematized intersection of terminology, images, models and rationale that everyone agrees upon and focus on REST, using HTTP/URI/HTML only for examples (not the other way around).&lt;/p&gt;




&lt;h2&gt;Formal models for REST - a FSM model of a simplified RESTful user-agent&lt;/h2&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;First off, &lt;strong&gt;developing useful formal models for understanding architectural styles isn't easy&lt;/strong&gt; since architectural styles are named sets of constraints commonly defined using natural language, rarely using formalisms. Also, models of REST concepts should include as many other REST concepts as possible - e.g. a model of HATEOAS should somehow clear up how application state, representations, methods, resources, steady states, transient states and other concepts all play their role in HATEOAS. It's not easy to model this in a clear and simple way. Nevertheless, these kinds of models are especially important since they connect rather than disperse concepts.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;Mike Amundsen's and Jan Algermissen's &lt;a href=&quot;http://www.amundsen.com/blog/archives/1032&quot; target=&quot;_blank&quot;&gt;poking&lt;/a&gt; &lt;a href=&quot;http://rest.hackyhack.net/2010-02-13.html#168/h168&quot; target=&quot;_blank&quot;&gt;at&lt;/a&gt; &lt;a href=&quot;http://tech.groups.yahoo.com/group/rest-discuss/messages/15101?threaded=1&amp;amp;m=e&amp;amp;var=1&amp;amp;tidx=1&quot; target=&quot;_blank&quot;&gt;REST steady states&lt;/a&gt; was very thought-provoking for me - excerpts pointing at something often ignored when discussing REST, but could be formally defined. This led me to try to model REST user-agents using some kind of a state machine. I soon found out there are lots of &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=267955&amp;amp;dl=ACM&amp;amp;coll=GUIDE&amp;amp;CFID=84620683&amp;amp;CFTOKEN=34066621&quot; target=&quot;_blank&quot;&gt;interesting&lt;/a&gt; &lt;strong&gt;&lt;a href=&quot;http://webpages.cs.luc.edu/~laufer/papers/isas95.pdf&quot; target=&quot;_blank&quot;&gt;papers&lt;/a&gt; &lt;a href=&quot;http://ieeexplore.ieee.org/iel5/10670/33674/01602332.pdf?arnumber=1602332 &quot; target=&quot;_blank&quot;&gt;on&lt;/a&gt; &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=366869&amp;amp;dl=GUIDE&amp;amp;coll=GUIDE&amp;amp;CFID=84620229&amp;amp;CFTOKEN=91600605&quot; target=&quot;_blank&quot;&gt;modeling &lt;/a&gt;&lt;a href=&quot;http://portal.acm.org/citation.cfm?id=267449&quot; target=&quot;_blank&quot;&gt;hypermedia&lt;/a&gt; &lt;a href=&quot;http://www.cs.auckland.ac.nz/compsci345s1c/lectures/formcharts.pdf&quot; target=&quot;_blank&quot;&gt;applications&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt; in general&lt;/strong&gt; and &lt;a href=&quot;http://intertwingly.net/blog/2005/03/09/Distributed-State-Machines&quot; target=&quot;_blank&quot;&gt;even&lt;/a&gt; &lt;a href=&quot;http://weblogs.java.net/blog/2007/04/27/rest-state-machine-duh&quot; target=&quot;_blank&quot;&gt;more&lt;/a&gt; &lt;strong&gt;&lt;a href=&quot;http://www.pluralsight-training.net/community/blogs/tewald/archive/2007/04/26/46984.aspx&quot; target=&quot;_blank&quot;&gt;blogs&lt;/a&gt; on modeling REST user-agents&lt;/strong&gt; using some kind of state machine formalism (&lt;a href=&quot;http://en.wikipedia.org/wiki/Finite_state_machine&quot; target=&quot;_blank&quot;&gt;FSMs&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/UML_state_machine&quot; target=&quot;_blank&quot;&gt;statecharts&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Petri_net&quot; target=&quot;_blank&quot;&gt;Petri nets&lt;/a&gt; or something else). Here are some of my thoughts after reading these papers and blogs:&lt;/p&gt;




&lt;ol style=&quot;text-align:justify;&quot;&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;Most often, models are based on the &quot;each page is a state and each link is a state transition&quot; analogy. This is confusing and wrong for two reasons. First, it's confusing since resource identifiers (e.g. URIs) are used to somehow address states of the application (e.g. an URI addresses a page which is mapped to a state) and state transitions (e.g. an URI is a link to a state which is mapped to a transition). In REST, resource identifiers are neither the single thing determining the state (e.g. two clients can perform the same GET request on a resource and get different representations which determine state) nor the single thing determining the transition between states (e.g. one client can perform a GET on a resource, the other could perform a PUT). Roy's thesis defines what constitutes application state and thus when the state changes: &quot;&lt;em&gt;An application's state is therefore defined by its pending requests, the topology of connected components, the active requests on those connectors, the data flow of representations in response to those requests, and the processing of those representations as they are received by the user agent.&lt;/em&gt;&quot; Second, models often ignore some REST concepts like steady and transient states and are therefore useful only for understanding REST up to a certain level.&lt;/li&gt;
    &lt;li&gt;State machines models are extremely simple to understand and a powerful tool for modeling. For example, state machines can also be used for &lt;a href=&quot;http://en.wikipedia.org/wiki/Model_checking&quot; target=&quot;_blank&quot;&gt;model checking&lt;/a&gt; using &lt;a href=&quot;http://en.wikipedia.org/wiki/Temporal_logic&quot; target=&quot;_blank&quot;&gt;temporal logic&lt;/a&gt; (e.g. check that from any state there is a link to the home page).&lt;/li&gt;
&lt;/ol&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;That's why I really like Stu Charlton's &lt;a href=&quot;http://www.stucharlton.com/blog/archives/2010/03/building-a-restful-hypermedia.html&quot; target=&quot;_blank&quot;&gt;recent post&lt;/a&gt; on RESTful user-agents which identifies different types of state machines involved in user-agent operation. Stu nailed most of the things I wanted to write about, but nevertheless - below is my first attempt at a simplified finite state machine (FSM) model of RESTful user-agents. I won't go into explaining FSMs in detail, so just check the &lt;a href=&quot;http://en.wikipedia.org/wiki/Finite_state_machine&quot; target=&quot;_blank&quot;&gt;Wikipedia article&lt;/a&gt; if you don't know what FSMs are.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;I'll concentrate on recognizer-type finite state machines - specifically, &lt;a href=&quot;http://en.wikipedia.org/wiki/Nondeterministic_finite-state_machine&quot; target=&quot;_blank&quot;&gt;nondeterministic FSMs (NFAs)&lt;/a&gt;. NFAs are mathematically defined as a quintuple (Σ,&lt;em&gt;S&lt;/em&gt;,&lt;em&gt;s&lt;/em&gt;&lt;sub&gt;0&lt;/sub&gt;,δ,&lt;em&gt;F&lt;/em&gt;), where&lt;/p&gt;




&lt;ul style=&quot;text-align:justify;&quot;&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;Σ&lt;/em&gt;&lt;/span&gt; is the input &lt;span style=&quot;color:#000000;&quot;&gt;alphabet&lt;/span&gt; (a finite, non-empty set of symbols).&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;S&lt;/em&gt;&lt;/span&gt; is a finite, non-empty set of states.&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;s&lt;/em&gt;&lt;sub&gt;&lt;span style=&quot;font-size:medium;&quot;&gt;&lt;em&gt;0&lt;/em&gt;&lt;/span&gt;&lt;/sub&gt;&lt;/span&gt; is an initial state, an element of &lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;S&lt;/em&gt;&lt;/span&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;δ&lt;/em&gt;&lt;/span&gt; is the state-transition function: &lt;em&gt;δ : S x Σ → P(S)&lt;/em&gt; where &lt;em&gt;P(S)&lt;/em&gt; the power set &lt;em&gt;S&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;F&lt;/em&gt;&lt;/span&gt; is the set of final states, a subset of &lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;S&lt;/em&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;The operation of an NFA automaton, as state machines are sometimes called, is described as follows. The NFA starts from the initial state and then sequentially reads one input symbol at a time each time applying the state-transition function to transfer itself to the next state. After all input symbols have been processed in this way, the NFA stops and outputs &quot;true&quot; if the last state is in the set of final states, or &quot;false&quot; otherwise. Notice that it is not defined how input symbols are generated, just that there is a sequence of them being fed to the automaton. Also notice that NFAs can nondeterministically transfer to a set of states at some point. This &lt;strong&gt;nondeterminism is important but also confusing&lt;/strong&gt; - how can the automaton be at more than a single state? Well, although the formal definition indicates that the automaton is in a set of states, the practical and useful meaning is that the automaton may be at any single state from that set - we don't know which one in advance, it can be any single one. In other words, a single state from the set will be chosen in some way e.g. using probabilities.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;This iterative process of automaton operation can be modeled as a system:&lt;/p&gt;




&lt;center&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;CurrentState = s&lt;sub&gt;0&lt;/sub&gt;
while there are more input symbols to process:
  InputSymbol = GetNextInput()
  CurrentState =
    TransitionFunction(InputSymbol, CurrentState)&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;center&gt;&lt;img class=&quot;aligncenter&quot; style=&quot;margin:5px;&quot; src=&quot;/images/rest_system1.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;123&quot; /&gt;
&lt;/center&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;




&lt;p style=&quot;text-align:justify;&quot;&gt;Here, CurrentState is a component that stores the current state of the automaton, InputSymbol is a component that stores the current input symbol (element from the input alphabet), GetNextInput is a component that provides the next input symbol and writes it to the InputSymbol component and TransitionFunction is a component that computes the state transition function and writes the new state to the CurrentState component. Notice that the GetNextInput component doesn't take any input in this description. This is not entirely true, of course - the operation of the component that generates input symbols is out of scope of formal automaton definition, the component may generate input symbols based on whatever it wants. So, I'll expand the system to include the CurrentState as an input to the GetNextInput component (since there is nothing else in the model to include):&lt;/p&gt;




&lt;center&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;CurrentState = s&lt;sub&gt;0&lt;/sub&gt;
while there are more input symbols to process:
  InputSymbol = GetNextInput(&lt;span style=&quot;color:#ff0000;&quot;&gt;CurrentState&lt;/span&gt;)
  CurrentState =
    TransitionFunction(InputSymbol, CurrentState)&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;center&gt;&lt;img class=&quot;aligncenter&quot; style=&quot;margin:5px;&quot; src=&quot;/images/rest_system2.png&quot; width=&quot;300&quot; height=&quot;123&quot; /&gt;
&lt;/center&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/center&gt;




&lt;p style=&quot;text-align:justify;&quot;&gt;Now the interesting part - &lt;strong&gt;mapping properties of RESTful user-agents to this NFA model&lt;/strong&gt;. As I wrote before, this is a simplified first-draft-quality model, not everything that should be included is included and thus the model may change when more details do get included. First I'll try to explain the mapping in a general way, not on a specific RESTful system, and after that I'll give a concrete example:&lt;/p&gt;




&lt;ul&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;&lt;strong&gt;The input alphabet&lt;/strong&gt; (set of input symbols generated by the GetNextInput component and stored in the InputSymbol component) are REST requests. Since a REST requests is defined by a resource identifier, method to be performed on the resource, metadata and a possible representation, the input alphabet is the set of all possible (syntactically) well-formed REST requests. This is why the resource identifier is not the only thing representing a transition - a single transition from a specific state is defined by all elements of a REST request, only one of which is the resource identifier. Therefore, there may be multiple transitions from a specific state and a specific destination resource identifier.&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;&lt;span style=&quot;font-size:13.1944px;&quot;&gt;&lt;strong&gt;The state transition function&lt;/strong&gt;, implemented in the TransitionFunction component, is the cumulative processing of REST requests. This process is performed by user-agents, intermediaries and origin servers, and the result is a REST response containing metadata and a representation of the resource identified in the related REST request. Here's the most important part - since the user-agent doesn't know what the response to a request will be and since the origin server may return different REST responses for the same REST request - this processing must be modeled as nondeterministic. In other words, the result of the transition function is a set of all possible REST responses which may be returned for a given REST request. As I explained earlier when demystifying nondeterminism, the origin server will in fact return a single response but since we don't know which one - this is modeled as a set of possible responses. Also, the metadata (media type) of the response defines if the state is steady or not by specifying which of the resources linked to from the response representation should also be requested. If the state is not steady, more requests should be sent for those resources. If the input symbol is a REST request for a resource for which there is no link in the current state then the transition function returns an empty set. The same happens if the system is not in a steady state and the input symbol is a REST request not in the set of pending requests.&lt;/span&gt;&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;&lt;strong&gt;The current state&lt;/strong&gt;, stored in the CurrentState component, is a set of REST responses and pending REST requests. The current state is considered a steady state if there are no pending requests, otherwise it's considered a transient state. &lt;strong&gt;The initial state&lt;/strong&gt; of the user-agent is steady and may contain a predefined representation with links to bootstrap the operation of the user-agent.&lt;/li&gt;
    &lt;li style=&quot;text-align:justify;&quot;&gt;The only thing left is to define how the user-agent chooses transitions - the next REST request for the current state. This is the role of the GetNextInput component which implements both application- and hypermedia-level logic. The application-level logic is in charge of generating input symbols in case the current state is steady, or in other words, it chooses then next step for achieving the overall application goal. The application-level logic may be a software program or a program that delegates this responsibility to a human user. The hypermedia-level logic is in charge of generating input symbols in case the current state is transient, or in other words, it chooses which of the pending REST requests will be processed next. To satisfy the HATEOAS constraint, both the application- and hypermedia- level logic generate REST requests with resource identifiers linked to from the current state.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;/images/rest_system3.png&quot; alt=&quot;&quot; width=&quot;600&quot; height=&quot;383&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Or mathematically (without all the detailed explanations):&lt;/p&gt;

&lt;ul style=&quot;text-align:justify;&quot;&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;Σ&lt;/em&gt;&lt;/span&gt; = { &lt;em&gt;R&lt;/em&gt; | &lt;em&gt;R&lt;/em&gt; is a valid REST request consisting of a resource identifier, method, metadata and representation }&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;S&lt;/em&gt;&lt;/span&gt; = { { &lt;em&gt;G&lt;/em&gt; } | &lt;em&gt;G&lt;/em&gt; is a valid REST response consisting of metadata and a representation or a pending REST request }&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;s&lt;/em&gt;&lt;sub&gt;&lt;span style=&quot;font-size:medium;&quot;&gt;&lt;em&gt;0&lt;/em&gt;&lt;/span&gt;&lt;/sub&gt;&lt;/span&gt; = initial representation containing links to bootstrap the operation of the user agent&lt;/li&gt;
    &lt;li&gt;&lt;em&gt;δ : S x Σ → P(S)&lt;/em&gt; where &lt;em&gt;P(S)&lt;/em&gt; the power set of &lt;em&gt;S&lt;/em&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;F&lt;/em&gt;&lt;/span&gt; = { &lt;em&gt;Z&lt;/em&gt; | &lt;em&gt;Z&lt;/em&gt; ∈ &lt;em&gt;S&lt;/em&gt; and &lt;em&gt;Z&lt;/em&gt; is a steady state }&lt;/li&gt;
&lt;/ul&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;The operation of the automaton can be described as follows. The automaton starts from the initial steady state containing links for bootstrapping the application. Each time the automaton is in a steady state, the application level logic generates the next input symbol (request) based on the links in the current state representations and the overall application goal. The request and the current state are used by the processing infrastructure (user-agent, intermediaries, origin server) to generate a response. Notice here that the current state (representation already on the client) need not be sent to the server, it may be used on the user-agent for processing (e.g. to determine if the request is for a resource linked to from the current state or not) while only the input symbol (the request) is sent over the network. The result of the processing is the new state of the user-agent. The new state may either be steady or transient, based on the representation received in the response and it's metadata (media type). If the state is transient, the hypermedia-level logic automatically chooses requests for fetching other resources in order to bring the user-agent into a steady state so that application-level logic can take over.&lt;/p&gt;


&lt;p&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;/images/rest_example1.png&quot; alt=&quot;&quot; width=&quot;400&quot; height=&quot;340&quot; /&gt;&lt;/p&gt;

&lt;p style=&quot;text-align:justify;&quot;&gt;Now an &lt;strong&gt;example - applying this model to a specific RESTful system&lt;/strong&gt;, which will of course be a simple web application shown above. The purpose of the web application is to simulate coin tossing. It has two web pages, &lt;em&gt;Main.html&lt;/em&gt; and &lt;em&gt;Cointoss.html&lt;/em&gt;. The &lt;em&gt;Main.html&lt;/em&gt; page contains only a single link to the &lt;em&gt;Cointoss.html&lt;/em&gt; page and nothing else. The &lt;em&gt;Cointoss.html&lt;/em&gt; page has a link back to the &lt;em&gt;Main.html&lt;/em&gt; page and a single image. Since the web application simulates coin tossing, which is nondeterministic, the image which gets included into the &lt;em&gt;Cointoss.html&lt;/em&gt; is chosen randomly by the server and is either the &lt;em&gt;heads.png&lt;/em&gt; image or the &lt;em&gt;tails.png&lt;/em&gt; image.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;The input symbols of the resulting automaton are requests for fetching application resources - the html pages and the images. The states of the resulting automaton are both steady states representing a complete page load or transient states representing partial page loads. Therefore, the &lt;em&gt;Main.html&lt;/em&gt; page is represented by only a steady state since it only contains a link to &lt;em&gt;Cointoss.html&lt;/em&gt;, while the &lt;em&gt;Cointoss.html&lt;/em&gt; page is represented by both a transient state and a steady state since it contains an image which must be fetched after the initial page. Let's assume that the initial state contains a single link to the &lt;em&gt;Main.html&lt;/em&gt; page. The transition function of the resulting automaton defines which responses the processing infrastructure returns for each state and requests. Therefore, if the user-agent requests a page or image, the server returns the requested page or image. However, if the user-agent is requesting the &lt;em&gt;Cointoss.html&lt;/em&gt; page - it isn't known in advance what the server will return (heads or tails), so we need a nondeterministic transition into two possible states. Lastly, steady states define the set of acceptable states.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;And here's the formal automaton definition for the explanation above:&lt;/p&gt;




&lt;ul style=&quot;text-align:justify;&quot;&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;Σ&lt;/em&gt;&lt;/span&gt; = { &lt;em&gt;R1&lt;/em&gt;, &lt;em&gt;R2&lt;/em&gt;, &lt;em&gt;R3&lt;/em&gt;, &lt;em&gt;R4&lt;/em&gt; }, where &lt;em&gt;R1&lt;/em&gt; is a request for fetching &lt;em&gt;Main.html&lt;/em&gt;, &lt;em&gt;R2&lt;/em&gt; is a request for fetching &lt;em&gt;Cointoss.html&lt;/em&gt;, and &lt;em&gt;R3&lt;/em&gt; and &lt;em&gt;R4&lt;/em&gt; are requests for fetching the &lt;em&gt;heads.png&lt;/em&gt; and &lt;em&gt;tails.png&lt;/em&gt; images. For simplicity, let's say these are the only input symbols the user-agent may generate, but in general - it may generate other syntactically valid requests.&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;S&lt;/em&gt;&lt;/span&gt; = { &lt;em&gt;S1&lt;/em&gt;, &lt;em&gt;S2&lt;/em&gt;, &lt;em&gt;S3&lt;/em&gt;, &lt;em&gt;S4&lt;/em&gt;, &lt;em&gt;S5&lt;/em&gt;, &lt;em&gt;S6&lt;/em&gt;}, where &lt;em&gt;S1&lt;/em&gt; is the initial state containing a link to &lt;em&gt;Main.html&lt;/em&gt;, &lt;em&gt;S2 &lt;/em&gt;is the state after receiving the &lt;em&gt;Main.html&lt;/em&gt; page, &lt;em&gt;S3 &lt;/em&gt;is the state after receiving the &lt;em&gt;Cointoss.html&lt;/em&gt; page which has a link to the &lt;em&gt;heads.png&lt;/em&gt; image which hasn't been fetched yet, &lt;em&gt;S4&lt;/em&gt; is the state after receiving responses to both the &lt;em&gt;Cointoss.html&lt;/em&gt; page and &lt;em&gt;heads.pn&lt;/em&gt;g, &lt;em&gt;S5 &lt;/em&gt;is the state after receiving the &lt;em&gt;Cointoss.html&lt;/em&gt; page which has a link to the &lt;em&gt;tails.png&lt;/em&gt; image which hasn't been fetched yet and &lt;em&gt;S6 &lt;span style=&quot;font-style:normal;&quot;&gt;is the state after receiving responses to both the &lt;em&gt;Cointoss.html&lt;/em&gt; page and &lt;em&gt;tails.pn&lt;/em&gt;g.&lt;/span&gt;&lt;/em&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;s&lt;/em&gt;&lt;sub&gt;&lt;span style=&quot;font-size:medium;&quot;&gt;&lt;em&gt;0&lt;/em&gt;&lt;/span&gt;&lt;/sub&gt;&lt;/span&gt; = &lt;em&gt;S1&lt;/em&gt;, since &lt;em&gt;S1&lt;/em&gt; is the initial state.&lt;/li&gt;
    &lt;li&gt;The transition function is defined for each pair of automaton state and input symbol: &lt;em&gt;δ&lt;/em&gt;(&lt;em&gt;S1&lt;/em&gt;, &lt;em&gt;R1&lt;/em&gt;) = &lt;em&gt;S2&lt;/em&gt;, &lt;em&gt;δ&lt;/em&gt;(&lt;em&gt;S2&lt;/em&gt;, &lt;em&gt;R2&lt;/em&gt;) = {&lt;em&gt;S3&lt;/em&gt;,&lt;em&gt; S5&lt;/em&gt;}&lt;em&gt;,&lt;/em&gt; &lt;em&gt;δ&lt;/em&gt;(&lt;em&gt;S3&lt;/em&gt;, &lt;em&gt;R3&lt;/em&gt;) = &lt;em&gt;S4&lt;/em&gt;, &lt;em&gt;δ&lt;/em&gt;(&lt;em&gt;S4&lt;/em&gt;, &lt;em&gt;R1&lt;/em&gt;) = &lt;em&gt;S2&lt;/em&gt;, &lt;em&gt;δ&lt;/em&gt;(&lt;em&gt;S5&lt;/em&gt;, &lt;em&gt;R4&lt;/em&gt;) = &lt;em&gt;S6&lt;/em&gt;, &lt;em&gt;δ&lt;/em&gt;(&lt;em&gt;S6&lt;/em&gt;, &lt;em&gt;R1&lt;/em&gt;) = &lt;em&gt;S2. &lt;/em&gt;For other pairs of state and input symbol the function returns an empty set { } since there are no other links for those pages (states) to resources identified in those requests (input symbols).&lt;/li&gt;
    &lt;li&gt;&lt;span class=&quot;texhtml&quot;&gt;&lt;em&gt;F&lt;/em&gt;&lt;/span&gt; = { &lt;em&gt;S1&lt;/em&gt;,&lt;em&gt; S2&lt;/em&gt;,&lt;em&gt; S4&lt;/em&gt;,&lt;em&gt; S6&lt;/em&gt; }, since those states are steady.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And here's the equivalent state diagram visualization of the automaton:&lt;/p&gt;

&lt;p style=&quot;text-align:center;&quot;&gt;&lt;/p&gt;


&lt;p&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;/images/rest_example2.png&quot; width=&quot;100%&quot;/&gt;&lt;/p&gt;

&lt;p&gt;For such a model, we could generate a random sequence of input symbols and check if the automaton will end up in a steady state or not. You can do this for homework :).&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;(&lt;strong&gt;&lt;em&gt;EDIT: inserted a few sentences to make this a real conclusion&lt;/em&gt;&lt;/strong&gt;) That's about it. All-in-all, I think REST is an important concept for the WWW and that more work should be done to explain it fully and concisely. After that, we can simplify the models to reflect the most important properties, but simplifying before understanding leads to ignorance and &lt;em&gt;mis&lt;/em&gt;understanding in discussions.&lt;/p&gt;


&lt;p style=&quot;text-align:justify;&quot;&gt;If you have ideas or comments about systematizing knowledge, terminology and models for REST or developing formal models for REST - let me know. &lt;a href=&quot;http://www.twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;



</content>
 </entry>
 
 <entry>
   <title>Real-time feed processing and filtering</title>
   <link href="http://ivanzuzak.info/2010/01/11/real-time-feed-processing-and-filtering.html"/>
   <updated>2010-01-11T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2010/01/11/real-time-feed-processing-and-filtering</id>
   <content type="html">&lt;p&gt;&lt;em&gt;This is another lengthy post so I'm writing a brief overview as an introduction.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;


&lt;p&gt;This post is about web syndication feeds (RSS and ATOM), technologies for real-time delivery of feeds (PubSubHubBub, RSSCloud) and two opportunities I believe could help make these technologies better and widen their adoption: &lt;strong&gt;real-time feed processing/filtering and end-user selection of processing/filtering services&lt;/strong&gt;. First, I'll write about my experience with polling-based feed processing services from developing Feed-buster, a feed-enhancing service for use in FriendFeed. Next, I'll give a short overview of PubSubHubBub (PSHB) and several ways of integrating feed filtering and processing functionalities into the PSHB ecosystem without changing the PSHB protocol. Lastly, I'll try to argument why there should be a better solution and outline an idea for an extension to the PSHB protocol.&lt;/p&gt;

&lt;p&gt;Before I continue, I have to acknowledge that I've discussed some of these ideas with &lt;a href=&quot;http://twitter.com/julien51&quot; target=&quot;_blank&quot;&gt;Julien &lt;/a&gt;&lt;a href=&quot;http://twitter.com/julien51&quot; target=&quot;_blank&quot;&gt;Genestoux&lt;/a&gt; (the guy behind &lt;a href=&quot;http://superfeedr.com/&quot; target=&quot;_blank&quot;&gt;Superfeedr&lt;/a&gt;) and &lt;a href=&quot;http://www.google.com/profiles/bslatkin&quot; target=&quot;_blank&quot;&gt;Brett &lt;/a&gt;&lt;a href=&quot;http://www.google.com/profiles/bslatkin&quot; target=&quot;_blank&quot;&gt;Slatkin&lt;/a&gt; (one of &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot; target=&quot;_blank&quot;&gt;PSHB&lt;/a&gt; developers) several months ago. Julien and I were even starting to draft a proposal for a PSHB extension for supporting filters, however, due to other stuff in our lives, we didn't really get anywhere.&lt;/p&gt;

&lt;h2&gt;Polling-based feed processing and filtering - experience from FriendFeed and Feed-Buster&lt;/h2&gt;


&lt;p&gt;&lt;a href=&quot;http://friendfeed.com/&quot; target=&quot;_blank&quot;&gt;FriendFeed&lt;/a&gt; is a social-networking web application that aggregates updates from social media sites and blogs that expose an &lt;a href=&quot;http://en.wikipedia.org/wiki/RSS&quot; target=&quot;_blank&quot;&gt;RSS&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Atom_feed&quot; target=&quot;_blank&quot;&gt;Atom&lt;/a&gt; feed of their content. You give FriendFeed the URI of an RSS/Atom feed and it fetches and displays short snippets of updates as they appear in the feed. In most cases this means that only the title and a short snippet of the description of the new item are shown. For feeds that have &lt;a href=&quot;http://en.wikipedia.org/wiki/Media_RSS&quot; target=&quot;_blank&quot;&gt;special XML tags&lt;/a&gt; that list media resources in the update, the images/videos/audio content from the new feed item is also displayed. The problem is that &lt;strong&gt;most RSS/Atom feeds don't have these media XML tags &lt;/strong&gt;since webapps that create the feeds (e.g. blogging engines) don't bother defining them. This gave a not-very-user-friendly look to most FriendFeed user pages which were just a long list of update titles and possibly snippets.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/feed-buster/&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Feed-buster&quot; src=&quot;/images/fbdemopic.png&quot; alt=&quot;Feed-buster&quot; width=&quot;60%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I built &lt;a href=&quot;http://code.google.com/p/feed-buster/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Feed-buster&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;, an &lt;/strong&gt;&lt;a href=&quot;http://code.google.com/appengine/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;AppEngine&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; service that inserts these MediaRSS tags into feeds that don't have them&lt;/strong&gt;. Since the only thing FriendFeed accepts from users are URIs pointing to feeds - the service must be callable by requesting a single URI with a HTTP GET request and must return an RSS/Atom feed in a HTTP response. Here's how Feed-buster works:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;An URI to an RSS/Atom feed is supplied as a query parameter of a HTTP GET request to the service. E.g. http://feed-buster.appspot.com/mediaInjection?inputFeedUrl=http://myfeed.com/atom.&lt;/li&gt;
    &lt;li&gt;The service fetches the target feed, finds all the images, video and audio URIs and inserts the special XML tags for each one back into the feed.&lt;/li&gt;
    &lt;li&gt;The service returns the modified feed as the content of a HTTP response.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;To use the service, the user would obtain an URI of an RSS/Atom feed, create the corresponding Feed-buster URI by appending the feed URI to the Feed-buster service URI and pass it to FriendFeed (1). Suppose that the feed is not real-time enabled (i.e. a PSHB or RSSCloud feed). In this case, every 45 minutes FF will poll for updates - send a HTTP GET request to the service (2), the service will fetch the original feed (3), process the feed (4) and return a HTTP response with the processed feed (5).&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Feed-buster architecture&quot; src=&quot;/images/fb.png&quot; alt=&quot;Feed-buster architecture&quot; width=&quot;60%&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Feed-buster is a&lt;strong&gt; feed processing service&lt;/strong&gt;: it takes a feed URI as input and returns the feed it points to as output, potentially modifying any subset of feed items (but not removing any). &lt;strong&gt;Feed filtering services&lt;/strong&gt; are similar: they take a feed URI as input and return the feed it points to as output, potentially removing any subset of feed items (but not modifying any). The difference is subtle and both terms could be unified under &quot;feed processing&quot;. Furthermore, this model of feed processing/filtering was nothing new at the time I developed Feed-buster, there were &lt;a href=&quot;http://www.readwriteweb.com/archives/6_ways_to_filter_your_rss_feeds.php&quot; target=&quot;_blank&quot;&gt;numerous services&lt;/a&gt; that filtered/processed feeds based on user preferences. The best example is probably &lt;a href=&quot;http://pipes.yahoo.com/pipes/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Yahoo! Pipes&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; which enables anyone to create a filtering/processing pipe a publish it as a service&lt;/strong&gt; just like Feed-buster.&lt;/p&gt;

&lt;p&gt;Lessons learned:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Feed-buster is very &lt;strong&gt;simple to use&lt;/strong&gt; and this helped to make it popular (appending an URI to another URI is something everyone can do).&lt;/li&gt;
    &lt;li&gt;Feed-buster's model of use is based on &lt;strong&gt;separation of filtering/processing services as individual entities in the ecosystem&lt;/strong&gt; which enables that these services be developed independently of publishers and subscribers. Applications that enable other applications make ecosystems grow.&lt;/li&gt;
    &lt;li&gt;Polling is bad (1). Because AppEngine applications have a &lt;a href=&quot;http://code.google.com/appengine/docs/quotas.html&quot; target=&quot;_blank&quot;&gt;fixed free daily quota&lt;/a&gt; for consumed resources, when the number of feeds the service processed increased -&lt;strong&gt; the daily quota was exhausted before the end of the day&lt;/strong&gt; because FF polls the service for each feed every 45 minutes. See the AppEngine resource graph below for a very clear visual explanation :). Of course, I implemented several caching mechanisms in the service and it helped, but not enough.&lt;/li&gt;
    &lt;li&gt;Polling is bad (2). Real-time feed delivery arrived in the form of &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot; target=&quot;_blank&quot;&gt;PubSubHubBub&lt;/a&gt; and &lt;a href=&quot;http://rsscloud.org/&quot; target=&quot;_blank&quot;&gt;RSSCloud&lt;/a&gt;, &lt;strong&gt;everyone loved it and wanted everything to be real-time&lt;/strong&gt;. But Feed-buster feeds weren't real-time. Even if the original feed supported PSHB, the output feed didn't (since it Feed-buster wasn't a PSHB publisher or hub). Feed-buster users were not happy.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a href=&quot;/images/fbgae.png&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Feed-buster - AppEngine request processing duration graph&quot; src=&quot;/images/fbgae.png&quot; alt=&quot;Feed-buster - AppEngine request processing duration graph&quot; width=&quot;576&quot; height=&quot;258&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;PubSubHubBub - real-time feed delivery&lt;/h2&gt;


&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;PubSubHubBub&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; is a server-to-server publish-subscribe protocol for federated delivery of feed updates&lt;/strong&gt;. Without going into a lot of detail, the basic architecture consists of publishers, subscribers and hubs which interact in the following way:&lt;/p&gt;

&lt;div id=&quot;_mcePaste&quot;&gt;
&lt;ol&gt;
    &lt;li&gt;A feed publisher declares its hub in its Atom or RSS XML file and a subscriber initially fetches the feed to discover the hub.&lt;/li&gt;
    &lt;li&gt;The subscriber subscribes to the discovered hub declaring the feed URI it wishes to subscribe to and an URI at which it wants to receive updates.&lt;/li&gt;
    &lt;li&gt;When the publisher next updates the feed, it pings the hub saying that there's an update and the hub fetches the published feed.&lt;/li&gt;
    &lt;li&gt;The hub multicasts the new/changed content out to all registered subscriber.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href=&quot;/images/pshbarch.png&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;PubSubHubBub ecosystem and protocol&quot; src=&quot;/images/pshbarch.png&quot; alt=&quot;PubSubHubBub ecosystem and protocol&quot; width=&quot;398&quot; height=&quot;107&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this gives us real-time feed delivery. &lt;strong&gt;But what about real-time filtering and processing?&lt;/strong&gt; How would a real-time-enabled version of Feed-buster be built? Of course, there are &lt;a href=&quot;http://blog.postrank.com/2009/10/filtering-the-real-time-web/&quot; target=&quot;_blank&quot;&gt;a lot more reasons for doing this&lt;/a&gt;, both from business and engineering perspectives.&lt;/p&gt;

&lt;h2&gt;Real-time feed processing and filtering (take 1)&lt;/h2&gt;


&lt;p&gt;So, the idea is to &lt;strong&gt;extend the PSHB ecosystem with filtering/processing services in some way&lt;/strong&gt;. First, here are a few ideas for doing this &lt;strong&gt;without extending the PSHB protocol&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Integrating filtering/processing services into publishers.&lt;/strong&gt; This means that the publisher would expose not only the original feed, but also a feed for each filter/processing defined by the subscriber. For example, &lt;a href=&quot;http://www.twitter.com&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt; has a single feed of all updates for a specific user, a feed for updates from that user containing the string &quot;hello&quot;, updates not containing &quot;world&quot;, updates written in English, and so on.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Integrating filtering/processing services into subscribers. &lt;/strong&gt;This means that the subscriber application would subscribe to feeds and filter/process them on it's own. It's not exactly the same thing but, for example, FriendFeed subscribes to feeds you want it to aggregate and later you can filter the content from within the FriendFeed application -- this is called search, as in Twitter, but basically means filter.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Integrating filtering/processing services into hubs. &lt;/strong&gt;This means that a hub would not only deliver feed updates, but process and filter them also. This would cause a large number of hubs to be developed, each implementing some filter or processing functionality. If you want to filter a feed - subscribe to a hub that implements that filter. If you want a new filter - build a new hub. However, if an end-user tells a subscriber application to subscribe to a feed with a specific URI, the subscriber will subscribe to a hub specified in the feed, not to the filtering/processing hub (since that hub wasn't  specified in any way). A possible way for enabling end-users to select which hub they want to use is to generate dummy feeds on filtering/processing hubs (e.g. http://www.hubforfiltering.com/http://www.myfeed.com/atom). The contents of this dummy feed is the same as the contents of the original feed but with a simple difference - the hub elements from the original feed are removed and a hub element for new hub is inserted. This way, when the end-user passes the dummy feed URI to the subscriber application, the application will subscribe to the filtering/processing hub, not the original one. The filtering/processing hub then subscribes to the original hub to receive updates, filters/processes received updates and notifies the subscriber.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Masking the filtering/processing services as the subscriber which then notifies the real subscriber. &lt;/strong&gt;I'm not sure this is possible (too lazy to go through the PSHB spec), but in theory, here's how it would work. The subscriber would obtain an URI pointing to the filtering/processing service for which the service would know what the real subscriber notification callback is (e.g. http://www.filter.com?subscriber=http://www.realsubscriber.com/callback). The subscriber would subscribe to the hub using the obtained URI. When the publisher publishes an update, the hub would pass the update to the filtering/processing service thinking it was the subscriber. The filtering/processing service would do it's thing and pass the update to the real subscriber. It's unclear though how this would be done by end-users since they'd have to know the subscriber application's callback URI.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;strong&gt;All of these approaches have their pros and cons.&lt;/strong&gt; Some are not easily or at all end-user definable, some may introduce unnecessary duplication of notifications, some introduce delivery of unwanted notifications, some do not support reuse of existing infrastructure and cause unnecessary duplication of systems, and most do not promote the development of filtering/processing services as a separate part of the ecosystem.&lt;/p&gt;

&lt;h2&gt;Real-time feed processing and filtering (take 2)&lt;/h2&gt;


&lt;p&gt;What I believe is needed is an architecture and protocol which supports three things. First - &lt;strong&gt;filtering/processing services as a separate part of the ecosystem&lt;/strong&gt;. Since publishers and subscribers can't possibly anticipate and implement every possible filter and processing service, this will enable a stream of development activity resulting in services with different functionality, performance and business models. Again, applications enabling other applications help software ecosystems grow.&lt;/p&gt;

&lt;p&gt;Second - &lt;strong&gt;a scalable processing model where hubs invoke filtering/processing services&lt;/strong&gt;. Regarding architectural decisions on where filtering/processing should be applied, there's a paper (&lt;a href=&quot;http://portal.acm.org/citation.cfm?id=343622&quot; target=&quot;_blank&quot;&gt;citation&lt;/a&gt;, &lt;a href=&quot;http://eprints.kfupm.edu.sa/22490/1/22490.pdf&quot; target=&quot;_blank&quot;&gt;pdf&lt;/a&gt;) from 2000. on &quot;&lt;em&gt;Achieving Scalability and Expressiveness in an Internet-scale Event Notification Service&lt;/em&gt;&quot; which states two principles:&lt;/p&gt;

&lt;blockquote&gt;

Downstream replication: A notification should be routed in one copy as far as possible and should be replicated only downstream, that is, as close as possible to the parties that are interested in it.

Upstream evaluation: Filters are applied and patterns are assembled upstream, that is, as close as possible to the sources of (patterns of) notifications.

&lt;/blockquote&gt;


&lt;p&gt;In short, these principles state that &lt;strong&gt;filtering services should be applied as close to the publisher&lt;/strong&gt; as possible so notifications that nobody wants don't waste network resources. However, &lt;strong&gt;processing services should be applied as close to the subscriber&lt;/strong&gt; so that the original update may be transported through the network as a single notification for as long as possible. In cases where there's a single hub between the publisher and subscriber, the same hub would invoke both processing and filtering services. However, in more complex hub network topologies different hubs would invoke different types of services based on their topological proximity to the subscriber/publisher.&lt;/p&gt;

&lt;p&gt;Third and last - &lt;strong&gt;end-user selection of these services&lt;/strong&gt;. When 3rd party filtering/processing services exist - how will they be chosen for a particular subscription? In my opinion, this must be done by end-users and thus there must be an easy way of doing it. The first thing that comes to mind would be to extend the subscription user-interface (UI) exposed to users of subscriber applications. E.g. instead of just showing a textbox for defining the feed the users wants to follow, there could be an &quot;Advanced&quot; menu with textboxes for defining filtering and processing services.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/images/pshbnew.png&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;New PSHB architecture and protocol outline&quot; src=&quot;/images/pshbnew.png&quot; alt=&quot;New PSHB architecture and protocol outline&quot; width=&quot;454&quot; height=&quot;282&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No matter how cool I think this would be as a core part of the PSHB protocol, it's probably a better idea doing it as an extension (as a first step?). So here's what the extension would define:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;The subscription part of the protocol additionally &lt;strong&gt;enables subscribers to define two lists of URIs &lt;/strong&gt;when subscribing to a hub&lt;strong&gt;, one declaring the list of filtering services and the other the list of processing services &lt;/strong&gt;that should be applied.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Hubs are responsible &lt;/strong&gt;not only for delivery of notifications but also&lt;strong&gt; for calling filtering/processing services&lt;/strong&gt; on those notifications and receiving their responses. An inter-hub subscription negotiation/propagation &lt;strong&gt;mechanism that enables the optimal placement of subscription-defined filters and processing services in the delivery flow&lt;/strong&gt;. In case of a single hub, nothing needs to be done since the hub invokes both types of services. However, in case of two hubs, the hub which first received the subscription would locally subscribe to the second hub stating only the filtering services while processing services would not be sent upstream. Thus, the hub closer to the subscriber would be responsible for invoking processing services, and the hub closer to the publisher would be responsible for invoking filtering services. This could, I believe, be generalized and formalized for any kind of hub network topology.&lt;/li&gt;
    &lt;li&gt;When an update is published, hubs responsible for invoking filtering or processing services must do so before forwarding the notifications downstream. There are several performance-related issues which need to be addressed here. First, &lt;strong&gt;the invocation of filtering/processing services should be asynchronous, &lt;/strong&gt;&lt;a href=&quot;http://www.webhooks.org/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;webhook&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;-based&lt;/strong&gt; (the hub calls a service passing an URI to which the result of processing should be POSTed). Second, &lt;strong&gt;invocation of services on a specific hub for a specific notification should be done in parallel&lt;/strong&gt;, except if multiple processing services were defined for a single subscription in which case those processing services must be invoked serially (filters can always be invoked in parallel). Third, there's a not-so-clear trade-off between a) waiting for all invoked filters to respond and sending a single notification carrying all metadata regarding which filters it satisfied and b) &lt;strong&gt;sending  multiple notifications containing the same content but different metadata regarding which filters were satisfied &lt;/strong&gt;(e.g. as each filter responds). Since all filters will not respond at the same time (some will respond sooner, some later and some possibly never) - waiting for all filters invoked in parallel before continuing seems contradictory to the constraint of real-time delivery. On the other hand, creating multiple notifications with the same data will introduce an overhead in the network. Overall, I believe that the overhead will not be substantial since there will not be many duplicates -- this can even be regulated as a hub-level parameter e.g. one notification for services returning in under 2 seconds, one for under 10 second, and one for everything else, and the benefit is basically a necessity.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;Conclusion&lt;/h2&gt;


&lt;p&gt;Of course I didn't consider all aspects of the problem and there are a lot more points of view to be considered, from is it legal to change content in a feed and in what way to how do we make this extension secure and fault tolerant? Nevertheless, I believe that the need and expertise are here and that it's an &lt;strong&gt;opportunity to make the real time web better&lt;/strong&gt;. What are your ideas for extending real-time content delivery technologies? &lt;a href=&quot;http://www.twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>RPC for Web Workers and distributed computing within the browser</title>
   <link href="http://ivanzuzak.info/2009/12/21/rpc-for-web-workers-and-distributed-computing-within-the-browser.html"/>
   <updated>2009-12-21T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2009/12/21/rpc-for-web-workers-and-distributed-computing-within-the-browser</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://ivanzuzak.info/2009/10/10/inter-window-browser-communication-and-how-to-make-it-better/&quot; target=&quot;_blank&quot;&gt;In a previous post&lt;/a&gt; I wrote about &lt;a href=&quot;http://code.google.com/p/pmrpc&quot; target=&quot;_blank&quot;&gt;pmrpc&lt;/a&gt; - a project of mine for developing a JavaScript library for &lt;strong&gt;cross-domain inter-window RPC-style communication in HTML5 browsers&lt;/strong&gt;. RPC communication is based on two technologies: &lt;a href=&quot;http://dev.w3.org/html5/spec/Overview.html#crossDocumentMessages&quot; target=&quot;_blank&quot;&gt;HTML5 cross-domain messaging&lt;/a&gt; as the transport mechanism and &lt;a href=&quot;http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal&quot; target=&quot;_blank&quot;&gt;JSON-RPC&lt;/a&gt; as the RPC protocol and message format, while the library supports other advanced features (access control, asynchronous calls, retries...). At the end of the post I outlined a few things &lt;a href=&quot;http://twitter.com/ivankovic_42&quot; target=&quot;_blank&quot;&gt;Marko&lt;/a&gt; and I wanted to implement next in pmrpc, one of which was support for Web Workers. From the post:&lt;/p&gt;

&lt;blockquote&gt;&lt;a href=&quot;http://www.whatwg.org/specs/web-workers/current-work/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Web Workers&lt;/strong&gt;&lt;/a&gt; are another specification being developed in parallel with HTML5. The specification “defines an API for running scripts in the background independently of any user interface scripts”. What’s interesting is that the postMessage API is used to communicate with web workers and therefor pmrpc could be extended to include support for web workers.&lt;/blockquote&gt;


&lt;p&gt;Well, the API used to send messages from a web page to a worker and vice versa is not exactly the same as the cross-document messaging API, but is very similar. So, the idea for supporting Web Workers was leave the &lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcApiDocs&quot; target=&quot;_blank&quot;&gt;pmrpc API&lt;/a&gt; for registering, calling and unregistering procedure unchanged, and just extend it to also use the Web Worker API for message transport (in addition to the cross-doc messaging). And about two weeks ago we released &lt;a href=&quot;http://code.google.com/p/pmrpc/downloads/list&quot; target=&quot;_blank&quot;&gt;a new version of pmrpc&lt;/a&gt; with Web Worker support. Here's an example of &lt;strong&gt;using pmrpc with Web Workers&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [worker object A - testingWorker.js]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// load pmrpc library&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;importScripts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;pmrpc.js&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// expose a procedure&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;               &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; // [window object B]
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; // load pmrpc library
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;pmrpc.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; // create worker
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;testingWorker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Worker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;testingWorker.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// calls the exposed procedure&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;testingWorker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;A few notes on worker support. Pmrpc currently supports only normal (&quot;dedicated&quot;) Web Workers. Shared Workers (workers shared between multiple web pages) and nested workers (workers within workers) are currently not supported since, as far as I know,&lt;strong&gt; Shared and nested Workers are not implemented yet in any browser&lt;/strong&gt;. Also, since Workers must be loaded from the same origin as the page that created them - the &lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcApiDocs#Access_control&quot; target=&quot;_blank&quot;&gt;access control feature&lt;/a&gt; in pmrpc make no sense and are therefore not supported for Web Workers.&lt;/p&gt;

&lt;p&gt;Next on our list is enabling &lt;strong&gt;discovery of registered procedures&lt;/strong&gt; scattered over multiple browser workers, iframes and windows. Currently, pmrpc requires that you tell it where the procedure you are calling is, but sometimes you don't know where it is, or don't care - e.g. you just want to call the &quot;DrawMap&quot; procedure loaded from domain &quot;http://www.good.com&quot; if it exists. Discovery should enable discovery of methods based just on their names. The problems in implementing this feature (knowing which windows, iframes and workers are currently running and syncing the list of registered procedures with each of them) made me think about where systems running in browsers are heading - towards a form of &lt;strong&gt;distributed &amp;amp; parallel computing, only within a single browser&lt;/strong&gt;. Distributed and concurrent execution, discovery, access control, synchronization, remote invocation, fault tolerance and naming are all concepts well know in distributed computing, and will possibly be re-invented in the context of web browsers to support this new shift. I'm not sure how far pmrpc will go in this direction, but I hope it will be a good example for other developers and research projects.&lt;/p&gt;

&lt;p&gt;Do you think that web browsers need more powerful mechanisms supporting this new form of distributed computing? &lt;a href=&quot;http://www.twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Extending and customizing Google Code project hosting</title>
   <link href="http://ivanzuzak.info/2009/12/13/extending-and-customizing-google-code-project-hosting.html"/>
   <updated>2009-12-13T00:00:00-08:00</updated>
   <id>http://ivanzuzak.info/2009/12/13/extending-and-customizing-google-code-project-hosting</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://code.google.com/hosting/&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;aligncenter&quot; style=&quot;margin-top:25px;margin-bottom:15px;&quot; title=&quot;Google Code&quot; src=&quot;http://www.gstatic.com/codesite/ph/images/code_small.png&quot; alt=&quot;&quot; width=&quot;161&quot; height=&quot;40&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've used &lt;a href=&quot;http://code.google.com/hosting/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Google Code project hosting&lt;/strong&gt;&lt;/a&gt; for almost every project I've started in the last few years. It's really great and I love both the Web UI and all the functionality-related features (which Google is &lt;a href=&quot;http://code.google.com/p/support/wiki/WhatsNew&quot; target=&quot;_blank&quot;&gt;continuously extending&lt;/a&gt;). However, one aspect in which I've found Google Code project hosting&lt;strong&gt; strangely lacking &lt;/strong&gt;&lt;strong&gt;is customizability and extendability&lt;/strong&gt; in adding rich content and even external applications to a project site. Wouldn't it be great if we could add a special &quot;Testing&quot; and &quot;Group discussion&quot; tab or an easy way to embed presentations and JavaScript code into wiki pages? This would boost the usability of project sites and make the visitor experience so much better.&lt;/p&gt;


&lt;p&gt;So, I've been thinking about this idea and playing with &lt;strong&gt;hacks and workarounds for extending Google code sites&lt;/strong&gt; &lt;a href=&quot;http://code.google.com/p/pmrpc/&quot; target=&quot;_blank&quot;&gt;for&lt;/a&gt; &lt;a href=&quot;http://code.google.com/p/urlecho/&quot; target=&quot;_blank&quot;&gt;my&lt;/a&gt;&lt;a href=&quot;http://code.google.com/p/feed-buster/&quot; target=&quot;_blank&quot;&gt; projects&lt;/a&gt;, and what I've discovered is that I'm not alone - &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot; target=&quot;_blank&quot;&gt;several&lt;/a&gt; &lt;a href=&quot;http://code.google.com/p/google-caja/&quot; target=&quot;_blank&quot;&gt;other&lt;/a&gt; &lt;a href=&quot;http://code.google.com/p/closure-library/&quot; target=&quot;_blank&quot;&gt;projects&lt;/a&gt; have been doing this also. So in this post I'll try to cover two approaches to extending and customizing Google Code project hosting: embedding 3rd party content using &lt;strong&gt;Google Gadgets&lt;/strong&gt; and viewing non-source files in the repository using the &lt;strong&gt;SVN mime-types property&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The first idea for extending project sites is to &lt;strong&gt;embed 3-rd party content into wiki pages&lt;/strong&gt; (Google Docs presentations, JavaScript programs and such). Although it is possible to use a &lt;a href=&quot;http://code.google.com/p/support/wiki/WikiSyntax#HTML_support&quot; target=&quot;_blank&quot;&gt;large subset of HTML&lt;/a&gt; in project wiki pages, &amp;lt;iframe&amp;gt; and &amp;lt;script&amp;gt; tags are not available. However, embedding Google Gadgets &lt;em&gt;is &lt;/em&gt;supported. &lt;a href=&quot;http://code.google.com/apis/gadgets/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Google Gadgets&lt;/strong&gt;&lt;/a&gt; are &quot; simple HTML and JavaScript applications that can be embedded in webpages and other apps&quot; (think clock, calendar, twitter and similar widgets) and are, in essence, an HTML &amp;lt;iframe&amp;gt; embedded in the parent page. Although there is a &lt;a href=&quot;http://www.google.com/ig/directory?synd=open&quot; target=&quot;_blank&quot;&gt;public directory of existing Gadgets&lt;/a&gt; which you could add to your wiki pages, what's more interesting is that you can build a Gadget yourself and that it's really easy to do. So, finally, the first idea for extending Google Code project hosting is to&lt;strong&gt; build your own Google Gadgets which wrap the content you want to embed in your wiki page&lt;/strong&gt;. Here's what you need to do:&lt;/p&gt;

&lt;ol style=&quot;padding-left:30px;&quot;&gt;
    &lt;li&gt;Create a file containing a blank, content-less XML Gadget specification -- you can just copy/paste the code from the &lt;a href=&quot;http://code.google.com/apis/gadgets/docs/gs.html#Hello_World&quot; target=&quot;_blank&quot;&gt;Google Gadgets tutorial&lt;/a&gt;.&lt;/li&gt;
    &lt;li&gt;Define the content of the Gadget. Depending on what you want to embed in your wiki page, there are two ways to go here:
&lt;ol&gt;
    &lt;li&gt;If you want to embed an existing web page or rich content available on the Web, the content of the Gadget will be a single &amp;lt;iframe&amp;gt; element with the src attribute pointing to the URL of that web-page.&lt;/li&gt;
    &lt;li&gt;If you want to embed content which does not exist on the web, you will have to write the HTML + JavaScript code that defines that content yourself and inline it in the Gadget. Be sure to check out the &lt;a href=&quot;http://code.google.com/apis/gadgets/docs/dev_guide.html&quot; target=&quot;_blank&quot;&gt;Google Gadgets developer guide&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
    &lt;li&gt;Save and upload the Gadget XML specification file into your project repository.&lt;/li&gt;
    &lt;li&gt;Edit one of your wiki pages and create a Google Gadget element that references the URL of the uploaded specification. &lt;strong&gt;Note&lt;/strong&gt; that you must reference the raw-file URL of the XML spec which you can get by viewing the uploaded file in your project's Source tab and then clicking &quot;View raw file&quot; under File info.&lt;/li&gt;
&lt;/ol&gt;




&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/pubsubhubbub&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Example 1&quot; src=&quot;/images/blog_pres1.png&quot; alt=&quot;Example 1&quot; width=&quot;90%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/feed-buster&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Example 2&quot; src=&quot;/images/blog_ff1.png&quot; alt=&quot;Example 2&quot; width=&quot;90%&quot;  /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;center&gt; 1. PubSubHubBub &lt;/center&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;center&gt; 2. Feed-buster &lt;/center&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcTesting&quot;&gt;&lt;img class=&quot;aligncenter&quot;  title=&quot;Example 3&quot; src=&quot;/images/blog_qunit1.png&quot; alt=&quot;Example 3&quot; width=&quot;90%&quot;  /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/urlecho&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Example 4&quot; src=&quot;/images/blog_form1.png&quot; alt=&quot;Example 4&quot; width=&quot;90%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;center&gt; 3. Pmrpc testing &lt;/center&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;center&gt; 4. UrlEcho &lt;/center&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;And here are some examples that show the usefulness of this approach (images above, in order of appearance):&lt;/p&gt;

&lt;ol style=&quot;padding-left:30px;&quot;&gt;
    &lt;li&gt;&lt;strong&gt;Embedding Google Docs presentations&lt;/strong&gt; that visually explain details of your project (&lt;a href=&quot;http://code.google.com/p/pubsubhubbub/&quot; target=&quot;_blank&quot;&gt;example project wiki page&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/source/browse/trunk/presentation_gadget.xml&quot; target=&quot;_blank&quot;&gt;XML spec&lt;/a&gt;). To get a Google Docs URL which you can use for embedding, go the presentation's page in Google Docs, click &quot;Share - Publish/Embed&quot;, and copy the URL under &quot;Your document is publicly viewable at:&quot;.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Embedding a FriendFeed discussion groups&lt;/strong&gt; for in-place discussions (&lt;a href=&quot;http://code.google.com/p/feed-buster/#Feedback&quot; target=&quot;_blank&quot;&gt;example project wiki page&lt;/a&gt; and &lt;a href=&quot;http://hosting.gmodules.com/ig/gadgets/file/105320743644204138718/feedbuster.xml&quot; target=&quot;_blank&quot;&gt;XML spec&lt;/a&gt; -- if you see a blank page, view the source of the page). To get a FriendFeed group URL which you can use for embedding, use the &lt;a href=&quot;http://friendfeed.com/embed/realtime&quot; target=&quot;_blank&quot;&gt;official FriendFeed instructions&lt;/a&gt; (basically, it's http://friendfeed.com/GROUP_NAME_HERE/embed e.g. &lt;a href=&quot;http://friendfeed.com/feed-buster/embed&quot;&gt;http://friendfeed.com/feed-buster/embed&lt;/a&gt;).&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Embedding QUnit testing pages&lt;/strong&gt; for following project stability and cross-browser testing (&lt;a href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcTesting&quot; target=&quot;_blank&quot;&gt;example project wiki page&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/pmrpc/source/browse/trunk/testing/testingGadget.xml&quot; target=&quot;_blank&quot;&gt;XML spec&lt;/a&gt;). This one is a bit complex -- first you'll need to create and upload a HTML page containing the QUnit test page (setting the mime-type property to text/html using instructions below) into your repository, and then link to the raw page URL in the &amp;lt;iframe&amp;gt; inside your Gadget.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Embedding dynamic content&lt;/strong&gt; and forms (&lt;a href=&quot;http://code.google.com/p/urlecho/#AppEngine_server&quot; target=&quot;_blank&quot;&gt;example project wiki page&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/urlecho/source/browse/trunk/googlecodegadget.xml&quot; target=&quot;_blank&quot;&gt;XML spec&lt;/a&gt;). There is no outside content in the Gadget spec here, everything is in the Gadget. &lt;strong&gt;Note &lt;/strong&gt;that the XML spec in the example also contains CSS styles so that the Gadget content has the same look-and -feel as the rest of the wiki page so visitors won't event know that a Gadget is there.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The second idea for extending project sites involves &lt;strong&gt;using the source repository for hosting non-source files&lt;/strong&gt; which will be viewed by project site visitors. This is useful if you want the freedom of creating custom web pages (not embed them into project wikis) and if you want to keep all those files in the project repository (and not on some other server). The idea here is to use the raw-file URL for files in the repository - visiting the raw-file view URL returns only the content of the file without the UI stuff of Google Code. The problem is that, by default, any file uploaded to the repository is attributed to be of type &lt;em&gt;text&lt;/em&gt;, so when you view the raw-file URL in the browser you get the content as text, which is useless if you want to see a HTML page. The good thing is that using custom SVN per-file properties it is possible to set the type of the file when it is uploaded in the repository. So, finally, the second idea for extending Google Code project hosting is to &lt;strong&gt;upload your content files into the repository and explicitly set their mime-types to the correct value&lt;/strong&gt;. Here's what you need to do :&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Create your content and save it into a file on your hard drive in the project repository folder.&lt;/li&gt;
    &lt;li&gt;Right-click the file and under TortoiseSVN -&amp;gt; Properties click &quot;New&quot;. In the &quot;Property name&quot; drop-down list choose &quot;svn:mime-type&quot; and ender the correct mime type for that file. You can find a list of all mime types here. E.g. for HTML pages it's &quot;text/html&quot; (this is for TortoiseSVN, command-line version is &lt;a href=&quot;http://code.google.com/p/support/wiki/SubversionFAQ#How_can_I_make_SVN_serve_HTML_and_images_with_the_correct_Conten&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;).&lt;/li&gt;
    &lt;li&gt;Upload the file to the repository.&lt;/li&gt;
    &lt;li&gt;Obtain the URL to the raw-file by viewing the uploaded file in your project's Source tab and then clicking &quot;View raw file&quot; under File info.&lt;/li&gt;
    &lt;li&gt;Create a link to the obtained URL from one of your wiki pages.&lt;/li&gt;
&lt;/ol&gt;




&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href=&quot;http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.2.html&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Example 1&quot; src=&quot;/images/blog_pshb.png&quot; alt=&quot;Example 1&quot; width=&quot;90%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;a href=&quot;http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/index.html&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Example 2&quot; src=&quot;/images/blog_closure.png&quot; alt=&quot;Example 2&quot; width=&quot;90%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;center&gt; 1. PubSubHubBub specification &lt;/center&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;center&gt; 2. Closure library API docs &lt;/center&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;


&lt;p&gt;And here are two examples that show the usefulness of this approach (images above, in order of appearance):&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;&lt;strong&gt;Creating a protocol specification with custom styling&lt;/strong&gt; (&lt;a href=&quot;http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.2.html&quot; target=&quot;_blank&quot;&gt;example project page&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/pubsubhubbub/source/browse/trunk/pubsubhubbub-core-0.2.html&quot; target=&quot;_blank&quot;&gt;source file&lt;/a&gt;)&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Creating advanced API docs&lt;/strong&gt; (&lt;a href=&quot;http://closure-library.googlecode.com/svn/trunk/closure/goog/docs/index.html&quot; target=&quot;_blank&quot;&gt;example project page&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/closure-library/source/browse/#svn/trunk/closure/goog/docs/index.html&quot; target=&quot;_blank&quot;&gt;source file&lt;/a&gt; -- note: you will not be able to view the source file, access is being blocked somehow)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;And that's it. Go fancy-up your project sites and let me know if you know any other cool ways of extenting Google Code project hosting. &lt;a href=&quot;http://www.twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Inter-window browser communication and how to make it better</title>
   <link href="http://ivanzuzak.info/2009/10/10/inter-window-browser-communication-and-how-to-make-it-better.html"/>
   <updated>2009-10-10T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2009/10/10/inter-window-browser-communication-and-how-to-make-it-better</id>
   <content type="html">&lt;p&gt;As promised in my &lt;a target=&quot;_blank&quot; href=&quot;http://ivanzuzak.info/2009/08/09/named-arguments-in-javascript.html&quot;&gt;post on named arguments in JavaScript&lt;/a&gt;, this post will be about &lt;a href=&quot;http://code.google.com/p/pmrpc&quot;&gt;pmrpc&lt;/a&gt; - a project I've been working on with &lt;a target=&quot;_blank&quot; href=&quot;http://mivankovic.blogspot.com/&quot;&gt;Marko&lt;/a&gt; for the last few months.&lt;/p&gt;

&lt;p&gt;But first, a bit of background. From mid 2007. when I was interning at Google up until today and my dissertation-related research, an issue that's consistently been popping up in anything I worked on is inter-window communication. &lt;strong&gt;Inter-window communication (IWC)&lt;/strong&gt; is the process of transporting data from one window object within a browser to another window object inside the same browser. What's relevant here is that window objects are both full-size windows and iframes - window objects that can be embedded within other window objects (think of an &lt;a target=&quot;_blank&quot; href=&quot;http://www.igoogle.com&quot;&gt;iGoogle&lt;/a&gt; page and all the gadgets in it).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://code.google.com/gme/articles/images/mashupgadgets_igoogle.jpg&quot; title=&quot;iGoogle&quot; class=&quot;aligncenter&quot; width=&quot;362&quot; height=&quot;220&quot;&gt;&lt;/p&gt;

&lt;p&gt;The reason why IWC is an issue is the security model of communication within browsers. &lt;strong&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Same_origin_policy&quot;&gt;Same Origin Policy&lt;/a&gt;&lt;/strong&gt; (SOP), a security policy introduced to reduce security risks, restricts access of processes executing within browsers. In essence, SOP prevents a document or script loaded from one domain from getting or setting properties of a document from another domain. For example, a page loaded from &lt;em&gt;http://www.google.com&lt;/em&gt; can not directly access data in an iframe loaded from &lt;em&gt;http://www.yahoo.com&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Although SOP turns Web applications into a set of isolated units, the &lt;a target=&quot;_blank&quot; href=&quot;http://groups.google.com/group/talk-about-widgets/web/use-cases-for-iwc&quot;&gt;need for communication between those islands&lt;/a&gt; is growing rapidly. With the advancement web technologies, web applications were slowly becoming componentized and many current web applications are based on &lt;strong&gt;mashing-up content from different sources&lt;/strong&gt; - map gadgets, finance widgets, blog commenting toolboxes, games, chat widgets and &lt;a target=&quot;_blank&quot; href=&quot;http://www.google.com/ig/directory&quot;&gt;many&lt;/a&gt;, &lt;a target=&quot;_blank&quot; href=&quot;http://www.facebook.com/apps/directory.php&quot;&gt;many&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://www.widgetbox.com/tag_cloud.jsp&quot;&gt;others&lt;/a&gt;. Since widgets, content encapsulated within an iframe, are the most popular method of including cross-domain content on a web page, &lt;strong&gt;inter-widget communication&lt;/strong&gt; is most often implemented as inter-window communication.&lt;/p&gt;

&lt;p&gt;A lot of &lt;strong&gt;groups and projects are researching models and developing systems&lt;/strong&gt; that address the problem of communication between widgets and between windows in general. So here's a short overview of this broad space of R&amp;amp;D. &lt;a target=&quot;_blank&quot; href=&quot;http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/Gadgets-API-Specification.html&quot;&gt;Various&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://www.w3.org/TR/widgets/&quot;&gt;widget&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://www.openajax.org/member/wiki/OpenAjax_Metadata_1.0_Specification_Widget_Overview&quot;&gt;specifications&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://dev.opera.com/articles/view/opera-widgets-specification-1-0-third-ed-2/&quot;&gt;are trying&lt;/a&gt; to formally define and standardize what a widget actually is. &lt;a target=&quot;_blank&quot; href=&quot;http://code.google.com/p/browsersec/w/list&quot;&gt;Browser security in general&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://w2spconf.com/2007/papers/paper-170-z_6423.pdf&quot;&gt;various issues&lt;/a&gt; concerning &lt;a target=&quot;_blank&quot; href=&quot;http://seclab.stanford.edu/websec/frames/post-message.pdf&quot;&gt;intra-browser communication&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://domino.research.ibm.com/library/cyberdig.nsf/papers/0EE2D79F8BE461CE8525731B0009404D/$File/RT0742.pdf&quot;&gt;mashup security&lt;/a&gt; are &lt;a target=&quot;_blank&quot; href=&quot;http://www.adambarth.com/papers/2009/barth-weinberger-song.pdf&quot;&gt;being&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://www.adambarth.com/papers/2009/barth-jackson-li.pdf&quot;&gt;heavily&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://www.adambarth.com/papers/2009/reis-barth-pizano.pdf&quot;&gt;researched&lt;/a&gt;. &lt;a target=&quot;_blank&quot; href=&quot;http://www.cs.rutgers.edu/~vinodg/papers/acsac2008b/acsac2008b.pdf&quot;&gt;Low-level IWC mechanisms&lt;/a&gt; are &lt;a target=&quot;_blank&quot; href=&quot;http://json.org/module.html&quot;&gt;being&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://dev.w3.org/html5/spec/Overview.html#crossDocumentMessages&quot;&gt;proposed&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://code.google.com/p/xssinterface/&quot;&gt;implemented&lt;/a&gt;, sometimes even as &lt;a target=&quot;_blank&quot; href=&quot;http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html&quot;&gt;browser hacks&lt;/a&gt;, and &lt;a target=&quot;_blank&quot; href=&quot;http://www.openajax.org/member/wiki/OpenAjax_Hub_1.1_Specification_Publish_Subscribe_Overview&quot;&gt;high-level&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://www.cs.rutgers.edu/~vinodg/papers/acsac2008b/acsac2008b.pdf&quot;&gt;communication models&lt;/a&gt; are being &lt;a target=&quot;_blank&quot; href=&quot;http://www2009.eprints.org/138/&quot;&gt;researched&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://svn.apache.org/repos/asf/incubator/shindig/trunk/features/src/main/javascript/features/rpc/&quot;&gt;developed&lt;/a&gt;. Even patents have been filed for methods of &lt;a target=&quot;_blank&quot; href=&quot;http://www.faqs.org/patents/app/20080295024&quot;&gt;inter-window&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://www.wipo.int/pctdb/en/wo.jsp?WO=2009036093&quot;&gt;inter-widget&lt;/a&gt; communication.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;HTML5 logo&quot; src=&quot;http://www.newsgeek.co.il/wp-content/uploads/2009/06/html5-logo.jpg&quot; alt=&quot;&quot; width=&quot;150&quot; height=&quot;200&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Among all of these efforts, one is catching on on a wider scale - the &lt;strong&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://dev.w3.org/html5/spec/Overview.html#crossDocumentMessages&quot;&gt;HTML5 cross-document messaging specification&lt;/a&gt;&lt;/strong&gt; aka the &lt;strong&gt;postMessage API&lt;/strong&gt;.  The postMessage API has been implemented in all popular web browsers and enables secure message-oriented communication between any window objects - scripts in any window may send messages to any other window and receive messages from scripts in other windows. Security is established by two access-control mechanisms: 1) the message sender may specify the domain from which the destination window must be loaded in order for the message to be delivered, and 2) the message receiver may inspect the domain from which a message was sent and drop unwanted messages.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;problem with postMessage is that it's a very low-level and general&lt;/strong&gt; communication mechanism which requires a lot of boiler-plate code every time it is used and even more if one wants to implement advanced communication or access-control models. Have a look at the &lt;a target=&quot;_blank&quot; href=&quot;http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#introduction-5&quot;&gt;example on using postMessage in the HTML5 spec&lt;/a&gt; to see what I'm talking about. However, it's exactly this generality and low-levelness that makes &lt;strong&gt;postMessage an excellent foundation to build upon&lt;/strong&gt;! Some of the projects I mentioned above have been working on &lt;a target=&quot;_blank&quot; href=&quot;http://svn.apache.org/repos/asf/incubator/shindig/trunk/features/src/main/javascript/features/rpc/&quot;&gt;advanced&lt;/a&gt; &lt;a target=&quot;_blank&quot; href=&quot;http://svn.apache.org/repos/asf/incubator/shindig/trunk/features/src/main/javascript/features/pubsub/&quot;&gt;communication libraries&lt;/a&gt; based on postMessage, but none that I know of are open-source and applicable in any context but rather tied to a specific application environment. Furthermore, advanced access control, fault tolerance and many other aspects of inter-window communication have been under-explored. These drawbacks were the main motivators for developing pmrpc.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;pmrpc logo&quot; src=&quot;http://code.google.com/p/pmrpc/logo?logo_id=1248529567&quot; alt=&quot;&quot; width=&quot;55&quot; height=&quot;55&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a target=&quot;_blank&quot; href=&quot;http://code.google.com/p/pmrpc&quot;&gt;Pmrpc&lt;/a&gt;&lt;/strong&gt; (&lt;em&gt;&lt;strong&gt;p&lt;/strong&gt;ost&lt;strong&gt;M&lt;/strong&gt;essage &lt;strong&gt;r&lt;/strong&gt;emote &lt;strong&gt;p&lt;/strong&gt;rocedure &lt;strong&gt;c&lt;/strong&gt;all&lt;/em&gt;) is a JavaScript library for advanced inter-window cross-domain communication. The library utilizes the postMessage API as an underlying communication mechanism and extends it to a &lt;a target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Remote_procedure_call&quot;&gt;remote procedure call (RPC) model&lt;/a&gt; using JSON-RPC. &lt;a target=&quot;_blank&quot; href=&quot;http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal&quot;&gt;JSON-RPC&lt;/a&gt; is a transport-independent protocol that uses the &lt;a target=&quot;_blank&quot; href=&quot;http://www.json.org&quot;&gt;JSON data format&lt;/a&gt; for formatting messages. The pmrpc library provides a simple API for exposing and calling procedures from windows or iFrames on different domains.&lt;/p&gt;

&lt;p&gt;Here's a &lt;strong&gt;simple example&lt;/strong&gt; for calling a function in another window:&lt;/p&gt;

&lt;p style=&quot;padding-left:30px;&quot;&gt;1. First, a procedure is registered for remote calls in the window or iFrame that contains the procedure:&lt;/p&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [window object A] exposes a procedure in it&amp;#39;s window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;printParam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;p style=&quot;padding-left:30px;&quot;&gt;2. Second, the procedure is called from a remote window or iFrame by specifying the window object which contains the remote procedure, name of the procedure and parameters:&lt;/p&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [window object B] calls the exposed procedure remotely, from its own window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;myIframe&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;5&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Furthermore, pmrpc also provides several &lt;strong&gt;features for advanced communication&lt;/strong&gt;: &lt;strong&gt;callbacks&lt;/strong&gt; for successful and unsuccessful calls, &lt;strong&gt;access control lists&lt;/strong&gt; on both the client and server side, &lt;strong&gt;fault tolerance&lt;/strong&gt; using user-defined retries and timeouts for each call, registering &lt;strong&gt; asynchronous procedures&lt;/strong&gt;. The features and their usage are explained in detail on the &lt;a target=&quot;_blank&quot; href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcApiDocs&quot;&gt;pmrpc API docs page&lt;/a&gt; and a &lt;a target=&quot;_blank&quot; href=&quot;http://docs.google.com/present/view?id=dctznkrh_677n8758gf8&quot;&gt;short presentation&lt;/a&gt;, so I'll just give an &lt;strong&gt;example of an advanced pmrpc call&lt;/strong&gt;:&lt;/p&gt;

&lt;p style=&quot;padding-left:30px;&quot;&gt;1. First, a synchronous procedure named &quot;HelloPMRPC&quot; accessible from windows and iframes loaded from any page on &quot;http://www.myFriendlyDomain1.com&quot; or exactly from the &quot;http://www.myFriendlyDomain2.com&quot; page is registered:&lt;/p&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [window object A] exposes a procedure in it&amp;#39;s window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;alertText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;alertText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accessControlList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;whitelist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.myFriendlyDomain1.com*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.myFriendlyDomain2.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;blacklist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;   &lt;span class=&quot;s2&quot;&gt;&amp;quot;publicProcedureName&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;   &lt;span class=&quot;s2&quot;&gt;&amp;quot;procedure&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;procedure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;   &lt;span class=&quot;s2&quot;&gt;&amp;quot;acl&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accessControlList&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;p style=&quot;padding-left:30px;&quot;&gt;2. Second, the procedure &quot;HelloPMRPC&quot; is called with a single positional parameter &quot;Hello world from pmrpc client!&quot;. In case of success, the return value will be alerted while in case of errors the error description will be alerted. The call will be retried up to 15 times, waiting 1500 milliseconds between retries. Windows or iFrames loaded from any domain, except from http://evil.com, may process the call:&lt;/p&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [window object B] calls the exposed procedure remotely, from its own window&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parameters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destination&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;frames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;targetIframeName&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;publicProcedureName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;HelloPMRPC&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello world from pmrpc client!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;onError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statusObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statusObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);},&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;retries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;destinationDomain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;nx&quot;&gt;whitelist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;nx&quot;&gt;blacklist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://evil.com*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pmrpc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Pmrpc is an &lt;strong&gt;open-source project&lt;/strong&gt; developed by &lt;a target=&quot;_blank&quot; href=&quot;http://mivankovic.blogspot.com/2009/10/pmrpc.html&quot;&gt;Marko Ivankovic&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;http://www.google.com/profiles/izuzak&quot;&gt;myself&lt;/a&gt; and is available under the &lt;strong&gt;Apache v2.0 license&lt;/strong&gt;. The library works in &lt;strong&gt;all web browsers&lt;/strong&gt; that implement the postMessage API (Firefox 3, Google Chrome, Internet Explorer 8). For more information please visit the &lt;a target=&quot;_blank&quot; href=&quot;http://code.google.com/p/pmrpc&quot;&gt;&lt;strong&gt;project homepage on Google Code&lt;/strong&gt;&lt;/a&gt; and the &lt;a target=&quot;_blank&quot; href=&quot;http://code.google.com/p/pmrpc/wiki/PmrpcApiDocs&quot;&gt;&lt;strong&gt;API docs page&lt;/strong&gt;&lt;/a&gt; for a full description of the API, feature list and usage examples.&lt;/p&gt;

&lt;p&gt;I'll end this post with a few &lt;strong&gt;ideas on making pmrpc even better&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;discovery&lt;/strong&gt; - currently, in order to call a remote procedure one needs to have a reference to a window that exposes that procedure. Sometimes obtaining a reference to a window is not very practical and easy (or possible) and a way to find windows by various criteria is needed. For example, discover all windows with a specific name or location or discover windows that expose a procedure with a specific name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;web workers&lt;/strong&gt; - &lt;a target=&quot;_blank&quot; href=&quot;http://www.whatwg.org/specs/web-workers/current-work/&quot;&gt;web workers&lt;/a&gt; are another specification being developed in parallel with HTML5. The specification &quot;defines an API for running scripts in the background independently of any user interface scripts&quot;. What's interesting is that the postMessage API is used to communicate with web workers and therefor pmrpc could be extended to include support for web workers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;publish-subscribe mechanism&lt;/strong&gt; - there are lots of communication models other than remote procedure call. One of the most popular models is &lt;a target=&quot;_blank&quot; href=&quot;http://en.wikipedia.org/wiki/Publish/subscribe&quot;&gt;publish-subscribe&lt;/a&gt; in which publishers publish events on channels and subscribers subscribe for events on these channels. Messages are delivered from publishers to subscribers without having a direct reference to each other.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I'd appreciate any feedback on pmrpc and our ideas for future work. What are your ideas for the future of inter-window communication? &lt;a target=&quot;_blank&quot; href=&quot;http://www.twitter.com/izuzak&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A better future for the FriendFeed tools and services ecosystem</title>
   <link href="http://ivanzuzak.info/2009/09/02/a-better-future-for-the-friendfeed-tools-and-services-ecosystem.html"/>
   <updated>2009-09-02T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2009/09/02/a-better-future-for-the-friendfeed-tools-and-services-ecosystem</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://friendfeed.com/fftools&quot;&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;FFtools&quot; src=&quot;http://friendfeed-media.com/p-ec49d82ba56b40f7a52b7fc838a84d44-large-1000&quot; alt=&quot;&quot; width=&quot;75&quot; height=&quot;75&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://friendfeed.com&quot; target=&quot;_blank&quot;&gt;FriendFeed&lt;/a&gt; is the only social-networking application I &lt;em&gt;get&lt;/em&gt; and like using, and one of the reasons why is that it's very community-oriented. The &lt;em&gt;groups &lt;/em&gt;and &lt;em&gt;friends &lt;/em&gt;approach of segmentation of attention easily directs both topic-oriented discussions and friends-oriented discussions towards the right people.&lt;/p&gt;

&lt;p&gt;One other nice thing about FriendFeed is that, although not as popular as Twitter or Facebook, it has a healthy ecosystem of developers extending and building upon the platform.  Lots of great &lt;a href=&quot;http://wittman.org/projects/friendfeedtranslate/install/index.html&quot; target=&quot;_blank&quot;&gt;user scripts&lt;/a&gt;, &lt;a href=&quot;http://ffcheck.com/&quot; target=&quot;_blank&quot;&gt;bookmarklets&lt;/a&gt;, &lt;a href=&quot;http://code.google.com/p/feed-buster&quot; target=&quot;_blank&quot;&gt;feed-processing services&lt;/a&gt;, &lt;a href=&quot;http://ffsms.com/&quot;&gt;sms services&lt;/a&gt; and &lt;a href=&quot;http://www.ffholic.com/&quot; target=&quot;_blank&quot;&gt;web apps&lt;/a&gt; have been developed and recently even more so with the release of the &lt;a href=&quot;http://friendfeed.com/api/documentation&quot; target=&quot;_blank&quot;&gt;new API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, what I don't like about the ecosystem is the separation of developers which develop tools and their potential users. Developers mostly use the official &lt;a href=&quot;http://groups.google.com/group/friendfeed-api&quot; target=&quot;_blank&quot;&gt;FriendFeed API Google group&lt;/a&gt; and &lt;a href=&quot;http://friendfeed.com/friendfeed-api&quot; target=&quot;_blank&quot;&gt;FriendFeed API group&lt;/a&gt; for discussing programming issues and the API, while non-programmers mostly join the &lt;a href=&quot;http://groups.google.com/group/friendfeed&quot; target=&quot;_blank&quot;&gt;FriendFeed Google group&lt;/a&gt; and the &lt;a href=&quot;http://friendfeed.com/friendfeed-feedback&quot; target=&quot;_blank&quot;&gt;FriendFeed Feedback&lt;/a&gt; and &lt;a href=&quot;http://friendfeed.com/friendfeed-beginners&quot; target=&quot;_blank&quot;&gt;FriendFeed for beginners&lt;/a&gt; FF groups. This definitely isn't the best solution for the future of the ecosystem. There is no central hub for the exchange of ideas between users and developers - users have a hard time finding existing tools and suggesting new ones while developers are have a hard time finding out what users need.&lt;/p&gt;

&lt;p&gt;Enter &lt;a href=&quot;http://friendfeed.com/fftools&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;FF tools and services&lt;/strong&gt;&lt;/a&gt; - a new FriendFeed group for both developers and users to discuss existing and future FF-related tools and services. The goals I hope the group will help catalyze are:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;establish a central place where &lt;strong&gt;both developers and users&lt;/strong&gt; of FriendFeed tools can go to sync up and discuss ideas,&lt;/li&gt;
    &lt;li&gt;compile a single &lt;a href=&quot;http://friendfeed.com/fftools/119bf1b1/list-of-ff-tools-and-services&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;list of all FriendFeed tools and services&lt;/strong&gt;&lt;/a&gt; - if you know or use a FF-related web app, bookmarklet or user script - just add it to this list and other users can use it to find cool apps,&lt;/li&gt;
    &lt;li&gt;compile a single &lt;a href=&quot;http://friendfeed.com/fftools/f5e50b9b/have-idea-for-cool-ff-web-app-or-service-add-your&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;list of suggestions for future FriendFeed tools and services&lt;/strong&gt;&lt;/a&gt; - if you have an idea for a cool FF web app or service which doesn't yet exist - just add it to this list and a developer with some free time might build it.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;And that's it - a place where the FriendFeed tools and services ecosystem can grow. &lt;a href=&quot;http://twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to supercharge your free AppEngine quota?</title>
   <link href="http://ivanzuzak.info/2009/08/27/how-to-supercharge-your-free-appengine-quota.html"/>
   <updated>2009-08-27T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2009/08/27/how-to-supercharge-your-free-appengine-quota</id>
   <content type="html">&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT (January 25 2012): This post was originally written in 2009. when AppEngine was still a &quot;beta&quot; product. In the meantime, AppEngine graduated and now has a &lt;a href=&quot;http://code.google.com/appengine/docs/billing.html&quot;&gt;shiny new billing policy&lt;/a&gt;. Long story short, Google &lt;a href=&quot;http://code.google.com/appengine/docs/billing.html#Enabling_Paid_Apps&quot;&gt;changed how paid apps work&lt;/a&gt;: &quot;Paid apps cost a minimum of $2.10/week&quot;. In result, the free lunch is over and all information in this blog post is not valid anymore. Still, I'm keeping the post around for historic reasons. &lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://code.google.com/appengine/&quot; target=&quot;_blank&quot;&gt;AppEngine&lt;/a&gt; is &lt;strong&gt;awesome&lt;/strong&gt;! Google's cloud computing platform is hosting countless web apps, from &lt;a href=&quot;http://moderator.appspot.com/&quot; target=&quot;_blank&quot;&gt;Google&lt;/a&gt; &lt;a href=&quot;http://pubsubhubbub.appspot.com/&quot; target=&quot;_blank&quot;&gt;products&lt;/a&gt; to innovative &lt;a href=&quot;http://appgallery.appspot.com/&quot; target=&quot;_blank&quot;&gt;personal projects&lt;/a&gt;, and is constantly being upgraded with cool &lt;a href=&quot;http://code.google.com/appengine/docs/roadmap.html&quot; target=&quot;_blank&quot;&gt;new features&lt;/a&gt;. &lt;span style=&quot;background-color:#ffffff;&quot;&gt;And best of all, AppEngine charges for resources (computing, storage and bandwidth) using a &lt;a href=&quot;http://en.wikipedia.org/wiki/Freemium&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;freemium&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;pricing model:&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;aligncenter&quot; title=&quot;Google AppEngine&quot; src=&quot;http://code.google.com/appengine/images/appengine_lowres.png&quot; alt=&quot;&quot; width=&quot;115&quot; height=&quot;88&quot; /&gt;&lt;em&gt;&quot;Each App Engine application can consume a certain level of computing resources for free, controlled by a set of &lt;/em&gt;&lt;a style=&quot;color:#0000cc;&quot; href=&quot;http://code.google.com/appengine/docs/quotas.html&quot;&gt;&lt;em&gt;quotas&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. Developers who want to grow their applications beyond these &lt;/em&gt;&lt;strong&gt;&lt;em&gt;free quotas&lt;/em&gt;&lt;/strong&gt;&lt;em&gt; can do so by enabling &lt;/em&gt;&lt;strong&gt;&lt;em&gt;billing &lt;/em&gt;&lt;/strong&gt;&lt;em&gt;for their application and set a daily resource budget, which will allow for the purchasing of additional resources if and when they are needed.&quot;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For example, the default free quota has a daily limit of 6.5 hours of CPU time with a maximum rate of 15 CPU-minutes/minute, while the billing enabled quota has 6.5 hours of free CPU time plus a maximum of 1,729 hours of paid CPU time with a maximum rate of 72 CPU-minutes/minute.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://code.google.com/appengine/docs/billing.html&quot; target=&quot;_blank&quot;&gt;Billing&lt;/a&gt; for paid resources is controlled with a &lt;strong&gt;daily budget&lt;/strong&gt; which developers set for each of their applications. The daily budget controls the amount of extra resources which may be purchased each day if the app steps over the free quota. The application developer defines how the daily budget is split between each of the &lt;strong&gt;billable quotas&lt;/strong&gt; - outgoing bandwidth, incoming bandwidth, CPU time, stored data and number of recipients emailed. For example, &lt;strong&gt;$1 &lt;/strong&gt;(the minimum daily budget) gets you 5 more CPU hours ($0.10 per CPU hour) and &lt;strong&gt;4 more GB of outgoing bandwidth &lt;/strong&gt;($0.12 per GB).&lt;/p&gt;

&lt;p&gt;Other than billable quotas, there are also &lt;strong&gt;unbillable quotas&lt;/strong&gt; which increase when you switch to the paid model but are not billed. So, &lt;strong&gt;by switching to the paid model, irregardless to how you distribute your budget, your app gets a free&lt;/strong&gt;&lt;strong&gt; bump&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;in the:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;number of requests it can process from &lt;strong&gt;1,300,000&lt;/strong&gt; to &lt;strong&gt;43,000,000&lt;/strong&gt; and from &lt;strong&gt;7,400&lt;/strong&gt; to &lt;strong&gt;30,000&lt;/strong&gt; req/min,&lt;/li&gt;
    &lt;li&gt;number of outgoing HTTP requests from &lt;strong&gt;657,000&lt;/strong&gt; to &lt;strong&gt;46,000,000&lt;/strong&gt; and from &lt;strong&gt;3,000&lt;/strong&gt; to &lt;strong&gt;32,000&lt;/strong&gt; req/min,&lt;/li&gt;
    &lt;li&gt;number of memcache calls from &lt;strong&gt;8,600,000 &lt;/strong&gt;to &lt;strong&gt;96,000,000&lt;/strong&gt; and from &lt;strong&gt;48,000&lt;/strong&gt; to &lt;strong&gt;108,000&lt;/strong&gt; calls/min,&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;and many others. These are very usable improvements by themselves for apps that need to process a lot of requests (or bursts of requests) which don't consume a lot of CPU time, or apps that need to make a lot of outgoing HTTP requests that don't consume a lot of bandwidth.&lt;/p&gt;

&lt;p&gt;So here's the idea for &lt;strong&gt;supercharging your free AppEngine quotas&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;switch you app to the paid model by enabling billing,&lt;/li&gt;
    &lt;li&gt;enter the minimum daily budget ($1),&lt;/li&gt;
    &lt;li&gt;distribute the budget over resources you are 100% sure will not consume their free quota (e.g. if you have a stateless app which doesn't use the database, put the whole $1 in the stored data quota).&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Since you put your budget on resources which won't consume the entire free quota and since AppEngine doesn't charge you anything if the app doesn't step over the free quota - you are essentially getting a &lt;strong&gt;better free quota&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT (Sept 5 2009):&lt;/strong&gt;&lt;/em&gt; Yesterday, a week after my original post, Google released AppEngine SDK 1.2.5 which includes a major feature a lot of developers have been waiting for - &lt;strong&gt;XMPP support&lt;/strong&gt;. What's interesting and relevant for this post is that XMPP has &lt;a href=&quot;http://code.google.com/appengine/docs/quotas.html#XMPP&quot;&gt;it's own quotas&lt;/a&gt; for the number of API calls, data sent, recipients messaged and invitations sent, and - &lt;strong&gt;none of these quotas are marked as billable&lt;/strong&gt;. Therefore, using the recipe for supercharging your free quota will also get you a significant boost in your XMPP quotas (657k -&amp;gt; 46000k API calls, 657k -&amp;gt; 46000k recipients messaged and 1k -&amp;gt; 100k invitations sent). Pretty cool!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;EDIT (Nov 2 2009):&lt;/strong&gt;&lt;/em&gt; I just noticed that it is &lt;strong&gt;possible to increase the limit on the number of apps each AppEngine user can create&lt;/strong&gt;. Currently, each user may create up to 10 AppEngine apps and there was no way to create more when you reached the limit, even by paying (or was there?). However, Google engineers have been approving explicit user requests for increases in the number of apps created &lt;a href=&quot;http://groups.google.com/group/google-appengine/browse_thread/thread/210ebae3dc88cc6a?hl=en&quot;&gt;on the official AppEngine group&lt;/a&gt;. People who have requested an increase have had the limit set to 20 apps.&lt;/p&gt;

&lt;p&gt;Are there any other hacks for squeezing more out of AppEngine?  &lt;a href=&quot;http://twitter.com/izuzak&quot; target=&quot;_blank&quot;&gt;@izuzak&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Named arguments in JavaScript</title>
   <link href="http://ivanzuzak.info/2009/08/09/named-arguments-in-javascript.html"/>
   <updated>2009-08-09T00:00:00-07:00</updated>
   <id>http://ivanzuzak.info/2009/08/09/named-arguments-in-javascript</id>
   <content type="html">&lt;p&gt;While working on another project (&lt;a title=&quot;pmrpc&quot; href=&quot;http://code.google.com/p/pmrpc&quot; target=&quot;_blank&quot;&gt;pmrpc&lt;/a&gt;, which I will write about soon), the implementation of a feature came down to calling JavaScript functions with &lt;a href=&quot;http://en.wikipedia.org/wiki/Named_parameter&quot; target=&quot;_blank&quot;&gt;named arguments&lt;/a&gt;. Unfortunately, the JavaScript language (or EcmaScript to be exact) &lt;a href=&quot;http://ajaxian.com/archives/chrome-extension-api-how-we-wish-we-have-named-parameters&quot;&gt;doesn't support named arguments&lt;/a&gt;, rather only positional arguments.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.javascriptkit.com/javatutors/namedfunction.shtml&quot; target=&quot;_blank&quot;&gt;Usually&lt;/a&gt;, JavaScript developers get around this by defining functions to accept a single object argument which acts like a container for all other named parameters:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// params is a container for other named parameters&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callMe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;param1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;param1&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;param2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;param2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;param3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;param3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// do something...&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callMe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;param3&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;param1&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;param2&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This solution works nicely when you are in the position to modify every function to be called this way. However, this is not always the case (e.g. when using external libraries), and also isn't as readable as having a proper parameter list, and introduces code overhead in every function that implements this principle. What I needed for my project is something that enables calling any JavaScript function with named arguments, without modifying the function itself.&lt;/p&gt;

&lt;p&gt;What I came up with (code presented below) is based on the following:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;using the &lt;em&gt;toString &lt;/em&gt;method of the Function prototype, it is possible to retrieve a string representation of any function definition&lt;/li&gt;
    &lt;li&gt;from the string representation, it is possible to parse the number, order and names of function parameters&lt;/li&gt;
    &lt;li&gt;from a dictionary of named arguments, it is possible to construct an array of arguments in the correct order using the parsed representation&lt;/li&gt;
    &lt;li&gt;using the &lt;em&gt;apply &lt;/em&gt;method of the Function prototype, it is possible to dynamically call a function, passing an array of arguments instead of an argument list.&lt;/li&gt;
&lt;/ol&gt;




&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;lineno&quot;&gt; 1&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// calls function fn with context self and parameters defined in dictionary&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 2&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// namedParams&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 3&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callWithNamedArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namedParams&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 4&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// get string representation of function&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 5&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fnDef&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 6&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt; 7&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// parse the string representation and retrieve order of parameters&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 8&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;argNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fnDef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fnDef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;(&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fnDef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;)&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt; 9&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;argNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;argNames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;argNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;, &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;10&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;argIndexes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;11&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;argNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;12&lt;/span&gt;     &lt;span class=&quot;nx&quot;&gt;argIndexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;argNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;13&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;14&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;15&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// construct an array of arguments from a dictionary&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;16&lt;/span&gt;   &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callParameters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;17&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;paramName&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namedParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;18&lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;argIndexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;paramName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;19&lt;/span&gt;       &lt;span class=&quot;nx&quot;&gt;callParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;argIndexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;paramName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;namedParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;paramName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;20&lt;/span&gt;     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;21&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;22&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;23&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// invoke function with specified context and arguments array&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;24&lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;26&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// example function&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callMe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;param1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;param2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;param3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;29&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// do something ...&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;31&lt;/span&gt; 
&lt;span class=&quot;lineno&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// example invocation with named parameters&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callWithNamedArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;34&lt;/span&gt;                &lt;span class=&quot;nx&quot;&gt;callMe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;param3&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;param1&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;param2&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This could also have been implemented as a Function prototype method and be called directly on a function object, which would simplify usage since the target function parameter wouldn't have to be passed. But, if the &lt;em&gt;CallWithNamedArgs&lt;/em&gt; function indeed was implemented prototype function, could the context parameter be removed also? I.e. is it possible to retrieve the current execution context (&lt;em&gt;this &lt;/em&gt;object) of the target function within the &lt;em&gt;CallWithNamedArgs &lt;/em&gt;method? The problem is that the execution context within the &lt;em&gt;CallWithNamedArgs method &lt;/em&gt;is the Function object on which the &lt;em&gt;CallWithNamedArgs &lt;/em&gt;method was called. But what we need is the execution context of the target function, which is the Function object on which the &lt;em&gt;CallWithNamedArgs &lt;/em&gt;method was called. That is, what we need is the current execution context of the parent object. Any ideas? &lt;a href=&quot;http://twitter.com/izuzak&quot;&gt;@izuzak&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
