<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Here comes the Sun</title>
	<atom:link href="http://sunng.info/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://sunng.info/blog</link>
	<description>Homemade Clojure Geek</description>
	<lastBuildDate>Fri, 11 May 2012 02:24:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>加入了美味书签</title>
		<link>http://sunng.info/blog/2012/05/%e5%8a%a0%e5%85%a5%e4%ba%86%e7%be%8e%e5%91%b3%e4%b9%a6%e7%ad%be/</link>
		<comments>http://sunng.info/blog/2012/05/%e5%8a%a0%e5%85%a5%e4%ba%86%e7%be%8e%e5%91%b3%e4%b9%a6%e7%ad%be/#comments</comments>
		<pubDate>Fri, 11 May 2012 02:24:46 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[自话]]></category>
		<category><![CDATA[Beijing]]></category>
		<category><![CDATA[meifm]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1232</guid>
		<description><![CDATA[距离上次更新已经有大半个月的时间了，最近一直忙着搬家和适应新环境。现在我又跑到北京来工作，好在这次终于不是在上地。我记得在写工作第三年的愿望的时候，有一条就是能加入一个优秀的小团队。那么目前看来一切顺利，美味书签这样的团队就是我一直希望能找到的。 我们的团队是Youtube创始人陈士骏的AVOS公司中国分支，中国团队由江宏带领，目前有20人，包括技术（前端、后端、移动），编辑等等。我们的团队网站上一一介绍了每个成员，我就不重复了。 在工作上，眼下最好的事情，是我终于可以利用自己喜爱和擅长的技术，来主导一些系统的开发。我们会尽可能地用热爱的语言（毫无疑问是clojure）开发，这想起来就让人兴奋。我这个人对技术还是有一些洁癖和偏执的。这样虽然路漫漫坑无数，但是收获一定不小，过程也在把握中，青春岁月不可再蹉跎了。 最后欢迎大家都来用我们的产品。]]></description>
			<content:encoded><![CDATA[<p>距离上次更新已经有大半个月的时间了，最近一直忙着搬家和适应新环境。现在我又跑到北京来工作，好在这次终于不是在上地。我记得在写工作第三年的愿望的时候，有一条就是能加入一个优秀的小团队。那么目前看来一切顺利，美味书签这样的团队就是我一直希望能找到的。</p>
<p>我们的团队是Youtube创始人陈士骏的<a href="http://avos.com" target="_blank">AVOS公司</a>中国分支，中国团队由江宏带领，目前有20人，包括技术（前端、后端、移动），编辑等等。我们的团队网站上一一介绍了每个成员，我就不重复了。</p>
<p>在工作上，眼下最好的事情，是我终于可以利用自己喜爱和擅长的技术，来主导一些系统的开发。我们会尽可能地用热爱的语言（毫无疑问是clojure）开发，这想起来就让人兴奋。我这个人对技术还是有一些洁癖和偏执的。这样虽然路漫漫坑无数，但是收获一定不小，过程也在把握中，青春岁月不可再蹉跎了。</p>
<p>最后欢迎大家都来用<a href="http://mei.fm" target="_blank">我们的产品</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/05/%e5%8a%a0%e5%85%a5%e4%ba%86%e7%be%8e%e5%91%b3%e4%b9%a6%e7%ad%be/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Slacker 0.8.0</title>
		<link>http://sunng.info/blog/2012/04/slacker-0-8-0/</link>
		<comments>http://sunng.info/blog/2012/04/slacker-0-8-0/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 06:05:01 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[slacker]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1227</guid>
		<description><![CDATA[A new release 0.8.0 of slacker has been pushed to clojars. Let&#8217;s go through the changes in this version. Clojure 1.3 compatible Slacker finally landed on clojure 1.3. It takes advantages of performance in 1.3. Also, you can use 1.3 &#8230; <a href="http://sunng.info/blog/2012/04/slacker-0-8-0/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A new release 0.8.0 of <a href="https://github.com/sunng87/slacker">slacker</a> has been pushed to clojars. Let&#8217;s go through the changes in this version.</p>
<h3>Clojure 1.3 compatible</h3>
<p>Slacker finally landed on clojure 1.3. It takes advantages of performance in 1.3. Also, you can use 1.3 API in slacker. For example, a timeout argument is supported in deref, which is useful when dealing with promise returned by slacker&#8217;s asynchronous call.</p>
<h3>Performance Boost</h3>
<p>The performance enhancement is on the highest priority in this release.  I have migrated the NIO infrastructure to a new library called <a href="https://github.com/sunng87/link">link</a>. Now slacker 0.8.0 is at least <strong>8x</strong> faster than previous release. There is significant improvement both on per-request latency and overall throughput. And the server thread model is optimized for data-intensive tasks. Heavy IO tasks in hosted functions won&#8217;t block the whole server. </p>
<h3>slacker as a ring app</h3>
<p>Instead of running default transportation, slacker now can be configured as a ring app and deployed on any ring adapter.</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>use 'slacker<span style="color: #66cc66;">.</span>server<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>use 'ring<span style="color: #66cc66;">.</span>adapter<span style="color: #66cc66;">.</span>jetty<span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span>run<span style="color: #66cc66;">-</span>jetty <span style="color: #66cc66;">&#40;</span>slacker<span style="color: #66cc66;">-</span>ring<span style="color: #66cc66;">-</span>app <span style="color: #66cc66;">&#40;</span>the<span style="color: #66cc66;">-</span><span style="color: #b1b100;">ns</span> 'slacker<span style="color: #66cc66;">.</span>example<span style="color: #66cc66;">.</span>api<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>:<span style="color: #555;">port</span> <span style="color: #cc66cc;">8080</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>This will expose the name space <em>slacker.example.api</em> with HTTP. Functions could be called with following URL pattern:</p>
<p>http://localhost:8080/&lt;namespace&gt;/&lt;function&gt;.&lt;content-type&gt;</p>
<p>For instance: http://localhost:8080/slacker.example.api/timestamp.json</p>
<h3>defn-remote</h3>
<p>There is a minor update for the defn-remote macro. </p>
<p>In 0.7.0, you have to specify remote namespace with an option:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>defn<span style="color: #66cc66;">-</span>remote sc timestamp :<span style="color: #555;">remote</span><span style="color: #66cc66;">-</span><span style="color: #b1b100;">ns</span> <span style="color: #ff0000;">&quot;slacker.example.api&quot;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>In 0.8.0, it&#8217;s more convenience:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>defn<span style="color: #66cc66;">-</span>remote sc slacker<span style="color: #66cc66;">.</span>example<span style="color: #66cc66;">.</span>api<span style="color: #66cc66;">/</span>timestamp<span style="color: #66cc66;">&#41;</span></div></div>
<p>To keep the core library compact, in 0.8.0, the cluster support has been moved to a standalone project <a href="https://github.com/sunng87/slacker-cluster">slacker-cluster</a>. </p>
<p>All above summarized my recent work in the slacker project. If you have any question with this library, feel free to drop me an email sunng@about.me .</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/04/slacker-0-8-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Visualizing OpenStreetMap Nanjing Contribution</title>
		<link>http://sunng.info/blog/2012/04/visualizing-openstreetmap-nanjing-contribution/</link>
		<comments>http://sunng.info/blog/2012/04/visualizing-openstreetmap-nanjing-contribution/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 07:02:40 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[把戏]]></category>
		<category><![CDATA[Nanjing]]></category>
		<category><![CDATA[OpenStreetMap]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1221</guid>
		<description><![CDATA[早上在prismatic上看到mapbox的一篇博客，介绍通过TileMill可视化OSM的贡献者，非常酷。于是我在南京的地图上也做了一个这样的可视化。 一个详细的大图在这里。虽然只做了南京的五个主要贡献者，基本上涵盖了大部分数据。 图例就不专门输出了 [user = 'Sunng'] { marker-fill: @magenta;} [user = 'fuwuyuan'] { marker-fill: @blue;} [user = 'sinopitt'] {marker-fill: @yellow;} [user = 'larryy'] {marker-fill: @green;} [user = 'zhengz'] {marker-fill: @red;} MapBox家的东西真的非常酷，这家的技术以nodejs为主，围绕osm开发了不少产品。最近比较大的新闻，比如4sq转到osm上，其实就是转到这家的osm服务上。有兴趣你可以关注一下！]]></description>
			<content:encoded><![CDATA[<p>早上在prismatic上看到mapbox的一篇<a href="http://mapbox.com/blog/how-to-map-contributions-openstreetmap/" target="_blank">博客</a>，介绍通过TileMill可视化OSM的贡献者，非常酷。于是我在南京的地图上也做了一个这样的可视化。</p>
<p><img src="http://i.imgur.com/U2yXK.png" alt="" /></p>
<p>一个详细的大图在<a href="http://i.imgur.com/YnULm.png" target="_blank">这里</a>。虽然只做了南京的五个主要贡献者，基本上涵盖了大部分数据。</p>
<p>图例就不专门输出了<br />
[user = 'Sunng'] { marker-fill: @magenta;}<br />
[user = 'fuwuyuan'] { marker-fill: @blue;}<br />
[user = 'sinopitt'] {marker-fill: @yellow;}<br />
[user = 'larryy'] {marker-fill: @green;}<br />
[user = 'zhengz'] {marker-fill: @red;}</p>
<p>MapBox家的东西真的非常酷，这家的技术以nodejs为主，围绕osm开发了不少产品。最近比较大的新闻，比如4sq转到osm上，其实就是转到这家的osm服务上。有兴趣你可以关注一下！<br />
<img src="http://i.imgur.com/Hum2r.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/04/visualizing-openstreetmap-nanjing-contribution/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>多线程服务器</title>
		<link>http://sunng.info/blog/2012/04/%e5%a4%9a%e7%ba%bf%e7%a8%8b%e6%9c%8d%e5%8a%a1%e5%99%a8/</link>
		<comments>http://sunng.info/blog/2012/04/%e5%a4%9a%e7%ba%bf%e7%a8%8b%e6%9c%8d%e5%8a%a1%e5%99%a8/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 15:52:15 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[手艺]]></category>
		<category><![CDATA[NIO]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1219</guid>
		<description><![CDATA[写了挺长时间网络程序了，有些事到最近才弄明白，记录一下。 写一个高性能的服务器，传统的BIO方式基本上已经被淘汰了，很难获得理想的性能。所以现在都是以事件驱动的方式来写，在Linux上用epoll,Java平台上就是NIO。再向上，有一些包装的库，比如twisted比如libevent比如Java上的Netty。 Netty的server需要至少两组线程，BossPool和WorkerPool,。前者负责accept，后者负责r/w。通常的例子里，这就是仅有的两组线程。用户在框架之上的业务逻辑，写在handler里，以单线程的方式运行在worker线程上。 这样的方式在很多例子里很普遍。但是如果handler里的业务逻辑比较复杂，尤其是IO的等待过长(比如查询数据库)，就会由于在handler上阻塞的时间过长，导致服务器读写的效率下降。所以通常是不能在这样环境下的handler里写IO阻塞的代码。 解决这个问题，一种方式是多线程，一种是全异步化。后者最典型的例子就是nodejs，坦白说编程模型非常复杂，对开发者要求较高。一种相对简单的办法，就是以多线程的方式，增加CPU的利用效率，来平衡IO阻塞带来的影响。IO等待时间的比重越大，线程数就可以陪得越高。牺牲一些sy的CPU时间，换取更高的利用率。 但是随之而来了另一个问题，因为在handler中使用了多线程的模型。对顺序收到的包，交由不同的线程并行处理，就没有办法保证返回时的顺序。客户端就无法了解刚刚返回的包是对应哪个请求的。 这个情况也有两种办法处理。其一是在线程管理上做文章，采用一种折中的办法。对于每一个客户端连接来说，仍然是占用同一个线程来处理。这样首先任务不会占用worker线程，其次在整体上仍然提高了CPU的利用率。但是这样做的缺点是，在单一客户端看来，任务仍然是串行执行: 三个需要耗时500ms的请求同时顺序发出，第三个至少要在1500ms之后才能收到响应，客户端的latency比较高。 另一种，就是在应用协议层面做一个冗余字段，通常叫做serial id或者transaction id。客户端为每一个请求生成一个这样的id，并存储这个id对应的回调。服务器端不需要对包的顺序作任何关注，只需要把这个id原封不动地拷贝回去即可。这样，服务器就可以自由调度线程来处理请求。以上面的例子，在不繁忙的情况下，三个响应在500ms左右就都可以到达了。 这种方式对应用协议有特殊的要求，但是比较常见的协议都预留了这个字段，Diameter协议甚至留了两个这样的字段来便于代理的实现。 slacker 0.7.x基于aleph，由于aleph / lamina无法侵入协议层面，所以采用的都是顺序的客户端和服务器。这种方式编程非常简洁，协议设计简单，实现起来很快。但是作为RPC框架，一旦客户的函数阻塞较长，就会影响整体性能。0.8.0开始，通过新的协议和link库支持，slacker采用了transaction id的方式，服务器端默认使用并行处理，客户端不再依赖顺序指定响应和回调。尽管在一些CPU为局限的测试里性能有少许下降(与单线程相比，增加了调度的成本)，但是针对实际应用里IO等待较多的情况，新版本应该会表现出更好的综合性能。 以上这些，就是最近的心得，希望能解释清楚事件驱动服务器里的这些事情。]]></description>
			<content:encoded><![CDATA[<p>写了挺长时间网络程序了，有些事到最近才弄明白，记录一下。</p>
<p>写一个高性能的服务器，传统的BIO方式基本上已经被淘汰了，很难获得理想的性能。所以现在都是以事件驱动的方式来写，在Linux上用epoll,Java平台上就是NIO。再向上，有一些包装的库，比如twisted比如libevent比如Java上的Netty。</p>
<p>Netty的server需要至少两组线程，BossPool和WorkerPool,。前者负责accept，后者负责r/w。通常的例子里，这就是仅有的两组线程。用户在框架之上的业务逻辑，写在handler里，以单线程的方式运行在worker线程上。</p>
<p>这样的方式在很多例子里很普遍。但是如果handler里的业务逻辑比较复杂，尤其是IO的等待过长(比如查询数据库)，就会由于在handler上阻塞的时间过长，导致服务器读写的效率下降。所以通常是不能在这样环境下的handler里写IO阻塞的代码。</p>
<p>解决这个问题，一种方式是多线程，一种是全异步化。后者最典型的例子就是nodejs，坦白说编程模型非常复杂，对开发者要求较高。一种相对简单的办法，就是以多线程的方式，增加CPU的利用效率，来平衡IO阻塞带来的影响。IO等待时间的比重越大，线程数就可以陪得越高。牺牲一些sy的CPU时间，换取更高的利用率。</p>
<p>但是随之而来了另一个问题，因为在handler中使用了多线程的模型。对顺序收到的包，交由不同的线程并行处理，就没有办法保证返回时的顺序。客户端就无法了解刚刚返回的包是对应哪个请求的。</p>
<p>这个情况也有两种办法处理。其一是在线程管理上做文章，采用一种折中的办法。对于每一个客户端连接来说，仍然是占用同一个线程来处理。这样首先任务不会占用worker线程，其次在整体上仍然提高了CPU的利用率。但是这样做的缺点是，在单一客户端看来，任务仍然是串行执行: 三个需要耗时500ms的请求同时顺序发出，第三个至少要在1500ms之后才能收到响应，客户端的latency比较高。</p>
<p>另一种，就是在应用协议层面做一个冗余字段，通常叫做serial id或者transaction id。客户端为每一个请求生成一个这样的id，并存储这个id对应的回调。服务器端不需要对包的顺序作任何关注，只需要把这个id原封不动地拷贝回去即可。这样，服务器就可以自由调度线程来处理请求。以上面的例子，在不繁忙的情况下，三个响应在500ms左右就都可以到达了。</p>
<p>这种方式对应用协议有特殊的要求，但是比较常见的协议都预留了这个字段，Diameter协议甚至留了两个这样的字段来便于代理的实现。</p>
<p>slacker 0.7.x基于aleph，由于aleph / lamina无法侵入协议层面，所以采用的都是顺序的客户端和服务器。这种方式编程非常简洁，协议设计简单，实现起来很快。但是作为RPC框架，一旦客户的函数阻塞较长，就会影响整体性能。0.8.0开始，通过新的协议和link库支持，slacker采用了transaction id的方式，服务器端默认使用并行处理，客户端不再依赖顺序指定响应和回调。尽管在一些CPU为局限的测试里性能有少许下降(与单线程相比，增加了调度的成本)，但是针对实际应用里IO等待较多的情况，新版本应该会表现出更好的综合性能。</p>
<p>以上这些，就是最近的心得，希望能解释清楚事件驱动服务器里的这些事情。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/04/%e5%a4%9a%e7%ba%bf%e7%a8%8b%e6%9c%8d%e5%8a%a1%e5%99%a8/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Slacker performance enhanced</title>
		<link>http://sunng.info/blog/2012/04/slacker-performance-enhanced/</link>
		<comments>http://sunng.info/blog/2012/04/slacker-performance-enhanced/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 07:04:21 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[手艺]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[netty]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[slacker]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1216</guid>
		<description><![CDATA[In the slacker framework, performance issue becomes more and more critical as the basic features are almost completed. As mentioned in cnclojure meetup, I will focus on the performance enhancement in next release. Now I have worked out a testable &#8230; <a href="http://sunng.info/blog/2012/04/slacker-performance-enhanced/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In the slacker framework, performance issue becomes more and more critical as the basic features are almost completed. As mentioned in cnclojure meetup, I will focus on the performance enhancement in next release. </p>
<p>Now I have worked out a testable version. The new slacker core has been moved to a new NIO library, <a href="https://github.com/sunng87/link" target="_blank">link</a>. Compared with aleph, link is a thin wrapper of Netty. It takes some nice features from aleph (gloss codec dsl, elegant API), and drops the heavy abstraction, lamina. The new slacker client runs on a real nonblocking connection. Connection pooling is no longer needed.</p>
<p>I have some performance benchmark to visualize the improvement. The test was made on my laptop (Intel(R) Core(TM)2 Duo CPU     T5870  @ 2.00GHz). It ran 400,000 calls with 40 threads on a local slacker server.</p>
<p>slacker 0.7.0 (clojure 1.2, aleph 0.2.0): <strong>614005.059259msecs</strong><br />
slacker 0.7.1-SNAPSHOT (clojure 1.3, aleph 0.2.1-beta2): <strong>409110.909142msecs</strong><br />
slacker 0.8.0-SNAPSHOT (clojure 1.3, link 0.2.0-SNAPSHOT): <strong>42468.401522msecs</strong></p>
<p><img src="http://i.imgur.com/gMtdo.jpg" alt="tps chart" /></p>
<p>Check out the new slacker on the <a href="https://github.com/sunng87/slacker/tree/0.8-dev" target="_blank">0.8-dev</a> branch. </p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/04/slacker-performance-enhanced/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>为WebWorker设置正确的路径</title>
		<link>http://sunng.info/blog/2012/03/%e4%b8%bawebworker%e8%ae%be%e7%bd%ae%e6%ad%a3%e7%a1%ae%e7%9a%84%e8%b7%af%e5%be%84/</link>
		<comments>http://sunng.info/blog/2012/03/%e4%b8%bawebworker%e8%ae%be%e7%bd%ae%e6%ad%a3%e7%a1%ae%e7%9a%84%e8%b7%af%e5%be%84/#comments</comments>
		<pubDate>Thu, 22 Mar 2012 09:32:32 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[把戏]]></category>
		<category><![CDATA[heatcanvas]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1208</guid>
		<description><![CDATA[WebWorker的路径通常是写在代码源文件中，而且这个路径并非其相对父js文件的相对路径，而似乎是相对页面的路径。所以指定一个正确的可随处部署的路径变得有些麻烦。昨天有人给HeatCanvas提了这个问题我才想到上网搜索了一下，有一个还算挺不错的办法。 写一个getPath函数，从document里找到父js的路径，拼到Worker的名字上。对heatcanvas.js这个文件来说就是： HeatCanvas.getPath = function&#40;&#41; &#123; &#160; &#160; var scriptTags = document.getElementsByTagName&#40;&#34;script&#34;&#41;; &#160; &#160; for &#40;var i=0; i&#60;scriptTags.length; i++&#41; &#123; &#160; &#160; &#160; &#160; var src = scriptTags&#91;i&#93;.src; &#160; &#160; &#160; &#160; var pos = src.indexOf&#40;&#34;heatcanvas.js&#34;&#41;; &#160; &#160; &#160; &#160; &#8230; <a href="http://sunng.info/blog/2012/03/%e4%b8%bawebworker%e8%ae%be%e7%bd%ae%e6%ad%a3%e7%a1%ae%e7%9a%84%e8%b7%af%e5%be%84/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>WebWorker的路径通常是写在代码源文件中，而且这个路径并非其相对父js文件的相对路径，而似乎是相对页面的路径。所以指定一个正确的可随处部署的路径变得有些麻烦。昨天有人给HeatCanvas提了这个问题我才想到上网搜索了一下，有一个还算挺不错的办法。</p>
<p>写一个getPath函数，从document里找到父js的路径，拼到Worker的名字上。对heatcanvas.js这个文件来说就是：</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">HeatCanvas.<span style="color: #660066;">getPath</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> scriptTags <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;script&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>scriptTags.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> src <span style="color: #339933;">=</span> scriptTags<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">src</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> pos <span style="color: #339933;">=</span> src.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;heatcanvas.js&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>pos <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> src.<span style="color: #660066;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> pos<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></div>
<p>因此现在HeatCanvas已经解决了这个路径问题，现在这个库应该更好用了。当然如果你改了我的文件名我就无话可说了。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/03/%e4%b8%bawebworker%e8%ae%be%e7%bd%ae%e6%ad%a3%e7%a1%ae%e7%9a%84%e8%b7%af%e5%be%84/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My favorite feature in leiningen 2</title>
		<link>http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/</link>
		<comments>http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 06:58:07 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[leiningen]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1202</guid>
		<description><![CDATA[Recently, the leiningen team has released a preview version for leiningen 2. It brings new features to the clojure build tool. But my favorite one is not listed in any document. So I would like to share with you here. &#8230; <a href="http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently, the leiningen team has released a preview version for leiningen 2. It brings <a href="https://github.com/technomancy/leiningen/blob/master/NEWS.md" target="_blank">new features</a> to the clojure build tool. But my favorite one is not listed in any document. So I would like to share with you here.</p>
<p>As you know, leiningen is a project oriented tool. It manages dependencies for a particular project. In Java world, Maven and Gradle are also working in this manner. </p>
<p>In contrast, there are tools which manages dependencies in a system scope. For instance, pip(python), npm(nodejs) and gems(ruby). One advantage of these tools is easy for evaluating a library. Concretely, when you want to test pyclj, just run &#8220;pip install pyclj&#8221; to install it. Then open a REPL and type &#8220;import pyclj&#8221;. That&#8217;s pretty easy.</p>
<p>But in clojure/leiningen, to take a tutorial of &#8220;core.logic&#8221;, we have following steps: </p>
<ol>
<li>Find a right directory and type &#8220;lein new logic-abc&#8221; to create a project. </li>
<li>cd into it, edit project.clj, add core.logic as a dependency</li>
<li>Run `lein deps`</li>
<li>Start a REPL and follow the tutorial</li>
</ol>
<p>So I guest you must have a lot of empty projects created for such purpose. </p>
<p>Now we could say goodbye to this situation. Leiningen 2 has move its dependency management core to a new library, called <a href="https://github.com/cemerick/pomegranate" target="_blank">pomegranate</a>. Pomegranate wraps aether, which is a maven library created by sonatype. With pomegranate, we can add a maven artifact from repository to REPL classpath. Still on the core.logic example, it becomes much easier:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ lein2 repl<br />
Welcome to REPL<span style="color: #66cc66;">-</span>y<span style="color: #66cc66;">!</span><br />
Clojure 1<span style="color: #66cc66;">.</span>3<span style="color: #66cc66;">.</span>0<br />
&nbsp; &nbsp; Exit: <span style="color: #555;">Control</span><span style="color: #66cc66;">+</span>D <span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>exit<span style="color: #66cc66;">&#41;</span> <span style="color: #b1b100;">or</span> <span style="color: #66cc66;">&#40;</span>quit<span style="color: #66cc66;">&#41;</span><br />
Commands: <span style="color: #66cc66;">&#40;</span>help<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; Docs: <span style="color: #66cc66;">&#40;</span>doc function<span style="color: #66cc66;">-</span>name<span style="color: #66cc66;">-</span>here<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>find<span style="color: #66cc66;">-</span>doc <span style="color: #ff0000;">&quot;part-of-name-here&quot;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; Source: <span style="color: #66cc66;">&#40;</span>source function<span style="color: #66cc66;">-</span>name<span style="color: #66cc66;">-</span>here<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>sourcery function<span style="color: #66cc66;">-</span>name<span style="color: #66cc66;">-</span>here<span style="color: #66cc66;">&#41;</span><br />
&nbsp;Javadoc: <span style="color: #66cc66;">&#40;</span>javadoc java<span style="color: #66cc66;">-</span>object<span style="color: #66cc66;">-</span>or<span style="color: #66cc66;">-</span>class<span style="color: #66cc66;">-</span>here<span style="color: #66cc66;">&#41;</span><br />
Examples from clojuredocs<span style="color: #66cc66;">.</span>org:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>clojuredocs name<span style="color: #66cc66;">-</span>here<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span>clojuredocs <span style="color: #ff0000;">&quot;ns-here&quot;</span> <span style="color: #ff0000;">&quot;name-here&quot;</span><span style="color: #66cc66;">&#41;</span><br />
nil<br />
user<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>use '<span style="color: #66cc66;">&#91;</span>cemerick<span style="color: #66cc66;">.</span>pomegranate :<span style="color: #555;">only</span> <span style="color: #66cc66;">&#40;</span>add<span style="color: #66cc66;">-</span>dependencies<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
nil<br />
user<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>add<span style="color: #66cc66;">-</span>dependencies :<span style="color: #555;">coordinates</span> '<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>org<span style="color: #66cc66;">.</span>clojure<span style="color: #66cc66;">/</span>core<span style="color: #66cc66;">.</span>logic <span style="color: #ff0000;">&quot;0.6.8&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#91;</span>org<span style="color: #66cc66;">.</span>clojure<span style="color: #66cc66;">/</span>clojure <span style="color: #ff0000;">&quot;1.3.0&quot;</span><span style="color: #66cc66;">&#93;</span> nil, <span style="color: #66cc66;">&#91;</span>org<span style="color: #66cc66;">.</span>clojure<span style="color: #66cc66;">/</span>core<span style="color: #66cc66;">.</span>logic <span style="color: #ff0000;">&quot;0.6.8&quot;</span><span style="color: #66cc66;">&#93;</span> #<span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#91;</span>org<span style="color: #66cc66;">.</span>clojure<span style="color: #66cc66;">/</span>clojure <span style="color: #ff0000;">&quot;1.3.0&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span><br />
user<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>use &nbsp;'<span style="color: #66cc66;">&#91;</span>clojure<span style="color: #66cc66;">.</span>core<span style="color: #66cc66;">.</span>logic<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
nilWARNING: <span style="color: #66cc66;">==</span> already refers to: #'clojure<span style="color: #66cc66;">.</span>core<span style="color: #66cc66;">/==</span> in namespace: <span style="color: #555;">user</span>, being replaced by: #'clojure<span style="color: #66cc66;">.</span>core<span style="color: #66cc66;">.</span>logic<span style="color: #66cc66;">/==</span><br />
user<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span>run<span style="color: #66cc66;">*</span> <span style="color: #66cc66;">&#91;</span>q<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">==</span> q <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Now core.logic is right on you classpath and you are ready to use any functions under the namespace. There&#8217;s no need to create project, no need to care about where the jars stored. Just start a REPL at anywhere you want. When you finished, send EOF to the REPL. Nothing to clean up.</p>
<p>My jython dependency manager <a href="https://github.com/sunng87/jip" target="_blank">jip</a> has <a href="http://sunng87.github.com/jip/#section-6" target="_blank">similar feature</a> as I described above. It does great help to me. So I have been waiting for this feature in leiningen for a long time. Thanks to leiningen guys, it finally comes.</p>
<p>Edit 20120323 21:39</p>
<p>If you want to load libraries from clojars, you should explicitly add clojars in add-dependencies:</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>add<span style="color: #66cc66;">-</span>dependencies :<span style="color: #555;">coordinates</span> '<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>incanter <span style="color: #ff0000;">&quot;1.2.3&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :<span style="color: #555;">repositories</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">merge</span> cemerick<span style="color: #66cc66;">.</span>pomegranate<span style="color: #66cc66;">.</span>aether<span style="color: #66cc66;">/</span>maven<span style="color: #66cc66;">-</span>central<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#123;</span><span style="color: #ff0000;">&quot;clojars&quot;</span> <span style="color: #ff0000;">&quot;http://clojars.org/repo&quot;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>(The example is copied from Pomegranate document.)</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/03/my-favorite-feature-in-leiningen-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>刷HTC EVO 3D GSM</title>
		<link>http://sunng.info/blog/2012/03/%e5%88%b7htc-evo-3d-gsm/</link>
		<comments>http://sunng.info/blog/2012/03/%e5%88%b7htc-evo-3d-gsm/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 13:39:01 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[装备]]></category>
		<category><![CDATA[android]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1200</guid>
		<description><![CDATA[去年买的水货Desire Z在服役了刚刚一年之后就坏了，看来肯定是上了奸商的当。鉴于最近的新手机也没有什么像当时Desire Z那样一见倾心的，这次保守起见买了个行货EVO 3D。买行货的问题不仅是贵（贵很多），而且默认的ROM实在是没法用。几大国产流氓软件堂而皇之地强制安装后台运行，系统连google账户，官方market都没有。 那么只能刷一下了。所有的步骤开始之前都是解锁，按照官方的解锁方式(http://www.htcdev.com)基本上没有什么难度。在我的archlinux上，不需要安装HTC Sync（也没得装），只需要从aur安装android-sdk和android-sdk-platform-tools就有adb和fastboot在PATH里。唯一值得一提的是，在我的系统上fastboot oem get_identifier_token需要sudo，否则会一直wait device。除了这个小插曲以外，按照官方的步骤就可以解锁HBOOT。 接下来就可以刷recovery了，HTC EVO 3D GSM版的codename叫做shootru，比较可靠的一个版本是4.0.1.4-shooteru，可以在网上搜索 cwm-4.0.1.4-shooteru.img 这个文件，比较好找。继续通过 sudo fastboot flash recovery cwm-4.0.1.4-shooteru.img把recovery刷进手机。 接下来就是ROM的选择了。最好的选择是cyanogenmod，EVO 3D分为GSM和CDMA版，cmod 7只支持CDMA版，似乎还没有稳定的正式版。对GSM似乎有正在开发7.2，不过按照他们的说法，自从4.0发布之后，所有人的注意力都转移到基于4.0的cmod9上，所以7.2这个版本希望也比较渺茫。9.0已经有开发版本，但是都有一些还未解决的严重bug。说了这么多就是说我暂时放弃cmod了。 除了cmod，EVO 3D GSM上一个比较被认可的ROM叫做LeeDrOiD.从网站上下载5.3.0的发布版，拷贝到sd卡上，通过recovery就可以安装。安装之前先要清除旧的数据。剩下这一步也没有什么悬念。但是安装之后5.3.0上，WIFI无法启动。必须继续更新kernel，从网站上下载。安装kernel的方法和之前不太一样，不能通过recovery安装。需要用一个叫做FlashImageGUI的工具，可以在网上直接搜索这个名字找到下载。剩下就很简单了。 折腾这么一圈，手机基本上能用了。不过我还是非常期待早日能用上cmod 9.]]></description>
			<content:encoded><![CDATA[<p>去年买的水货Desire Z在服役了刚刚一年之后就坏了，看来肯定是上了奸商的当。鉴于最近的新手机也没有什么像当时Desire Z那样一见倾心的，这次保守起见买了个行货EVO 3D。买行货的问题不仅是贵（贵很多），而且默认的ROM实在是没法用。几大国产流氓软件堂而皇之地强制安装后台运行，系统连google账户，官方market都没有。</p>
<p>那么只能刷一下了。所有的步骤开始之前都是解锁，按照官方的解锁方式(http://www.htcdev.com)基本上没有什么难度。在我的archlinux上，不需要安装HTC Sync（也没得装），只需要从aur安装android-sdk和android-sdk-platform-tools就有adb和fastboot在PATH里。唯一值得一提的是，在我的系统上fastboot oem get_identifier_token需要sudo，否则会一直wait device。除了这个小插曲以外，按照官方的步骤就可以解锁HBOOT。</p>
<p>接下来就可以刷recovery了，HTC EVO 3D GSM版的codename叫做shootru，比较可靠的一个版本是4.0.1.4-shooteru，可以在网上搜索 cwm-4.0.1.4-shooteru.img 这个文件，比较好找。继续通过 sudo fastboot flash recovery cwm-4.0.1.4-shooteru.img把recovery刷进手机。</p>
<p>接下来就是ROM的选择了。最好的选择是cyanogenmod，EVO 3D分为GSM和CDMA版，cmod 7只支持CDMA版，似乎还没有稳定的正式版。对GSM似乎有正在开发7.2，不过按照他们的说法，自从4.0发布之后，所有人的注意力都转移到基于4.0的cmod9上，所以7.2这个版本希望也比较渺茫。9.0已经有开发版本，但是都有一些还未解决的严重bug。说了这么多就是说我暂时放弃cmod了。</p>
<p>除了cmod，EVO 3D GSM上一个比较被认可的ROM叫做<a href="http://leedroid.com/evo-3d/?c=roms">LeeDrOiD</a>.从网站上下载5.3.0的发布版，拷贝到sd卡上，通过recovery就可以安装。安装之前先要清除旧的数据。剩下这一步也没有什么悬念。但是安装之后5.3.0上，WIFI无法启动。必须继续更新kernel，从<a href="http://leedroid.com/evo-3d/?c=kernels">网站上下</a>载。安装kernel的方法和之前不太一样，不能通过recovery安装。需要用一个叫做FlashImageGUI的工具，可以在网上直接搜索这个名字找到下载。剩下就很简单了。</p>
<p>折腾这么一圈，手机基本上能用了。不过我还是非常期待早日能用上cmod 9.</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/03/%e5%88%b7htc-evo-3d-gsm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kliment Voroshilov tank 2</title>
		<link>http://sunng.info/blog/2012/03/kliment-voroshilov-tank-2/</link>
		<comments>http://sunng.info/blog/2012/03/kliment-voroshilov-tank-2/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 07:39:19 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[自话]]></category>
		<category><![CDATA[D60]]></category>
		<category><![CDATA[tank]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1198</guid>
		<description><![CDATA[业余时间，我除了写括号以外，也会做点模型，不过是入门水平。用淘宝店家的话说，你随便涂涂就行了。这个KV-2坦克是去年秋天买的，后来周末学车加上天冷坐不住就搁置下来。现在稍微暖和一点，就赶紧把开工。 KV-2坦克，是二战时期苏联的重型坦克。最早参加了苏芬战争，后来投入到早期的苏德战争。但是绝大多数被德军在巴巴罗萨行动中摧毁、俘虏。被俘虏的KV-2坦克被刷上德军的标志也为德军服役，这在二战早期的东线战场倒是很常见。我的这个KV-2附带的水贴纸也分两个版本，分别是苏军和德军的涂装。 花了一天时间素组。 今天又花了一上午时间上漆。第一次上漆，也没看什么教程，就是这个结果了。 下一个目标就是T34。]]></description>
			<content:encoded><![CDATA[<p>业余时间，我除了写括号以外，也会做点模型，不过是入门水平。用淘宝店家的话说，你随便涂涂就行了。这个KV-2坦克是去年秋天买的，后来周末学车加上天冷坐不住就搁置下来。现在稍微暖和一点，就赶紧把开工。</p>
<p>KV-2坦克，是二战时期苏联的重型坦克。最早参加了苏芬战争，后来投入到早期的苏德战争。但是绝大多数被德军在巴巴罗萨行动中摧毁、俘虏。被俘虏的KV-2坦克被刷上德军的标志也为德军服役，这在二战早期的东线战场倒是很常见。我的这个KV-2附带的水贴纸也分两个版本，分别是苏军和德军的涂装。</p>
<p>花了一天时间素组。<br />
<a href="http://www.flickr.com/photos/40741608@N08/6825567316/" title="DSC_0016 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7043/6825567316_29e7e13830.jpg" width="500" height="335" alt="DSC_0016"></a></p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6825568984/" title="DSC_0013 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7041/6825568984_8e897f9513.jpg" width="335" height="500" alt="DSC_0013"></a></p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6971689967/" title="DSC_0023 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7180/6971689967_171ab05c49.jpg" width="335" height="500" alt="DSC_0023"></a></p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6825572612/" title="DSC_0019 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7176/6825572612_a4bdb17248.jpg" width="500" height="335" alt="DSC_0019"></a></p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6971692767/" title="DSC_0029 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7182/6971692767_c84b5aba61.jpg" width="500" height="335" alt="DSC_0029"></a></p>
<p>今天又花了一上午时间上漆。第一次上漆，也没看什么教程，就是这个结果了。</p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6971694113/" title="DSC_0003 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7057/6971694113_73c6939dc8.jpg" width="335" height="500" alt="DSC_0003"></a></p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6825576398/" title="DSC_0009 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7059/6825576398_e57bf106a2.jpg" width="500" height="335" alt="DSC_0009"></a></p>
<p><a href="http://www.flickr.com/photos/40741608@N08/6971697399/" title="DSC_0015 by 贝小塔, on Flickr"><img src="http://farm8.staticflickr.com/7045/6971697399_fd01ca6c69.jpg" width="335" height="500" alt="DSC_0015"></a></p>
<p>下一个目标就是T34。</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/03/kliment-voroshilov-tank-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What&#8217;s new in slacker 0.7.0 ?</title>
		<link>http://sunng.info/blog/2012/03/whats-new-in-slacker-0-7-0/</link>
		<comments>http://sunng.info/blog/2012/03/whats-new-in-slacker-0-7-0/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 13:48:36 +0000</pubDate>
		<dc:creator>sunng</dc:creator>
				<category><![CDATA[ANN]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[slacker]]></category>

		<guid isPermaLink="false">http://sunng.info/blog/?p=1195</guid>
		<description><![CDATA[I just released [slacker "0.7.0"] to clojars. This is the first release after my presentation on the Clojure China Meetup. lbt05 contributed an ACL module to slacker, which is the most significant feature in this release. The ACL module provides &#8230; <a href="http://sunng.info/blog/2012/03/whats-new-in-slacker-0-7-0/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just released [slacker "0.7.0"] to clojars. This is the first release after my presentation on the Clojure China Meetup. <a href="https://github.com/lbt05" target="_blank">lbt05</a> contributed an ACL module to slacker, which is the most significant feature in this release. </p>
<p>The ACL module provides a simple DSL to define access rules.</p>
<div class="codecolorer-container clojure twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="clojure codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #66cc66;">&#40;</span>use 'slacker<span style="color: #66cc66;">.</span>acl<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#40;</span>use 'slacker<span style="color: #66cc66;">.</span>server<span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span>defrules myrule<br />
&nbsp; <span style="color: #66cc66;">&#40;</span>allow <span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">&quot;10.60.15.*&quot;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #66cc66;">&#40;</span>start<span style="color: #66cc66;">-</span>slacker<span style="color: #66cc66;">-</span>server <span style="color: #66cc66;">...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :<span style="color: #555;">acl</span> myrule<span style="color: #66cc66;">&#41;</span></div></div>
<p>&#8220;myrule&#8221; defines a limited access control list. Only clients from IP segment 10.60.15.* could access the slacker service.</p>
<p>And there are also minor enhancements in this release:</p>
<ul>
<li>Content compression, new content type :deflate-carb :deflate-json and :deflate-clj</li>
<li>In debug mode, server side stacktraces are printed on client</li>
<li>Zookeeper node path refined</li>
<li>New options in use-remote, <img src='http://sunng.info/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly and :exclude</li>
<li>Cheshire used as json library</li>
</ul>
<p>slacker 0.7.0 will be the last version on clojure 1.2 . As aleph 0.2.1 is coming near, we will migrate to clojure 1.3 as soon as possible. If you like to taste slacker on your 1.3 application now, there is a 0.7.1-SNAPSHOT available.</p>
]]></content:encoded>
			<wfw:commentRss>http://sunng.info/blog/2012/03/whats-new-in-slacker-0-7-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

