關於 ASP.NET 的 Cache

一般人大概會想,這有甚麼好說的,不就是在頁面加上 @ OutputCache 指示詞(Directive), 這樣就表示會快取頁面.
列在 .Net framework SDK documentation 裡的詳細語法:

<%@ OutputCache Duration=”#ofseconds” Location=”Any | Client | Downstream | Server | None” Shared=”True | False” VaryByControl=”controlname” VaryByCustom=”browser | customstring” VaryByHeader=”headers” VaryByParam=”parametername” %>

或許吧,這沒啥大不了的,但我好奇的是,背地裡,.Net 是怎麼幫我完成這件事情的呢??
從 .Net Framework SDK documentation 裡面,幾乎無法找到相關資訊,解釋得很籠統.
於是我只能作這些猜想:
1. .Net 利用 HTTP/1.1 的 Caching 來實現.
2. 內部再使用 Cache hashtable 來避免對後端過於頻繁的存取.例如,取得資料以後,先放到 Cache,如果 Cache 裡面找的到(表示沒過期),就直接拿來顯示,否則的話就再去取資料.
我對第二點沒什麼意見,實際上應該是要這麼作.
但是第一點,我就有問題了. HTTP/1.1 的 Caching 機制對 server 端來說,server 只是送出特定的 HTTP header, 如 Cache-Control, Expires 等等. (參見 HTTP/1.1: Caching in HTTP ).
對 client 來說,他收到這些 header, 怎麼實做,反而是看他自己.如果是坊間抓網頁程式,他可以忽略這些 header, 卯起來抓,那麼這樣就沒有 cache 的效果啦~
另外一點,我感到懷疑的,在他語法裡,可以指定 Any/Client/Downstream/Server, 所謂的 Server, 又是指甚麼意義呢?
就我自己的認知,應該是 Server 在處理的時候,會把整個頁面放到 Cache 裡面.
當遇到有人索取這頁面的時候,就會檢查 Cache, 如果有就直接取出.
所以我查找 Mono 與 .Net 解釋 HttpApplication 的部份,他們都特別指出了 HttpApplication 收到 web request 以後處理的順序:

1. BeginRequest
2. AuthenticateRequest
3. AuthorizeRequest
4. ResolveRequestCache
5. AcquireRequestState
6.PreRequestHandlerExecute
7.PostRequestHandlerExecute
8.ReleaseRequestState
9.UpdateRequestCache
10.EndRequest

特別注意步驟 4 與步驟 9, 他們都提到了 Cache.
p.s. 我覺得 Mono Framework class reference 寫的比較清楚, 參閱 HttpApplication
接著,我又利用 Google 查找相關資訊.
發現有用mono應用程式的 web.config 多半都會加掛 OutputCacheModule 這個 Module.

<httpModules>
<add name=”OutputCache” type=”System.Web.Caching.OutputCacheModule”/>
</httpModules>

