<?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>reality &#187; cache</title>
	<atom:link href="http://www.reality.hk/articles/tag/cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.reality.hk</link>
	<description>Reality is merely an illusion, albeit a very persistent one.</description>
	<lastBuildDate>Sun, 05 Sep 2010 14:37:02 +0000</lastBuildDate>
	<language>zh-tw</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>在 Jboss Seam 中使用 PojoCache 和 Page Fragment Cache (2)</title>
		<link>http://www.reality.hk/articles/2008/02/03/776/</link>
		<comments>http://www.reality.hk/articles/2008/02/03/776/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 16:03:08 +0000</pubDate>
		<dc:creator>小影</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[seam]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.reality.hk/articles/2008/02/02/776/</guid>
		<description><![CDATA[直接在 component 中使用 PojoCache 讓我們可以在物件的層次控制緩存，雖然這可以很強大和靈活，但如果每個物件都要特別地作緩存，那業務的源碼就會充滿著緩存代碼，難以維護。這時候我們可以用 Page Fragment Cache。 (源碼 svn) 打開 view 的檔案 view/index.xhtml，加入 seam 的 &#60;s:cache&#62; tag。Seam 的 Page Fragment Cache 同樣是用 PojoCache 去實現，s:cache tag 中的 region 和 key 跟 PojoCache 中用法完全一樣。 同時在 SFSB 的 interface 和 implementation 加入方法 getMoreMessage()： public String getMoreMessage(){ log.info("retrieve moreMessage()"); return "Hello, again! (this message is component cached)"; } [...]]]></description>
			<content:encoded><![CDATA[<p>直接在 component 中使用 PojoCache 讓我們可以在物件的層次控制緩存，雖然這可以很強大和靈活，但如果每個物件都要特別地作緩存，那業務的源碼就會充滿著緩存代碼，難以維護。這時候我們可以用 Page Fragment Cache。</p>
<p><span id="more-776"></span></p>
<p>(<a href="http://svn.reality.hk/web/seam/cachetest/tags/03_fragment/">源碼 svn</a>)</p>
<p>打開 view 的檔案 view/index.xhtml，加入 seam 的 &lt;s:cache&gt; tag。Seam 的 Page Fragment Cache 同樣是用 PojoCache 去實現，s:cache tag 中的 region 和 key 跟 PojoCache 中用法完全一樣。</p>
<p><img src="http://farm3.static.flickr.com/2274/2236993638_d53aa554b4.jpg?v=0" alt="" /></p>
<p>同時在 SFSB 的 interface 和 implementation 加入方法 getMoreMessage()：</p>
<pre><code>
    public String getMoreMessage(){
        log.info("retrieve moreMessage()");
        return "Hello, again! (this message is component cached)";
    }
</code></pre>
<p>運行的效果如下：<br />
<img src="http://farm3.static.flickr.com/2287/2236690244_20e2943dd0.jpg?v=0" alt="" /></p>
<p>留意 console 的輸出：<br />
<img src="http://farm3.static.flickr.com/2390/2235901167_2d80484568.jpg?v=0" alt="" /></p>
<p>在第一次之顯示之後，gerMoreMessage() 方法就沒有再被呼叫過，這是由於整個被 s:cache 包圍的組件也被緩存了。</p>
<h2>手動移除過期物件</h2>
<p>要留意 PojoCache 並不像 Hibernate 的 second level cache，更改了的物件並不會自動把有關的 PojoCache 和 page fragment 自動 invalidate 掉。除了指定 Eviction Policy外，一些對更新敏感的資料需要用手動的方法移除。PojoCache 容許我們手動用 Region 和 Key 指定移除特定的緩存。</p>
<p>(<a href="http://svn.reality.hk/web/seam/cachetest/tags/04_remove_cache/">源碼 svn</a>)</p>
<pre><code>
    public String flush(){
        log.info("flush cache");
        try {
            pojoCache.remove("/message", "complexTask");
            pojoCache.remove("/message", "complexTask2");
        } catch (CacheException ex) {
            log.warn("Unexpected error while remove cache... #0 #1, error=#2", "complexTask", "complexTask2", ex.getMessage());
        }
		return "/index.xhtml";
    }
</code></pre>
<p>使用 flush() 方法後指定的兩個緩存就會被移除。</p>
<p>加入移除緩存按鍵的主頁：<br />
<img src="http://farm3.static.flickr.com/2354/2236704152_81ec2a5968.jpg?v=0" alt="" /></p>
<p>使用 flush() 後的 console ，是我們其待的結果：在 flush 後原本的 cache 不見了。<br />
<img src="http://farm3.static.flickr.com/2029/2235914753_f3ba814c2a.jpg?v=0" alt="" /></p>
<h2>回顧及後話</h2>
<p>這一篇中我們試驗了Seam 的以下功能：</p>
<ul>
<li>使用和設定 PojoCache 去緩存任何物件；</li>
<li>使用 Page Fragment Cache 去緩存頁面的組件；</li>
<li>手動移除過期的緩存</li>
</ul>
<p>有一些東西我是沒有討論的，例如這裡只有講最簡單的本地緩存，Transaction Manager 和不同 Isolation Level 在應用中的影響等等&#8230;這些應用就得等高人指教了。</p>
<p>在 Seam 中使用 PojoCache 並不困難，基本的 Seam 己包括所有需要的組件。然而，實際應用前我們必需要先設定它，這卻是異常神秘和讓人困惑的。在 Seam 的文件中有關緩存的課題我們只能找到這一句：<em><a href="http://docs.jboss.com/seam/2.0.1.CR1/reference/en/html/cache.html">JBossCache 有許多嚇人和讓人困惑的設定，我們不會在此討論。詳情請參考 JBossCache 的文件。</a></em>然而就算你讀完 <a href="http://labs.jboss.org/file-access/default/members/jbosscache/freezone/docs/2.0.0.GA/JBossCache-UserGuide/en/html_single/index.html">JBoss Cache User Guide</a> 也不可能讓你設定好 seam 中的 PojoCache，因為JBoss Cache 中的例子根本不能用在 seam 中。</p>
<p>在網路和 JBoss 的網站上可以找到大量過時的資料，究竟 JBossCache，TreeCache 和 PojoCache有何分別？究竟怎樣才能讓我的 Hello World Seam Application 可以使用到最簡單的緩存？最後我由討論區上<a href="http://www.techienuggets.com/Detail?tx=12973">一篇孤獨的文章</a>，加上 seam 的 blog example ， <a href="http://fisheye.jboss.org/browse/Seam/trunk">Seam 的源碼</a>以及 TreeCache 的文檔中才慢慢找出個頭緒來&#8230; 回頭己是花了兩天。</p>
<p>希望這篇記錄有助以後需要最簡單 Seam 緩存的人。</p>
<h3>延申閱讀</h3>
<p>請直接在我的 <a href="http://del.icio.us/siuying/cache+jboss?setcount=100">del.icio.us</a>看看。</p>
<p>P.S. 在 Rails 中要 page fragment cache 只要在 view 中加入兩句，不用設定甚麼 xml 啊&#8230;<br />
&lt;% cache do %&gt;<br />
<em>&#8230; content &#8230;</em><br />
&lt;% end %&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.reality.hk/articles/2008/02/03/776/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在 Jboss Seam 中使用 PojoCache 和 Page Fragment Cache (1)</title>
		<link>http://www.reality.hk/articles/2008/02/02/777/</link>
		<comments>http://www.reality.hk/articles/2008/02/02/777/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 14:41:10 +0000</pubDate>
		<dc:creator>小影</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[seam]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.reality.hk/articles/2008/02/02/777/</guid>
		<description><![CDATA[實際的 Web Application 中，緩存 (cache) 是不可或缺的事。 JBoss Seam 當然也提供了多種緩存服務。在這系列的文中我會講講最高層，最易應用和最易理解的 PojoCache 以及 Page Fragment Cache 。 基本的 Web App 在使用緩存之前，我們首先建立一個 Hello World 程式作為藍本 (源碼 svn)。 設定 Seam 的 Page Action 在 resources/WEB-INF/pages.xml 加入以下一句： &#60;page view-id=&#34;/index.xhtml&#34; action=&#34;#{complexWork.work}&#34; /&#62; 這會讓 seam 在顯示 index.xhtml 前先執行 complexWork.work method。 設定業務邏輯，這裡我們使用 Stateful Session Bean (SFSB)。 @Stateful 代表這是個 SFSB。@Name 指定了它在 seam 中的名字，我們以後可以用 complexWork [...]]]></description>
			<content:encoded><![CDATA[<p>實際的 Web Application 中，緩存 (cache) 是不可或缺的事。 JBoss Seam 當然也提供了多種緩存服務。在這系列的文中我會講講最高層，最易應用和最易理解的 PojoCache 以及 Page Fragment Cache 。</p>
<p><span id="more-777"></span></p>
<h2>基本的 Web App</h2>
<p>在使用緩存之前，我們首先建立一個 Hello World 程式作為藍本 (<a href="http://svn.reality.hk/web/seam/cachetest/tags/01_nocache/">源碼 svn</a>)。</p>
<ol>
<li>設定 Seam 的 Page Action<br />
在 resources/WEB-INF/pages.xml 加入以下一句：</p>
<p>&lt;page view-id=&quot;/index.xhtml&quot; action=&quot;#{complexWork.work}&quot; /&gt;</p>
<p>這會讓 seam 在顯示 index.xhtml 前先執行 complexWork.work method。
</li>
<li>設定業務邏輯，這裡我們使用 Stateful Session Bean (SFSB)。
<p>@Stateful 代表這是個 SFSB。@Name 指定了它在 seam 中的名字，我們以後可以用 complexWork 在 seam 中稱呼它。work() 是我們的主要業務邏輯 ，它會等待一秒以模擬一些繁重的工作，再把 message 設定為 &#8220;Hello, World&#8221;。@Out annotation 會讓 seam 知道我們想在頁面上看到 message。</p>
<h3>src/action/hk/reality/seam/cache/action/ComplexWork.java</h3>
<p><a href="http://www.flickr.com/photos/realityhk/2236065541/"><img src="http://farm3.static.flickr.com/2345/2236065541_5a0059f009.jpg?v=0" alt="" /></a></p>
<h3>src/action/hk/reality/seam/cache/action/ComplexWorkBean.java</h3>
<p><a href="http://www.flickr.com/photos/realityhk/2236859264/"><img src="http://farm3.static.flickr.com/2383/2236859264_7906407702.jpg?v=0" alt="" /></a></p>
</li>
<li>設定 view：
<p>沒有甚麼值得一談的，只是把 message 顯示出來： </p>
<h3>view/index.xhtml</h3>
<p><a href="http://www.flickr.com/photos/realityhk/2236028689/"><img src="http://farm3.static.flickr.com/2286/2236406969_3669e7c419.jpg?v=0" alt="view/index.xhtml" /></a>
</li>
<li>Deploy 後到 http://127.0.0.1:8080/cachetest/index.seam 可以看到結果：<br />
<img src="http://farm3.static.flickr.com/2180/2236639132_9ea7cdf1b3.jpg?v=0" alt="" /></p>
<p>留意 console ，每次 refresh 網頁 SFSB 也在重新工作：<br />
<img src="http://farm3.static.flickr.com/2019/2235849465_d7a24a9007.jpg?v=0" alt="" /></p>
<p>接著我們要為 SFSB 加入緩存 。
</li>
</ol>
<h2>使用 PojoCache</h2>
<p>PojoCache 是 seam 內置的 Java 物件緩存組件。PojoCache 支援 JTA transaction manager，isolation level，replication，overflowing， eviction policy 等功能，要完整設定並不簡單。但要讓它可以供 seam 應用則不難，首先要在 resources 下加入設定檔 treecache.xml 。(<a href="http://svn.reality.hk/web/seam/cachetest/tags/02_pojocache/">源碼 svn</a>)</p>
<p><a href="http://svn.reality.hk/web/seam/cachetest/trunk/resources/treecache.xml"><img src="http://farm3.static.flickr.com/2150/2236094047_e2b0aaa5fc.jpg?v=0" alt="" /></a></p>
<p>這個設定檔中值得留意的是 Eviction Policy 。 Eviction Policy 是指 PojoCache 移除 cache 中的規則。現在 PojoCache 只支援 LRU (Least Recently Used) policy。現在的設定下，在 &#8220;/message&#8221; region 中最多可存放 100 個物件，每個物件最多可以保留 10 秒。詳細的設定可以參考 JBoss TreeCache Manual 中的 <a href="http://www.redhat.com/docs/manuals/jboss/jboss-eap-4.2/doc/cache/Tree_Cache_Guide/Eviction_Policies-TreeCache_LRU_eviction_policy_implementation.html">LRU eviction policy</a>。</p>
<p>接著在需要 PojoCache 的 component 中指定 Injection ：<br />
<img src="http://farm3.static.flickr.com/2033/2236116183_e6e94d4dfd.jpg?v=0" alt="" /></p>
<p>留意改動後的 work() 方法，使用 pojoCache 就如一般的 Map 一樣簡單。</p>
<p><img src="http://farm3.static.flickr.com/2233/2235884935_7c59887307.jpg?v=0" alt="" /></p>
<p>使用 PojoCache 後再到 index.seam，會發現只有第一次啟動網頁時需要較長時間。<br />
在之後十秒內再 refresh 網頁幾乎不用任何等待，這是由於我們設定了緩存有 10 秒的壽命。</p>
<p>在此我們己經成功設定 seam 使用 PojoCache 了！<a href="http://www.reality.hk/articles/2008/02/02/776/">第二部份</a>將會討論使用 Page Fragment Cache 以及手動移除 Cache 的方法。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.reality.hk/articles/2008/02/02/777/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