參考 mono 的源碼以後,發現這就是我要找的.
這個 Module 的確做了我推想的事情.
他在 OnResolveRequestCache 事件先依據 FilePath 去檢查 Cache, 如果存在,就直接以 Cache 內保存的內容輸出.
接著在 OnUpdateRequestCache 事件,檢查頁面是否需要被 Cache, 需要的話,就把輸出結果保存到 Cache 中.
Bingo!!
但這是mono的作法, .Net 是否也有同樣的類別呢??
我利用Reflector 這個工具去看 System.Web.dll, 的確, 有 OutputCacheModule 這個 Module.
至此,我們已經解決了我想要解決的問題,並做出一個小結論:
如果想對頁面作 Cache 的話,需要作兩件事情:
1. 在頁面的開始加上 @ OutputCache 指示詞.
2. 在 web.config 裡面加掛 OutputCacheModule
可是我接下來想知道的是,如果我用 .Net 去寫作的時候,也需要特別加掛這個 Module 嗎??
再次求助於 mono 的源碼, 從 HttpApplication.cs 開始查找.
我直接搜索 HttpModule, 因為我想知道 HttpApplication 是在何時載入 Module.
HttpApplication 正巧有一個 HttpModuleCollection, 這看來就是 HttpModule 的 Collection.
宣告的名稱為 modcoll, 接著以 modcoll 進行搜索.很快就找到 InitOnce, 這裡以 ModulesConfiguration 對 modcoll 進行了初始化.
接著再查看 ModulesConfiguration 與 HttpModulesConfigurationHandler 的源碼, 至此已經真相大白.
原來如果沒有在 web.config 指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.
那麼微軟的 .Net 呢??
Reflector 查找同樣的 Class, 並進行 disassembly.
果然也做了一樣的事情,沒指定要掛載的 module 的話,只會掛載內定的 DefaultAuthenticationModule.
補充結論:
除了小結論所提到的事項之外,一定要在 web.config 裡面指定要掛載 OutputCacheModule, 才會更能發揮 Cache 的功效.
參考資料:
*HTTP/1.1: Caching in HTTP
*Caching in ASP.NET
*Page Output Caching, Part 1
*ASP.NET Caching
*mono的源碼
*.Net framework SDK documentation

freenx on Fedora Core 4

以前裝過,可是忘記了
現在又想用,結果搞了半天,好不容易設定成功了,把方法記起來.
$su root
#yum install freenx
由於這一版的 freenx 使用的目錄有點改變
所以到 /var/lib/nxserver/ 下,多增加一個軟連結
#cd /var/lib/nxserver
#ln -s nxhome home
接著改一下設定
#cd /etc/nxserver
#cp node.conf.sample node.conf
打開 node.conf
把 SERVER_NAME 與 SSHD_PORT 這兩行前面的註解拿掉.
重新啟動 nxserver
#nxserver –restart
確定 user 是否已經自動幫你加入了,看有沒有自己的 linux 帳號
#nxserver –listuser
如果沒有的話,那麼就得新增 user
#nxserver –adduser your_name
#nxserver –passwd your_name
安裝 Windows 版的 nxclient, 這可以到NoMachine網站下載.
下載完成以後就進行安裝,基本上都是 step by step, 沒啥困難的.
主要的幾個設定就是 ip, port, 還有 key
接著回到 server, 處理 key 的部份
這邊我不清楚是否要重新產生,不過我還是做了.
#nxkeygen
產生完畢後,切換到 /var/lib/nxserver/home/.ssh,將 client.id_dsa.key 檔案的內容複製出來,這邊就不仔細描述複製的方法了,總之你自己看著辦.
#cd /var/lib/nxserver/home/.ssh
#cat client.id_dsa.key
把這內容貼到 nxclient for Windows 的 key 裡面 (在 configuration 的時候會有個按鈕叫做 “key”,點下後可以貼東西 )
保存設定以後,輸入你的帳號與密碼,再進行連結,這樣就大功告成了.
參考資料:
*HOWTO FreeNX Server – Gentoo Linux Wiki
*NX/FreeNX HOWTO
*Linux-Tip.net – Remote access with FreeNX in 5 steps
*FedoraNEWS.ORG – HOWTO setup Freenx on Fedora

Whisky + 綠茶

今天在中時部落格看到這篇美酒加咖啡?不,威士忌加綠茶.
原來還有這麼一種混法, Whisky + 綠茶.
下次有空來試試看,依照我的經驗,挑選茶裡王的綠茶應該會比較順口.
因為他們的綠茶還蠻甜的…
突然想到,大部分混酒法都是以甜度較高或酸度較高的飲料與烈酒作搭配.
像是: Vodka + 七喜 (甜度高的蘇打汽水), 紅酒(酸澀) + 蘋果西打(甜度高的汽水) 之類的
莫非這就是調酒公式?!

weblogs.com 剖析

Overview
weblogs.com是一個彙整的服務,在這個網站上,你會看到目前最新的 blog 文章.
原理
weblogs.com是採取一種被動的方式來得知目前有哪些 blog 文章,換言之,也就是 blog hosting system 在發出文章的時候,就會通知(ping)weblogs.com,讓weblogs.com知道說有新文章啦…
運作
weblogs.com 主要利用兩個方式來接收 ping
*XMLRPC
*REST, 也就是以 http get, post 的方式
參數大同小異:
*name: name of site (limited to 1024 character)
*url: url of site or rss feed (limited to 255 character)
回傳值:
*flerror (bool): true 表示有錯誤發生
*message: successful: Thanks for the ping.”, failure: error message.
背地裡,weblogs 收到這些訊息之後到底做了什麼事情呢??
推測:
1. 組合 ping 過來的資訊
2. 排程,定時去 fetch
3. 把已經取得的資訊組合放到 xml, 裡面提供有 name, url, rssurl, when
name: name of the weblog
url: url
rssUrl: 該網站的 rss/atom feed url
when: a number of second, 拿 weblogUpdated.updated 減去此數字,就是 weblogs.com 收到 ping 的時間.

惡搞-烏來聯外道路

今天逛到惡搞之事,居然有要搞這麼一條路,從三峽到烏來。這中間可是跨過不少山區耶….

前幾日回祖父家(獅頭山附近)的時候,才聽到長輩們在聊,說最近山區這附近(含宜蘭)落下的都是”鹼雨”,使得作物都長不起來,聽說是安坑焚化爐引起的(不過這沒依據…參考用)。這附近已經很糟了,現在還要搞這條聯外道路,肯定對環境影響很大。

這裡是發動一人一信的網址:http://home.kimo.com.tw/syhalpinia/letter.htm,多少出點力吧,決定的日子就在明天了…

 

夢境-電梯

前幾天做了個夢,情節很類似鬼故事.
不知怎麼的,跟同事分手,我回公司八樓.
回公司途中想到 USB 隨身碟借給同事 I, 於是趁著同事還沒走遠, 趕緊跑去拿.
拿回來之後,就回公司.
公司在八樓,所以當然是坐電梯,一坐之下,居然到了頂樓.
頂樓挺吵雜的,蠻多人閒逛,也蠻多人在那兒賣東西….
我試著搭電梯下樓,但電梯總是不來.
於是我試著從樓梯間往下走,這時候有個老外和我一起走,他還蠻照顧我的.
可是說也奇怪,不管我怎麼走,都還是回到頂樓.
突然有個人敲破玻璃,拉著綁著柱子的繩子往下跳,後來沒啥消息.
沒辦法,只能找那些賣東西的人幫忙了.
賣東西的人說,”你得專心致意地搭電梯才能下去.”
果然,我下去了,到了一樓… 可是我想先到公司啊… =_=”
夢境裡面好像還有要好的五專何同學,但我忘記發生啥事情了…
唉~~實在是應該當天記下的.

給定 assembly strong name 的方法

給定 assembly strong name 的方法
1.sn -k “your_snk.snk”
2.在你的 AssemblyInfo.cs 裡面加上
[assembly: AssemblyKeyFile(@”your_snk.snk”)]
3.編譯,收工.
Mono 也有同樣的指令,用法也完全一樣.
不再贅述.

混合編譯vb.net與c#

上次有人有在討論區問到怎麼混合編譯 vb.net 與 c# 的程式.
那時唯一的好解法,就是將 vb.net 程式編譯為 assembly
c# 程式也編譯為 assembly,這樣就能交互引用了.
這樣的缺點是,assembly 會比較多一些.
今天在CodeProject逛到這篇:Post build step static linking tool for C#, using ILMerge,恰好就可以解決此問題.
他引用了微軟研發ILMerge來作合併的工作.
不過很可惜的是,ILMerge目前還不能在Mono上使用.