2016/06/27

資料流 dataflow

120518-A-AB280-_-30

即使再愛寫程式, 仍然相信未來的數位應用是不需要寫的。

如果不用寫, 那會是:
  1. 程式產生器, 像填寫問卷或描述摘要一般, 再生出對應程式。
  2. 強化版 IDE 或 Scratch/Alice 拖拉。
  3. 人工智慧 加 對話介面 (Siri+)。
前兩項侷限在某些範圍, 最後一項雖然部分已達成, 但普及(廣度/深度)仍然需要時間。

比較相信的方式是透過資料驅動 (data driven), 雖然這詞已被定義在特定範圍, 這裡以更廣的角度來看 …

用時事舉例, 偏黑色的例子: 如果一個名字出現在高層的『黑名單』, 不用特別吩咐, 組織裡就會有特別的處理方式。在這情境下, 名字資料, 有機會驅動許多非正規服務的運作。服務的多寡, 端視人心有多黑。

愈寫愈冷, 換點正常的舉例。

有一陣子, 在商業/工作流程的產品上開發。流程、表單、管理, 組合得好, 客戶也開心 … 幾乎相信這是數位化的聖杯。直到某年夏天安裝冷氣, 師傅們能在 12 樓凌空裝支架固然讓人驚嘆 (工作加表演, 合法嗎?), 完工後立即用 Line 拍照回報, 才發現之前產品有些地方是到達不了的。整個過程能辨識身分(IM User), 在特定通道(開群組)資料不會亂, 而使用者要準備的資料只有照片 (手機應用的普及又比客製程式優) … 不用專屬產品, 卻綽綽有餘。雖然做功能評比, 產品可能會有優勢, 但實務上是能忽略。

另外, 豐富的雲端應用, 也消彌客製開發的必要。

例如, Google Forms 讓問卷填寫、搜集更容易。遇到排班表的需求, 雖然表單難做, 但可直接使用 Google Sheets 像真實的班表開放給大家填。配合清楚的規則(有填寫紀錄), 以及 Line 即時使用協助, 只要填上姓名資料即可。原本預計幾天才能做完(傳統紙本), 結果不到一個小時就收工。

這三個範例, 都只有少量且必要資料, 就足以成事。形式上分別類於反應式 (reactive, 資料到服務), 流處理 (stream processing), 以及資料協作 (collaboration) 的例子。前兩者明確定義類等於資料流 (dataflow), 最後一項是目前數位化應用的主力之一 。

從已往開發的角度來看, 會需要採買或打通一些產品, 外加一些寫程式的工作。現在, 依附已有的應用, 在適當規劃下, 都只要一些資料就可達成目標。

未來利用資料流的方式, 當是愈來愈多。

2016/06/20

應用開發的階段史 - 套包、殼層、木馬

How to Draw a Horse by Van Oktop

應用開發有趣的地方, 除了有寫不完的程式, 某種程度必須與時俱進, 不斷的面對改變。再者, 資訊科技在各行各業滲透程度愈來愈高, 自然產生更多應用開發的需求。變化, 擴散, 再加上循環, 形成無窮盡。有人厭倦, 卻也有更多人加入。

經歷一些隨坡逐流的改朝換代, 逐漸也有自己的步調, 去調適需求, 參與人力, 以及處理不同目標。
從流行的角度, 所謂的階段應該是 web, agile, mobile, serivce, cloud, big data, …。
這裡從過往經歷不同的嘗試來看:
最早著手於開發的基石們, 不斷認識不同的語言, 元件, 工具。
一直到現在, 用套包 package 解決特定問題, 產品、框架、服務大多以這種方式存在, 相處也愈來愈自然(不見得輕鬆), 不論是著手使用, 或要加加減減。
再一步是面對人力更迭。
長久以來, 雖然大家的任務可能不同, 不同工但同具, 甚至同工同具, 讓大家視野皆同, 很多問題時間可解。一旦有客戶的人員要加入開發組, 就成為一項挑戰, 因為整疊工具要上手, 並不是短短時間可解決的。
雖然主流是大家一起學寫程式, 但有難易、親疏之分, 要把人力拉齊不容易。
開源常見的腳本語言可解這項難題 … 把落落長的實作, 用更容易表達的方式呈現。對新加入開發組的客戶而言, 更好學習, 更好應用, 也更容易維護。
原本歸功腳本語言的強大, 後來習得資料流 (dataflow) 手段, 以試算表 (spreadsheet) 搭配某元件解決另一項難題後, 方才體驗到這是殼層 shell 概念在發功。是 linux, osx 使用者的日常, 但放到應用開發 … 可讓需要程式專業的部分開放給更多人參與。
最後是跳脫循規蹈矩。
原因是客戶指定基石 .net 加上 m 社的一堆產品。.net 固然是近來完整又與時俱進, 有問題的是搭建在上面 流程、表單 等產品。後來 m 社也宣告 2013 是最後一版, 且在 2023 停止支援。
實際面臨的問題是, 即使只改一個需求甚至改一個字元, 都得歷經一段超過 10+ 分鐘的特殊工具存檔, 打包 (pack) 與部署 (deploy) 過程。這和主流編纂原碼, 由版本控制系統加持部署的方式大不同。而且它的部署還不時有原因不詳的失敗 … 實際時間是 n 倍計。
儘管不同平台有不同部署的方式, 但對於資訊應用系統, 以原碼或利用殼層隔出原碼操作, 讓所改即所得, 是較理想的方式。最好的例子是 web 應用, 不論 html/css/js 如何往上擴充, 原碼透明度都高, 找問題並解決才方便。畢竟運算資源提高了, 這種方式對待人力資源是比較友善的。
改變的契機在一個與 linux 整合的專案, 前端依然是 m 社的產品組合, 後端則帶進開源服務套件。後來順勢把其他專案的後端都取代, 但使用者接觸到的包含 m 社的 web 介面、管理、資料庫保持不變。取而代之的後端可視為木馬, 透過這個木馬讓開發者得以直接變更原碼, 更快更容易達成目標。
以上回顧了過往開發的三個階段: 套包(package), 殼層(shell), 木馬(trojan)。
基本上, 對一包包推陳出新的零件保持興趣, 相處得好, 伺機解決疑難雜症。
這些有的可能是產品, 有的是框架, 有的是服務, 有的是個語言, … 各別自成體系, 學習曲線各自不同。如果需要更多人加入擴展應用系統, 人員程度角色不一的狀況下, 規劃出殼層是種解決方式。
搭建殼層通常透過腳本語言做簡化和操作 API 以及資料, 如果要非程式人員也能貢獻, 規劃資料流的殼層, 例如試算表則是更佳法門。
然而面對品牌迷思, 教育別人, 不如改變自己, 種子也要扎根才有長大的機會。塞個玻璃般透明的木馬, 成為一種手段, 畢竟開放又方便, 讓人很難拒絕。

2015/06/01

打造微服務

剛開始並沒有預期是使用微服務。

在不斷調整的過程, 以及閱讀他人的想法後, 瞭解自己所處的位置。

推敲起來, 像是在一個只有筷子的用餐環境下, 自然會去使用。雖然不是刻意, 終究殊途同歸的結果。

主題是替某個研究單位打造內部資訊系統, 將目標和資源透明化的專案管理工具。

開始打工, 指定 M 社的 CMS 方案

團隊成立, 有不少角色, 大家都在熟悉中。
照傳統的方式進行訪談, 分析, 設計, 實作, …
光是資料表就討論大半年, 畢竟這是全部的人都認識, 總能談上兩句。

在 M 社工具(SD/IP/SM/VS四樣)加持, 歷經一番波折後完成。
工具多, 卻有各自的假設。在預給情境下, 拖拉點貼就解決。
然而, 經常面對的是一堵堵高牆, 愉快的滑鼠生涯了結, 開始耕碼長征之路。
在 API 叢林穿梭; 也在系統間徘徊。
幸好有許多第三方元件支持, 第一版得以面世。

棘手的問題在於, 冗長的開發到結果, 是一大包(monolith)。
縱使 M 社兵多將廣, 面對複雜的環境, 提供更多工具, 卻更令人左支右絀, 疲於奔命。即使變更一小處字樣, 從修改到配置, 不僅耗工夫, 也費時間。

如果偏好階級化流程, 有一大撮團隊, 絕對可讓大家都很忙, 每個人都有事情做。


因地制宜, 替系統加一層殼(Shell)

當時領域探索的人多, 需求也多; 然而隨時間推衍, 變化也多。
按官方手法實作, 必定成為瓶頸。

為了將 需求實作 的距離拉近, 借鏡 Unix, 在應用系統上加一層 Shell。作業系統的 Shell 通常是一個互動環境, 但在應用系統有不同呈現方式。例如要修改已有的網頁, 用 jQuery 一般比手工刻 JaveScript 好。存取複雜的資料, 透過 ORM 常不如 SQL 直接。而以框架為底、API/程式庫為輔、使用工具打造的應用, 也的敵不過腳本(Script)靈活。

這個案例是有工具負責資料綱目, 流程/表單, 並用 C# 做擴充。

最後維持資料綱目, 保留表單, 改為事件驅動(Event driven), 基本上利用 Powershell Script 在表單變化時更新資料庫, 同時擔任流程處理與擴充功能的任務。 對使用者的結果不變, 但流程的反應較好(原本頓頓的); 擺脫工具大包的束縛, 更快滿足需求。

從結果來看, 這個技巧是讓需求到方案的流動, 透過新搭建的 Shell, 約 80% 可快速流過; 縱使還有 20% 得經傳統工具, 由於毋需經常打交道, 阻礙自然較低。



持續開發, 逐步擴展, 遞加服務

完成第二階段, 系統表現稱職, 跑出新題目 … 建立 TLD 服務。兩個子系統 bind/whois 包含 server 和 DB 在 Linux, 使用者介面被期望繼續在 M 社的 SP 上。一般性應用的開發, 會將 DB 連線拉到 SP, 解決跨系統、跨設備的問題。但我們以系統安全的角度, 選擇用訊息傳遞(messaging)來解決, 順勢引入 python 的網路服務引擎 twisted

隨著系統擴展, 在 2014 的某個階段, 決定後端服務皆用 twisted。

這個決定點在於, 綜使之前做了簡化, 但開發的元件散落在各子系統上。加上原廠的方案, 檔案幾乎都是 binary 或是一大串, 版本控管有麻煩, 再在使變更困難或成本驟增。

所以把在各子系統做的, 除 UI, 權限管理外, 將通訊處理(protocol)、編組/解組(marshalling / unmarshalling)、資料存取、子系統溝通(REST 或 Web Services) … 分層(layered)後做成 twisted 的服務, 全部處理都訊息化, 包含檔案上/下傳。

這些順勢做的改變, 後來對照 microserivces 的要件, 很多地方相似, 甚至一致。

最明顯的好處是在面對人力多樣化, 經歷過: 原班的開發人員, 甲方組織的員工, 以及最後加入的外包單位。自己組員問題少, 甲方組織要投入前, 備妥環境著實不易, 後來用簡化的虛擬機器(做成 VM), 讓人入手。 到了外包單位加入, 已經有新的架構, 只要把 python 環境建立(難度大概只有 1/20 吧?), 加上源碼儲存庫, 按著符合情境腳本(Scenario)的 nose 測試碼, 就可開拓新的道路。不論開源工具帶來的好處, 新的方式讓開發者在特定區塊(Bounded context)就可完工, 是差異所在。

按照目前狀況, 應用系統想組合/分散功能, 更換子系統, 包含資料庫與文件管理(DMS), 甚至作業系統(docker?), 都變成策略面的考量, 不會因為技術造成障礙, 或讓開發好的應用鎖在某個地方。嗯, 是鎖在 python 上沒錯, 不過還有幾個選擇 …。

(待續)

2012/12/09

PDF Forms

近來關注著表單的相關方案, 除了 Web(眾多框架, backbone-forms), XML(XForms, InfoPath, XUL) … 前陣子逛軟體商店, 才發現有處理 PDF 表單這類 App。

搜尋相關資源, 整理一下 …

雖然系出 Adobe, 卻也不一定需要 Adobe 官方指定工具, 就能從頭到尾、從建立到處理, 完成所有工作。

特點

和 Web, XML 方案要一整個系統最大的差別, 在於 PDF 的表單只要單檔就可運作。

1. 方便移動

PDF 表單除了只要單檔, 和 PDF 一樣, 不論行動設備或各種常見的作業系統都通行。

在 OS X 上的 Preview 可直接填寫。

另一個觀點是能離線作業 … 得以各別填妥表單再傳送處理。

2. 容易讀取

不論對人與電腦都方便。

PDF 可輸出的樣式彈性很大, 幾乎是報表方案的代名詞。好讀自然不再話下, 只要有適當的設計規劃。再加上一些欄位就成為 PDF Forms, 立即讓人填寫。

讀取表單內容, 可利用 pdftk 直接讀出資料, 毋須寫程式也可使用 … 在下一段介紹用法。

實作

很多介紹, 是以寫程式來產生 PDF 表單, 後續處理表單資料也要額外程式 … 其實不一定需要, 這些工作不寫程式也能達成。

1. 建立表單 PDF Forms

在 OS X 有 PDFpenPro, PDFClerk Pro, PDF Nomad 可替 PDF 加上表單欄位。

開放源碼 OpenOffice(使用版本 3.4.1), 則可在各平台直接建立 PDF 表單。步驟大致如下:

a. 新增 XML 表單

11 New XML Form

b. 建立表單項目

在下面的範例, 塞一張圖檔、加一些欄位, 額外使用淡紅色標示欄位名稱

12 Construct Form

建妥表單, 再到下一步。

c. 輸出 PDF 表單

13 Export PDF

d. PDF 表單選項

14 Export PDF Options

e. PDF 表單檔名

15 Export PDF Filename

完成以上步驟, 應該能順利產生 PDF 表單: fruit_order.pdf 檔案。

下載: fruit_order.odt(無法預覽, 請選擇下載), fruit_order.pdf(線上看有點怪, 下載後 ok)。

2. 取出資料

a. 填寫表單資料

使用 Preview 按上面 PDF 表單給定欄位, 填入各項資料。

21 Fill PDF

填入的資料會存入該 pdf 檔案中。

b. 讀取表單資料

使用 pdftk, 如果檔案放在 ~/Desktop/fruit_order.pdf, 執行如下指令:

$ pdftk ~/Desktop/fruit_order.pdf dump_data_fields_utf8 output -

就可將表單資料輸出到 stdout, 或把 - 改為檔名, 選擇輸出到特定檔案。

22 Use pdftk

和先前 b. 建立表單項目 步驟比較, 可看出 欄位名稱 (FieldName) 和 填寫資料 (FieldValue) … 很容易對上。

3. 佈置 PDF 表單

從上面的介紹, 瞭解 PDF 表單 建立, 填寫, 讀取 方式, 接下來看看怎麼安置這些 PDF 表單檔案。

a. 電子郵件

PDF 放在網站上提供下載, 或以電子郵件傳給需要填表單的人。

在 PDF 表單裡頭標注, 填寫完寄給 foo@jia-side.org … 即可完成表單發送、接收的程序。

只是收到 PDF 檔案後會怎樣被處理, 全取決於經辦人員。

b. 檔案分享

適合組織內區域網路中檔案共享, 或使用網際網路檔案服務的方式 … 也就是特定群組內的檔案分享。

在檔案相關系統中, 安排 PDF 表格處理方式的各種目錄。例如: 所有表單的 樣板目錄, 處理中目錄, 完成目錄, 以及最後流入按年份分門別類的 庫存目錄, …

使用大部份人都熟悉的方式, 不同工作在不同目錄間流動, 即可完成許多原先紙本的工作。

c. 內容管理 + 流程系統

基本上, 是前個項目 b. 檔案分享 的進階版 … 概念相同, 但所有動作自動化。

  • 樣板目錄 中, 各表單的版本由內容管理區分。
  • 新填表單送入 收件目錄, 由流程系統分派給經辦人員。
  • 表單處理的特定過程, 皆由流程系統安排。(可考慮資料檢核)
  • 處理完成, 按流程安排的步驟放入 完成目錄 中, 供相關人員瀏覽。
  • 老舊檔案的時間屆存檔年份, 內容管理負責移到 庫存目錄 備查。

用途

表單是許多組織行動的基礎, 單純表單的角色, 卻常被使用系統人力資源所左右。

複雜的系統, 其本身往往就需要很多專業人士來維持。

從頭打造的應用系統, 建立/維護也是個問題, 總不成每每來個衝刺。

使用 PDF 表單, 有機會突破這些罩門。

  • 能操作文書軟體, 就能建立/維護表單。
  • 不需 Web 專業, 也可在表單中盡量放入必要訊息。(參考高鐵轉乘服務的PDF檔)
  • 讀取表單內輸入項目的資料, 只要工具, 不用寫程式。

使用方面 PDF 表單也近似紙本表單, 能高亮(Highlight)標示、張貼備忘(Note) …

31 Preview PDF Note

再者, 若打通檔案的流通, 透過智慧手機、平板設備處理 PDF 表單, 會更接近真實填寫表單, 包括簽名

2012/09/18

PyHUG 2012/09

PyHUG 九月份主題是 BBS Crawler(bsdconv) 和 Plone

bsdconv 在萬碼奔騰的年代, 處理多種 codecs 和多樣 encodings 是很好的方案。

marr 帶來 Plone 這個 CMS 的簡介和近況。早先我學習 Python 是想用 Plone, 它是一個有感情基礎的 CMS XD

在討論的過程中, 有人對客製強化功能有興趣, Plone 也提供很方便的工具, 我過去也是 跟著既定的脈絡走。但最近使用 SharePointInfoPath 執行一個中大型屬於 CMS 的案子, 所以有其它想法。

首先, 在資料規劃上 … 大量, 多欄, 關聯的資料, 最好的歸宿還是資料庫。CMS 適合擺放目錄式, 多樣(圖檔, pdf, xls, doc, …), 和多版本(v1, v2 的 doc) 的資料。

概念上, 前者適合應用程式(Application), 後者配合流程(Process)。

應用程式處理資料的方式千變萬化, 通用的資料庫仍舊是好選擇。特別是商用資料, 對資料有各種使用方式, 避免瞻前顧後的話, 資料就放在成熟的方案裡頭。

如果說資料庫中表格(Table)的上位是 ERD, CMS 中內容(Content)的上位就是內容型態 (Content Type, CT)。不論 Plone, SharePoint, 或 Jackrabbit 都有相同的概念。通常在 CMS 以檔案系統的概念來做高階規劃 … 建立目錄結構, 接下來就是在目錄下分配使用 CT。一個目錄可使用多個 CT, 也就是先前提到的 多樣性, 而 CT 有不同版本對應不同 Content, 即多版本也順利在 CMS 中成立。 拿程式語言來比擬, CT 像是 Class, Content 是 Object, Folder 是 Collection。

再加上 CMS 對 CT, Folder, Content 有良好權限管理 (Plone 強項, 可類比成 檔案系統的權限設定)。基本上放在 CMS 的資料, 不會被不相干的人取得, 竊認為這是 和資料庫最大區別。

試想 … 流程有多樣電子資料要附帶著, CMS 就是一個很好的載體, 要區分存取權限 也容易。流程若有調整, 造成電子資料的差異, CT 多版本能順利解決這類問題。

應用程式當然也可以做, 但中間規劃, 設計, 與元件 … 太多是重複問題。有些框架有元件, 先不論功能適用, 能像 marr 所言: 最新的 Plone 4 最新版還照顧到 7,8 年前的 Content 就是個門檻了 XD

而許多事務流程系統, 重視流程的彈性, 卻忽略實際工作的要務 … 讓整合困難重重。

說到這裡, 有個題目是 … 表單 (Form) 適合資料庫, 還是 CMS?

不用說很多 MVC 以資料庫為主, 很多 View 概念上就是表單, 甚至 HTML 都有 form 標籤。 考慮實際流程發生的安全問題, 檔案管理, 流程變更要兼容並蓄(新/舊版本), 雖然有各式 各樣的解決方案, 但這些問題放在 CMS … 很自然就被解決掉了。

但在 CMS 裡頭做表單, 問題是 … 簡單的很快, 複雜的費工又很痛(會的人不多)。

我忽略 CMS 的角色有一段時間, 直到用過 InfoPath …

簡單來說 InfoPath 可直覺且快速完成複雜的表單(免除魔術師養成), 然後在 SharePoint 做為一個 CT。安排在特定目錄下, 表單資料存成一個純 XML 檔案, 取得也是一個 XML 檔案。

這種方法接下來的問題是, 要把資料放在資料庫 … 現在資料庫處理 XML/Json 都很強大, 都可以直接吃 XML, 或輸出 XML … 省卻中間的 App Server 或魔術師用的框架, 只要有 SQL 經驗, 輔以一些 XML 的操作就可上手。

整個過程大致是: 

基本上, 在 CMS 的加持下, 免除了表單與資料庫千絲萬縷的關係, 變成有必要才做。

而 OSS 在這方面 … 目前看到的方案還是與資料庫緊密結合 orz

除了一些以 JavaScript 加重瀏覽器負荷的專案, 例如 Backbone-form … 這也是最近嘗試瞭解的題目。

以上是從 Plone 這 CMS 角色延伸想到的 ... 整理下來。從服務式架構的角度, 各組合的角色要清楚, 避免把太多東西塞到某個元件裡。很多時候, 應用開發沒有問題, 畢竟很多功能的差異都可透過努力去彌補, 但清楚的角色有助於系統維護, 另一方面考慮元件的生命週期, 要升級/替代也才能較順利的進行。

另外, 會後聊到 Gmail 保密問題, 我有時會用 GnuPG 套件 … 如果收信人願意的話 XD

組合是 Postbox + Enigmail, Postbox 對 Gmail 的支援良好, 又吃 Mozilla based 的 add-ons (Enimail 提供 GnuPG 功能)。

2012/09/11

嘗試 Require + LiveScript + Backbone

最近想利用 Backbone 的某個套件來做東西, 於是開始摸索 Web 前端。

原先打算用 CoffeeScript 撰寫 Backbone 相關程式碼, 只是 半路 看到更加 有趣的 LiveScript … 馬上改弦易徹。

對 LiveScript 新手, 最初的挑戰 … 不確定寫的是對還是錯。 LiveScript 有個方式是 轉成 JavaScript 來確認 … 雖然有 LiveScript.tmbundle 可為 TextMate/Sublime Text 加持, 由於挺偏好 CoffeeScript-Sublime-Plugin 透過 Command Palette … 選擇 CoffeeScript: Run JavaScript 的方式, 把 CoffeeScript 轉成 JavaScript。於是 混合 LiveScript.tmbundle 和 CoffeeScript-Sublime-Plugin 建立 LiveScript-sublime 專案, 加強 Sublime Text 對 LiveScript 的支援。

接下來是程式碼模組化, CoffeeScript 有 require-cs 擴充 Require 載入 CoffeeScript 能力, 但 LiveScript 沒有。因此參考 require-cs 建立 require-ls, 方便 LiveScript 切分模組。

最後試著把這些組合起來, 以 Backbone 原本的 範例 改寫 為 LiveScript 加上 Require 的版本 … 建立一個 require-ls-backbone 專案記錄這些嘗試。

2012/08/13

集中/聚眾/集眾開發

一直從事軟體開發工作, 其中不論參與產業, 各類技術, 團隊規模, 時間長短, 雖有各有不同, 皆是解決客戶問題為主, 也都是專案的型態 … 而專案執行方式也各有不同, 從古早到近年流行的, 或多或少都參與過。總的來說, 都是由外而內的驅使著開發者, 必須針對客戶的需求做處理, 做回應。

從剛開始是廠商, 標準, 或方法的傳聲筒, 到現在能夠提出各式各樣的嘴砲意見。這是 … 馬齒徒長!!??

由外而內的改變, 雖然邊拉距邊有進展, 但聽說真正的成長是由內而外。因此, 開始思考在執行專案時, 發生衝突到最後調和的事件。嗯, 這篇不是談技術, 因為技術最好的歸宿就是被消滅; 也不是談業務, 因世代更迭的業務, 總是來來去去。目標是整理一下開發大環境的差別, 及相關的影響。最後歸納為, 開發者正經歷集中開發(Central), 聚眾開發(Clustered), 與集眾開發(Crowded)的不同世代。



把紅點視為一開發單位, 紅點散落位置區分了不同的方式:
  • 集中開發: 紅點集中在一起, 為共同目標而努力。
  • 聚眾開發: 紅點聚落各有長處, 分工聚落各有發揮, 但聚落合作才能完成目標。
  • 集眾開發: 當群體進展到某個程度, 個別單位縱使降低對資源的要求, 還是能達成目標。



從硬體, 軟體, Java 舉例來說:
  • 硬體: 古早到現在 IBM 的角色, 毋庸置疑; 台灣著名的就是電腦組件聚落; 蘋果則近年來讓電腦取代寵物的地位方面功績卓著。
  • 軟體: Oracle 專長打造資料的家; MS 建立的聚落嚴有許多 … 作業系統, 企業應用, 遊戲; SF 雖然漸漸被取代, 但卻是讓大眾發表分享源碼, 方便交流的起點。
  • Java: Sun 早先前集中資源打造出跨世紀的 JVM, JDK; Apache 以 Web, Services 甚至雲端著名, 近來常做撫養托孤業務; Hadoop 是 Apache 其中一個聚落, 但更能表現集眾開發, 為此獨立出來。
先看 Apache 與 Sourceforge, A 和 S 都是開放源碼的重鎮, 但 A 是會員制, S 則隨開隨用。Apache 能到頂層(top level)的專案, 幾乎都可視為一個聚落, 聚集著對專案有興趣的公司或個人。開始先在論壇, 事例追蹤上參與, 被認同後才賦予擔負工作的身份。A 要去瞭解, 要去參與, 而 S 只要名稱不同, 很快就能開個專案, 我還是我。在早期 S 能聚集的是本身具備吸引力的專案, A 透過組織方式更能推動發展。

發展到一個階段, 開發不只著重開發者的角色。以社群類處理的使用者數量來說, 是早先集中式商業公司嘗試以高規格軟硬解決而失敗的題目。流行的方式是將問題分解, 個別強化, 捨棄不需要的部份, 組合成因應需求的系統。例如, 連線數量(MINA), 訊息處理(Camel), 計算能力(Hadoop), 資料存取(Cassandra), 內容管理(Jackrabbit), … 全部都可以分解, 組合, 不需要一個全能的應用伺服器(Application Server)。

更重要的是, 個別專案都經過不斷使用的驗證, 也持續被使用。例如: A 賣場, F 聯誼社, G 廣告商參與的 Hadoop, Cassandra, … 要集中資源或指定聚落開發類似的功能, 都難以負荷。但從滿足大眾市場, 回頭灌溉成的專案, 就能因此受惠。

所以集眾開發必須加上, 個別經營大眾的觀點:



在以上前題成立的狀況, 個別開發也成為可能:



回頭看過去執行專案使用新技術, 會不斷被勸阻, 因為總是增加風險。但最後化險為夷, 是這些新技術總是進展到一個難以預估的地步, 不論是功能或穩定方面, 這些都不是古早開源專案可以想像的。唔, 大約十年前。最後的結果 … 除了組員肯定, 也被客戶讚許(多次廠商競賽, 都協助客戶拔得頭籌) :-)

那些都是隨波逐流的好處, 卻也可能遇到 … 使用協力的專案被腰斬, 功能不如預期, 整合障礙, …。竊認為是技術問題, 調和正正負負的項次, 就不在這裡細細討論。

最後記下一個開放問題: Scrum 方法用在何種開發情境(集中, 聚眾, 集眾)合宜?

2011/12/14

OFBiz Go

App 很紅, 主要在行動設備上, 上下游都很火紅。要談的 App 是現在不太紅的 Ent App (Enterprise Applications), 或是說已經紅過了, 但仍然是每個公司, 組織都會用到的。

App 多是產品, 而 Ent App 是種社會(Social), 俗名是江湖, 充滿交流與妥協, 大多以專案形式進行。就算從產品開始, 後面也會帶專案, 常見區分出軟體, 硬體, 開發, 維護, … 各個階段。

由於 Ent App 牽涉層面通常既廣又深, 以技術角度來看, 擴散方式(銷售, 安裝)一直沒太大改變。現在雖然服務導向, 雲端喊得震天嘎響, 但除了網路基礎服務(信件,檔案), Web應用或特殊應用, 要把 Ent App 放上去, 應該還有些東西要準備好。用雲端的榜樣電與水比擬, 水除了自來水, 還有各式來源; 電除了公共設施, 也有可移動型的, 或私人備援。因此資料的移動能力要具備, 否則還是有些不足。

開放源碼讓技術普及, 加上硬體設備的大幅提升, 過去得詳加規劃, 才能執行的 Ent App, 現在只要在雲端或筆電開個 VM (虛擬機器) 就行開工。再者, 小公司不需要 24 小時運轉的系統, 功能有的話, 需要時再開啟。甚至中型單位, 只要合宜的環境及配套規劃, 也能朝這方面努力。

首先, 要面對的問題是 … 怎麼去開始?

OFBiz 下載頁面中, 寫明只要有 JDK(Java 1.6 SDK), 下載 zip 後解開壓縮檔, 執行指令就可以開始。

似乎還算容易?

但每個平台準備 JDK 其實都不太一樣, 更不用說如果發生衝突的話要怎麼辦, 例如在 Linux 上用 OpenJDK。這些說明字句雖少, 看起來簡單, 毫無疑問是寫給工程人員看的。再加上 Ent App 的社會屬性是有機成長, 如果要修改, 要調整, 按照慣例就得靠自學, 或找人助拳。

以整個過程來看, 愈到後面, 障礙愈高, 的確是不太容易推動。

之前在一種應用源碼管理的實作討論過 可短小, 可長久, 可分享 的客製化方式。路雖然通了一小段, 但想想, 比原來 OFBiz 官方的安裝方式還要複雜, 素人要開始, 會有不小的障礙。

因此做了 OFBiz Go 用一個步驟完成 所有 繁瑣的準備工作。

準備工作有:

  1. 下載必須的 JDK, Python, Subversion, Mercurial 以及相關工具(patch, diff, cURL, 或 Wget), Windows 要再加 MinGW
  2. 安裝妥上面這些東西, 做好設定 … 例如系統變數, Mercurial 的設定, 與 virtualenv 的環境。

當然如果機器上已經有的軟體項目, 就略過不下載, 也不安裝。

寫上一篇的時候, 略過這些步驟。對熟悉這些工具的人, 早就備妥; 但不熟悉的人, 繁瑣且容易漏東漏西的過程, 反而造成困擾。即使自己做, 將這些裝到 Linux, 也碰上不少問題。

想做個 VM 來用, 但每次要把數 GB 的東西搬來搬去, 還得搬進雲裡頭, 舉重若輕恐怕也不太容易辦到。

在支援 Windows 前提下, 也考慮 Puppet, Chef, 或老牌 CFEngine 這類 組態管理 工具。但即便輕如 CFEngine 都必須做額外的安裝設定, 所以這工具還是留給 應用系統, 做為其中的組件。

剩下可用的大概就是系統腳本語言(Shell Script)。

OFBiz Go 是先在 OS X 上寫個 .sh 做完上述工作。然後找到 Windows 2008 用 Powershell 寫個 .ps1。最後用 VMWare 開啟 Ubuntu 11.10, 原本認為 OS X 小改就可以用, 但還是改了不少。

比較特別是 Powershell 挺有 Power 的 … 要正確合法下載 JDK, 需使用者同意。Powershell 可控制 IE 瀏覽器帶出正確下載網頁, 當使用者點選同意後, 繼續腳本的工作。

目前在 OS X 10.6, Windows 2008R2 / 7, 還有 Ubuntu 11.10 測試過。OS X 可能會不太行, 因為環境不乾淨。;-)

只要腳本的下載, 安裝, 驗證的工作做完, 就可和 應用程式源碼溝通。把繁瑣的過程, 劃分成兩個階段, 方便入門者, 也方便自己。

由於大部份工具和 Python 相關(Fabric, MQ), 下週三(2011/12/21) 晚上 19:30 在新竹的 PyHUG 會描述 配置方式應用客製 兩階段的安排, 及運作細節。除了 Ent App, 很多類似的狀況, 也可用相同方式處理。歡迎參加, 和我們一起討論。

2011/10/31

數位中樞

今年初(2011)在考慮資料問題, 腦中閃過一個字詞 "data hub", 而後 data 範圍擴大, 改為 digital。在網路搜尋 "digital hub", 赫然發現 10 年前已在某個場合上提出

賈伯斯先生當時提出 digital hub 是 Mac, 圍繞 hub 周圍的是音樂播放器, 手機, 數位相機/攝影機, 影音播放, PDA, ... 等等設備。

Digial Hub

看了一會, 難免感嘆即使同個字詞, 在不同背景產生的意義與結果是完全不同。特別是 hub 旁邊的設備已被征戰過一輪, 圖片的戰略意義更能凸顯出來。

上禮拜和某長輩聊到創業的話題, 提到 digital hub。再搜尋一次, 果然有人把該圖視為霸業的開端, 而在今年中 digital hub 向雲端轉進

另外, 也看到我們的 B 社, 相隔 2 年, 在 2002 年末就追上驥尾, 推出產品, 其實算快了。但和韓國的 S 社比較, 就很堪玩味。

最後心得是 ... 如果常留意業界資訊, 應該就不會去想 digital hub 這組字詞。

2011/10/02

泛 Markdown 編輯器

Markdown 專治滑鼠過動, 加持文件檔案撰寫。主要功效是運鍵如飛, 也能有好看好編的文件。

即便使用 Markdown 只要能輸入文字的編輯器都行, 然後再加工處理。先前找相關軟體, 只有少數編輯器, 網誌特用編輯器, 還有就是深具實驗性但得常重開程式的佛心開源類。現在相關應用已遍地開花, 這幾天在更新一些軟體, 就發覺 Markdown 被普遍支援且種類繁多, 也因此補入一些工具 …

BBEdit TextMate Espresso MarsEdit nvALT Scrivener Byword Marked
格式 MD MD/MMD MD MD MMD MMD MMD MMD
預覽 即時 手動 手動 即時 即時 批次 手動 唯讀
用途 通用編輯器 網誌庫 文件庫 專寫
(M)MD擋
專看
(M)MD擋
特色 老牌 現代 網頁 網誌 Simplenote
同步
寫作 好看 方便
$ $$ $$ $$$ $$ 0 $$ $ $

這樣看下來, 剛開始入門的首選非 nvALT 莫屬, 有看到不少都是 Byword + Marked 組合搭配使用。個人是習慣所有文件與工作日誌都放在 Scrivener, 因為分門別類/關聯/搜尋/輸出都便利。檔案編寫原本用 BBEdit, 正試用 Byword + Marked。另外 nvALTSimplenote 同步的特性, 方便文件跨平台與透過瀏覽器分享, 也置入工作流程中 …

2011/04/28

一種應用源碼管理的實作

這是之前 應用系統的版本管理 一文的實作, 目的是開源應用系統的版本管理。嘗試解決應用系統的客製化部份, 除了快速跟隨主要版本的提升, 同時也方便系統的繁殖 ... 預防天災(?)

這裡以 OFBiz r1096871 為例, 檔案有 {java:1436, xml:2626, groovy:454, properties:103, js:451, css:101, jar:391}, 它一直保持在更新的 狀態

面對必要的客製化, 過去常用上游分支 (vender branch) 手法處理, 以固定目錄版本管理為主, 實務上要面對許多細節。現在流行的分散式版本管理, 加上 rebase 大大改善舊有的方式。但分支有版本相依的特性, 而 OFBiz 的版本存檔 (snapshot) 就有 215mb 之譜 ... 要保存和轉移都負擔。

利用補丁管理(Patch Management)是不錯的主意, Mercurial 的 MQ 到 1.8 已經相當成熟。唯一問題是 OFBiz 使用 Apache 官方版本管理 Subversion, 由於版本存檔太大導致 hg-svn 掛點, 不得不生出對策。

因此, 題目變成上游是 svn (原本用 git, 簡化問題還是用 svn 示範), 實際處理用 hg 加 mq。

以自己流通的 mq 版本存檔為例, 大小約 100kb 左右(zip), svn 與對應 hg 則依需要而建。在 hg 功能的協助下, 能快速跟隨 trunk 版本更新, 而 mq 存檔小也利於保存和繁殖。(OFBiz 的 mq 範例放在 bitbucket )

但是實際運作起來, 操作有些瑣碎, 對象也繁多 ... 還好有 Fabric 加持簡化成三種操作, 得以省略一堆指令。

三種操作

  1. 初始 (init)
    拿到 mq 存檔, 加上 OFBiz Apache 上的 zip 檔 (附帶 .svn)。先把 OFBiz zip 檔解開有了 svn 儲存庫 (repository), 再更新與 mq 相同的 svn rev. 版本, 接著複製到 hg 儲存庫。

  2. 更新 (update)
    因應上游 trunk 更新, 把 svn 儲存庫與上游同步, 再更新 hg 儲存庫, 最後把 mq 做 rebase 處理。需要留意 OFBiz 會更新 *jar, 是不在 svn diff 服務範圍, 得由外部 diff 助拳。而後, 視情況對 mq 進行提交 (mqcommit), 或上送(mqpush)。

  3. mq變更 (mqpull)
    上游版本變更與驗證已完成, 並上送 bitbucket (第二個操作)。這時要對運作端進行更新, 先把新的 mq 取下, 依據新 mq 更新 svn 儲存庫, 同時更新對應 hg 儲存庫。


一般使用只要用 初始mq變更 就能保持版本換新, 僅在開發與測試需要 更新(mq commit/push) 的機制。

常見方式是: 只有開發與測試使用版本管理工具, 運作端用 rsync 之類工具同步, 符合標準 開發,
測試, 正式環境 分階段的開發週期。

用 svn-hg-mq 的好處是可從容面對應用系統會遇到的因地制宜 ... 如果不時在 正式環境 被要求改一點顯示文字或邏輯, 用此法就放手去改。然後以 mq commit 保存差異並列管, 之後再看看要怎麼處理, 同時也可放心進行上游版本更新(如果有的話)。

假使開發語言單一, 系統規模在一定範圍之內, 人力還是可以處理。而像 OFBiz 有 java, xml, groovy, ... 子系統多, 關連又盤根錯節, 就最好有固定的方式處理。

實際操作

在 OS X 10.6 + macports 與 Ubuntu 10.10 測試過。

要有 gcc, python, virtualenv, apple/sun jdk 6 (openjdk 6 還是無法使用 OFBiz)。因為 mercurial 1.8 和 fabric 1.0.1 都要用新版, 習慣用 virtualenv 來建, 這時得有 gcc 相關工具備著。


環境建立:
@ /w/proj
$ virutalenv --no-site-packages fab
$ cd fab
$ source bin/activate
(fab) $ pip install mercurial
...
(fab) $ pip install fabric
...
(fab) $ curl -O https://bitbucket.org/tcc/ofbiz-util/raw/38e378fef189/fabfile.py


準備 ~/.hgrc:
[ui]
username = jia@side.org
[extensions]
pager = 
hgext.mq = 
[pager]
pager = LESS='FSRX' less

注意 username, pager, mq 都要有 ... fabfile.py 會用到。


執行:
假設主要目錄是 /w/proj/fab/ofbiz, 會在下面自動建立 svn/, hg/, zip/ 三個目錄 ...
  1. svn/ 目錄為 svn 儲存庫, 和遠端 svn 同步。
  2. hg/ 目錄為 hg 儲存庫, 用來執行應用系統。和本地 svn/ 同步, 並且以 hg-mq 進行客製化處理。
  3. zip/ 目錄存放 ofbiz-trunk-current.zip 檔案, 只在 "初始" 步驟有用, 之後可刪除。
  • 進行初始儲存庫:
    @ /w/proj/fab
    $ source bin/activate
    (fab) $ fab init:/w/proj/fab/ofbiz
    ...
    就會進行, 由於部份操作挺費時間, 或須備妥網路, 像下載 ofbiz-trunk-current.zip 會停下來詢問, 若要執行到底:
    (fab) $ fab init:/w/proj/fab/ofbiz,auto=Y
    ...
    加上參數 auto=Y 即可。
  • 當 mq@bitbucket 有新版本要更新:
    (fab) $ fab mqpull:/w/proj/fab/ofbiz,sync=Y
    ...
    若沒有 sync=Y 就得手動進行 sync:
    (fab) $ fab sync:/w/proj/fab/ofbiz
    ...
目前 mq@bitbucket 沒有開放更新, 得自行建立 mq repository ... 修改 fabfile.py:
  1. 註解第 31 列 hg_mq_url = 'https://bitbucket.org/tcc/ofbiz-mq'。
  2. 打開第 32 列 hg_mq_url = 'file:///w/proj/ofbiz/mq2' 做必要修改。
然後與 trunk@OFBiz 同步:
(fab) $ fab update:/w/proj/fab/ofbiz
...
接著提交寫入, 並上送:
(fab) $ fab mqcommit:/w/proj/fab/ofbiz,push=Y
...
若沒下 push=Y, 要手動進行上送:
(fab) $ fab mqpush:/w/proj/fab/ofbiz
...

全部操作就這樣了。

建置 OFBiz 前先置入 hg-mq:
@/w/proj/fab/ofbiz/hg
(fab) $ hg qpush -a
...

然後按 OFBiz 安裝進行:
(fab) $ ./ant clean-all
...
(fab) $ ./ant run-install-extseed
...
(fab) $ ./ant create-admin-user-login
...
(fab) $ ./startofbiz.sh

...

如果要建立另一份系統做開發, 把目錄 /w/proj/fab/ofbiz/ 改為其他的, 例如 /w/proj/yi/side/ ... 依據客製 hg-mq 很快就能建立一套新的應用系統。不用辛辛苦苦裝完系統, 再逐一做客製相關設定。

試試看, 或許有更好的做法 :)

2011/04/20

oXygen XML 中文 PDF 輸出

一直用 oXygen 編輯器來處理 XML 相關檔案, 後來發覺寫文件的功能日益強大, 但輸出 PDF 有些障礙。也不是太大問題, 需要一些設定, 這裡的說明將包含 FO, Docbook, DITA。此外, 索引方面以 DITA 輸出為例, 示範更換 FO 處理器為 XEP 個人版。

以下環境是 OS X 10.6 加上 oXygen XML Editor 12.1。 請留意檔案位置, Windows 下注意 TTF 檔的差異。

另外, FO, Docbook, DITA 都有自由軟體套件, 協助編寫文件, 沒有 oXygen 編輯器也能運作。

FO 設定

  1. 產生字型規格檔, 參考: http://xmlgraphics.apache.org/fop/0.95/fonts.html

    假定把 FOP 1.0 安裝在 /w/j/x/fop-1.0 目錄。執行下列指令, 產生字型規格檔:

    $ export CL=/w/j/x/fop-1.0/build/fop.jar:/w/j/x/fop-1.0/lib/avalon-\
    framework.jar:/w/j/x/fop-1.0/lib/commons-logging.jar:/w/j/x/fop-\
    1.0/lib/commons-io.jar
    $ java -cp $CL org.apache.fop.fonts.apps.TTFReader \
    /Library/Fonts/Arial\ Unicode.ttf ArialUnicode.xml

    產生 ArialUnicode.xml, 放在 /w/proj/xml/fo/ArialUnicode.xml

  2. 建立 FOP 設定檔 userconfig.xml, 放在 /w/proj/xml/fo/userconfig.xml

    <fop version="1.0">
      <base>.</base>
      <renderers>
        <renderer mime="application/pdf">
          <filterList>
            <value>flate</value>
          </filterList>
          <fonts>
            <font metrics-url="file:///w/proj/xml/fo/ArialUnicode.xml" 
                embed-url="file:///Library/Fonts/Arial Unicode.ttf"
                kerning="yes">
              <font-triplet name="ArialUnicodeMS" style="normal"
               weight="normal"/>
              <font-triplet name="ArialUnicodeMS" style="normal"
               weight="bold"/>
              <font-triplet name="ArialUnicodeMS" style="italic"
               weight="normal"/>
              <font-triplet name="ArialUnicodeMS" style="italic"
               weight="bold"/>
              <font-triplet name="any" style="normal" weight="normal"/>
              <font-triplet name="any" style="normal" weight="bold"/>
            </font>
          </fonts>
        </renderer>
      </renderers>
      </fop>

    其中字型名稱 name="ArialUnicodeMS" 從 /w/proj/xml/fo/ArialUnicode.xml 裡頭的名稱參考而來。

  3. 修改 oXygen 設定 Preferences ➠ XML ➠ XSLT-FO-XQuery ➠ XQuery ➠ FO Processors

    找到 Configure file 項目改為 /w/proj/xml/fo/userconfig.xml

中文 FO 測試

  1. 編修原 oxygen/samples/fo/Miscellances/helloWorld.fo 改為 helloWorld-u8.fo:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Example from: http://www.renderx.net
      Copyright © 2004 RenderX, Inc.-->
    <fo:root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="my-page">
          <fo:region-body margin="1in"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="my-page">
        <fo:flow flow-name="xsl-region-body" font-family="ArialUnicodeMS">
          <fo:block>Hello, world! 大家好!</fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  2. 產生 PDF: 選單 Document ➠ Transformation ➠ Apply Transformation Senario 產生。

    或按 cmd + shift + T, 選擇 PDF (第一次要選 FO PDF)。

Docbook 設定

做妥上面 FO 設定。修改 oxygen/frameworks/docbook/xsl/fo/docbook_custom.xsl 在 </xsl:stylesheet> 前, <!-- end oXygen patch. --> 之後, 加上:

<!-- Traditional Chinese patch -->
<xsl:param name="body.font.family">ArialUnicodeMS</xsl:param>
<xsl:param name="body.font.size">12</xsl:param>
<xsl:param name="monospace.font.family">ArialUnicodeMS</xsl:param>
<xsl:param name="title.font.family">ArialUnicodeMS</xsl:param>
<!-- end Traditional Chinese patch -->

中文 Docbook 測試

  1. 修改 oxygen/samples/docbook/v5/sample.xml。Author 模式下, 在文字後加入中文, 例如:

    <sect1>
        <title>Inline Markup and Images 大家好</title>
  2. 產生 PDF, 同 FO 方式 ... cmd + shift + T 選擇 PDF (第一次要選 Docbook PDF)。

DITA 設定

  1. 修改 oxygen/frameworks/dita/DITA-OT/demo/fo/cfg/fo/font-mappings.xml

    找到以下字樣:

    <physical-font char-set="Simplified Chinese">
        <font-face>AdobeSongStd-Light</font-face>
    </physical-font>

    增加類似段落(共三處):

    <physical-font char-set="Traditional Chinese">
        <font-face>ArialUnicodeMS</font-face>
    </physical-font>
  2. 複製 oxygen/frameworks/dita/DITA-OT/demo/fo/cfg/fo/i18n/zh_CN.xml 成為同目下新檔 zh_TW.xml

    修改此 zh_TW.xml 內容, 把 <alphabet char-set="Simplified Chinese">...</alphabeat> 改為:

    <alphabet char-set="Traditional Chinese">
      <character-set>
        <character-range>
          <start include="yes">&#x0100;</start>
          <end include="yes">&#xff00;</end>
        </character-range>
      </character-set>
    </alphabet>

    很偷懶的方式, 需要修正。

  3. 修改 oxygen/frameworks/dita/DITA-OT/demo/fo/fop/conf/fop.xconf

    在 fop ☞ renderers ☞ renderer mime="application/pdf" ☞ fonts 下增加:

    <font metrics-url="file:///w/proj/xml/fo/ArialUnicode.xml"
        embed-url="file:///Library/Fonts/Arial Unicode.ttf" kerning="yes">
      <font-triplet name="ArialUnicodeMS" style="normal" weight="normal"/>
      <font-triplet name="ArialUnicodeMS" style="normal" weight="bold"/>
      <font-triplet name="ArialUnicodeMS" style="italic" weight="normal"/>
      <font-triplet name="ArialUnicodeMS" style="italic" weight="bold"/>
      <font-triplet name="any" style="normal" weight="normal"/>
      <font-triplet name="any" style="normal" weight="bold"/>
    </font>
  4. 建立 zh_TW 必要檔案, 在 oxygen/frameworks/dita/DITA-OT/demo/fo/cfg/common/ 下要有三個檔案:

    • index/zh_TW.xml

      複製 zh_CN.xml 修改, 先將 <language>zh-TW</language> 改為正確對應。下半部所有中文的 index.group 改為只有(也是需要修正):

      <index.group>
        <group.key>中文</group.key>
        <group.label>中文</group.label>
        <group.members>
          <char.set start-range="一" end-range="龤"/>
        </group.members>
      </index.group>
    • properties/zh_TW.properties

      chm.native.encoding=big5
      chm.project.language=0x404 Traditional Chinese
    • vars/zh_TW.xml

      複製修改, 可能必要的是 "Product Name"(顯示在 PDF 上方頁角), 其他隨意。

  5. 修改 oxygen/frameworks/dita/DITA-OT/demo/fo/build.xml 增加:

    <property name="document.locale" value="zh_TW"/>

    在 <property name="customization.dir ...> 上即可。

中文 DITA 測試

  1. 開 oxygen/dita/ 下某 DITA 專案, 開專案下的檔案在 Author 模式下修改, 增加中文字, 例如:

    <title>Changing the oil in your car 測試看看</title>
  2. 產生 PDF, 同 FO/Docbook 方式 ... cmd + shift + T 選擇 PDF (第一次要選 DITA Map PDF)。

安裝 XEP 個人版

FOP 1.0 還不支援索引(indexing)功能, 請參考 http://xmlgraphics.apache.org/fop/compliance.html#fo-object-indexing-section

XEP 個人版非商業用可取代 FOP 產生索引 http://www.renderx.com/download/personal.html

  1. 下載, 安裝到 /w/j/x/XEP/。

  2. 修改 /w/j/x/XEP/xep.xml 增加 (搜尋到 font-group):

    <font-group xml:base="file:/Users/tcchou/Library/Fonts/"
        label="Windows TrueType" embed="true" subset="true"> 
      <font-family name="ArialUnicodeMS">
        <font><font-data ttf="Arial Unicode.ttf"/></font>
      </font-family>
    </font-group>

    把 Arial Unicode.ttf 複製到個人字型目錄, 因為還有其他字型 ...

  3. oxygen 增加 XEP

    Preferences ➠ XML ➠ XSLT-FO-XQuery ➠ XQuery ➠ FO Processors

    點選 "If you have a custom XEP installation ..." 旁的 Browse 按鈕, 選擇 /w/j/x/XEP/xep 。

  4. 點選 "Configure Transformation Scenario", Duplicate "DITA Map PDF" 選擇 Processor: XEP 。

  5. 選擇 DITA 下專案(it-book 有 indexing 範例), 產生 PDF ... cmd + shift + T 。

2011/03/28

OSDC.TW Tabledown 演講資料與問答

週日(27) 在 OSDC.TW Tabledown 演講的投影片:


利用一些時間把範例整理上傳到 Google code

除了把 Tabledown 修完, 有個 pip 的 req. 檔案能協助把演講提到的 twill, scotch, mechanize, Beautiful Soup, Tabledown 都給裝妥。先將 python, pip 裝完, 接著再參考 00README.txt。

範例要執行, 可能有困難的地方是將 OFBiz 裝起來。而 User 的 Id 預設為數值累加, 不太方便。附上一個修補使 Id 能和 UserName 相同 (試過今天的 trunk)。得事先裝好 Java 6, 接下來再花些時間建系統 ... 有問題的話也請提出 :-)

另外, 把當天遇到的 Q & A 整理如下:
  1. 在某頁從資料庫到試算表的做法為何?
    ⇒ 投影片的試算表是以 "人" 的角度建立資料表達的方式, 都是手工建立的。僅示範從試算表到 Web App 單向, 主要是跨越資料關連,多個畫面,細節這些煩瑣與難度。從資料庫到試算表要自動達成更接近人需要的, 應該是另一個題目。
  2. 如何執行?
    ⇒ 目前範例都是寫死的, 在命令列下執行 XD 日後考慮有無更彈性的做法, 像提供 plugin, 只要準備好試算表加上 plugin 就能處理妥。
  3. 接受的試算表格式? 雲端?
    ⇒ 目前沒有能力處理雲端試算表, 只有 python-excel 專案能接受的 .xls 檔案。
  4. 能否即時執行, 和後端同步?
    ⇒ 範例中時間表(Timesheet)有想過直接與 Web App 同步, 有點這種味道? 但要考量資料同步問題 … 沒直覺的解法, 暫時擱著。([事後] 先解 Q1 問題, 再為 collections 做 diff, 或許類似 git snapshot 做法)
  5. 問題加密 (POS?) … 和 Td 無關, 所以加密 XD
    ⇒ 回覆加密 (POS!)
  6. 範例中 Master 與 Detail 關連?
    ⇒ 簡單版: 沒有關連; 真相版: Master 是鍵值式資料, Detail 是條列式資料 … 原則上都可以多個。而資料的關連由開發者(程式)決定, 例如在專案 Master 有人員 ID 以逗號隔開, 實際上在專案資源畫面有多筆資料。
後來看了 sleepnova 推薦的 Prezi, 另外想到試算表與 XML, Json, Yaml, … 相比, 雖然個個都能記錄資料, 但使用者愛用的原因, 該是較能掌握東西放在哪裡, 即使只有列和行。

感謝四方大德惠予討論, 也謝謝 hcchien 與 OSDC.TW 工作人員的辛勞 :-)

2011/02/18

開放源碼資訊應用系統的開發觀點

資訊應用系統較開放的定義: 公司、組織所需要的應用系統, 下面縮減為企業應用(Ent App), 與當下常見移動 (Mobile) 和 Web 應用有所區別。開放源碼顧名思義即可。身處在公司組織中, 資訊系統所涵蓋的可能是有什麼用什麼, 或依需要採買。企業應用則依公司組織的需求, 所打造的應用 … 有些是獨立系統, 或某個系統的擴充。常要與不同單位, 甚至跨公司組織的各系統聯繫以協同作業。

去年 2010 接觸一個國外頗具規模組織的企業方案導入, 從基礎設施開始到應用系統的那種。儘管方案已落入 M 社手中, 仍有許多可深入思考借鏡之處。

這個需要方案的組織, 雖然考慮過開放源碼方案, 對技術有想像, 對未來有憧憬, 最後還是回到踏實的 … 支援問題。

按捺支援問題, 整理過程中一些溝通討論的部份。

從頭開始的組織, 討論的觀點有多高? 大概有太空那麼高。平常較常用的辭彙字眼, 鮮少在此時派上用場。與非開發者進行討論, 還是得用流行 … 呃, 太空的觀點來溝通, 也難怪不斷有人創造一些東西來滿足。在其中討論的議題有目錄服務, 檔案分享搜尋, 管理監控, 入口網站, 工作流程, 應用系統, … 等。前三個題目, 一般公司組織都給 M 社綁住, 接下來似乎 M 社都把東西都準備好, 都可一次夠足儘管用。

曾被詢問: 如果不用 M 社方案, 這些問題如何解? 兜幾家公司產品才解決又沒參考案例, 說服力自動下降。能否找到適當資源滿足這些要求, 就成了給自己的寒假作業。

選擇以 Java, Python 為基礎, 避免對作業系統的依賴太深。

把問題劃分幾個區塊, 否則以系統/應用分太簡略, 純以開發觀點來看又太複雜:

  • 應用系統: 這是已經存在並使用的應用。ERP, B2B, 入口網站, 網購平台, 生產系統, … 甚是以套件存在的論壇, 而開發成果也在此區塊。
  • 基礎系統: 不需要應用也存在的系統。例如電子郵件, 資料庫, 網站網路服務(Web/FTP), …。
  • 工具: 基本上是支援開發相關工具。像源碼的版本管理, 記錄工作的事例追蹤, 負責測試建置, 文件產生, 資料處理, …
  • 開發作業: 可以是獨立的應用, 但通常除了基礎系統, 也與其他應用系統打交道。現在複雜環境, 選適當語言外, 更需要適當框架加持。

這些區塊的涵蓋面是否恰當, 以流行的 Web 框架來檢視: 資料庫/網站在基礎系統; 編輯器/版本管理在工具區; 開發框架本身在開發作業區; 如果套在入口網站裡, 就看成在應用系統區。

再來把之前討論議題在放進來:
  • 目錄服務: 有名的 OpenLDAP 使用過一陣子, 那時要編得安全一點不太容易。現在 ApacheDS, 有 Java 環境就能很快上手。雖沒 M 社搭配其作業系統的特異功能, 但具備 Kerberos, DNS, NTP, DHCP。另有 Directory Studio 處理綱目和資料都便利, 而單一簽入(SSO)可交給 CAS 處理或 PicketBox。這些放到基礎系統區。
  • 檔案分享搜尋: 從歷史來看, M 社把之前拳王 N 社撂倒後就一直雄據著, 不過移動設備和 Web 普及應該稍有機會推動一下這板塊 … 內容管理交互服務(CMIS)。實作不少, 偏好的是 Nuxeo, 實際選擇視需求而定。也放到基礎系統區。
  • 管理監控: 之前做都是一兩個系統加上數個服務, 要求是把自己做的管好就好, 沒從組織觀點來看。這方面有許多成熟產品, 例如 SpringSurce 有併入 Hyperic。會考慮的是 Zenoss, 畢竟現在有各式各樣服務, 彈性大一些會比較好。而 Java 在開發作業考量與 Zenoss 搭配, 執行記錄方面從 log4j 著手走 syslog 即可。還是放到基礎系統區。
  • 入口網站: 已經流行過好一陣子的題目, 或許每個人都有自己的一套, 就略過。分類的話, 由於依使用方式不同而有差異, 所以放應用系統區。
  • 工作流程: 推薦的是原 jBPM 開發人員從 jBoss 離開, 在 Alfresco 支持下做的 Activiti 專案。從 2010 年底釋出 5.0 以來, 2011 的前兩個月都按表操課, 穩定釋出新版本 5.1, 5.2。具備彈性流程工具外, 比較特別的是考慮開發人員甘苦, 不會一昧討好商務端人員。Activiti 可考慮嵌入與應用共存, 但從服務獨立、聯合管理的角度, 應該是單獨存在的系統, 因此放到基礎系統區。
  • 應用系統: 從開發觀點來看, 只要一個語言就可做任何事, 然而任何人能完成的事情都是有限。現成開源應用系統也不少(ERP, CRM), 加上在雲端的就更多。但能否存活, 像後者在 2010 收了好幾家, 特別讓人有疑慮。因此期望把關鍵資料放在自己可以掌握的地方, 彈性/好用是必需的, 但也不會因為開發專案的公司策略調整或併購而影響。因此選擇 OFBiz 來擔任企業核心的應用系統。

回頭看各區塊, 應用系統依實際狀況而定, 基礎系統補上即時訊息(IM) Openfire 做即時通訊, 另外以通用伺服器 Felix, Karaf, Camel, ServiceMix 統籌日漸增長的服務。工具區塊比較被熟悉, 也常見許多討論個人、團體開發過程中面對的問題與解決方式。這裡對之前 近未來 IT 開發 一文做補充, 成為開發作業區塊:
  • 穩定層: 包含應用系統與基礎系統, 有穩定的界面。例如 ERP 財務的界面, 或像檔案傳輸的方式也固定。
  • 動態層: 原本以樣板打造動態層, 要含括一般且普遍的情況下, 得選用框架。以 Web 來說, 會用 Grails, 他和原本 Java 與企業大宗資源 DB 溝通方式非常的 … 一脈相承, 能快速且彈性建立 Web 應用或服務。在 Web 應用方面, 加上 ZK 協助能使用先進的 Web 技術, 卻毋需太煩惱衍生的問題。而面對複雜的服務與模組, 有更強力的 Scala/Akka 組合以函數編程與靜態語言協助建立穩定的服務。
  • 領域層: 有了上面分門別類的區塊提供各式的服務, 接下來在 grails 與 akka 下, 開發領域相關的東西。

整理如下圖:

歡迎指教與補充。 :)

參考連結:

2011/01/09

Tabledown

目前資訊技術兩股趨勢: 一個是普及的行動設備, 一個是數大的雲端計算。在兩者激盪之下, 各種應用遍地開發。從 TIOBE 索引排名, 以及陸續開張的軟體商店, 就可看出百家(?)爭鳴, 且各家皆各自擁有龐大的支持群眾。

普及的行動設備會演變成為一個人擁有多個設備, 但不連線(不連續)就會造成的問題。Dropbox 解決了檔案問題, 讓檔案同步因此大受歡迎。而雲端運算到後面各個服務的連結也會造成不連續, 簡單舉例: 金流可連續完成, 但物流就不可能。

從結果來推論需求, 如果生產, 金流, 物流都上雲端了, 那在手上(設備)要掌握什麼資訊?
(嗯 … 產品的規劃設計是另一件事。)

要掌握的資訊, 可能人人不同, 也可能隨客戶的客戶而不同(B2B)。

雖然流行的腳本語言(Scripting)能因應快速的變更, 大部分時候在程式碼與資料間是有清楚的界線。這個界線是 … 使用者(或客戶)非常在意資料, 而程式員則關注程式碼。即便可選擇的開發工具很多, 也都很強大, 但幾乎是建立 MVC 下, 類似 rails 模式, 或者是說與資料庫關係密切, 這些都屬於連線(連續)的形式。

最好能夠做到『碼即資料, 資料即碼』(code is data, data is code), 由使用者在掌握資料即能驅動後頭的雲端, 即使不連接也可讓服務運作下去。

不論如何, 資料還是需要載體(Container), 最好的載體應該是試算表。它除了能放置資料, 還能兼顧人們視覺操作的慣性, 可將資料的顯示位置, 存在與否, 還有排列做調整。如果沒有應用程式, 這種方式應該是首屈一指的資料載體。

主角都現身, 可想像一下: 透過試算表來連接各種後端的服務(雲端)。資訊服務業能透過試算表輸入資料(例如使用者需求), 再批次進入報價服務, 每月產生報價單寄送給客戶。至於損溢, 現金流量, 庫存也可定時同步到試算表 … 並竟不是每個人都每秒十萬上下。

基於這樣的出發點, 建立了 Tabledown 專案。簡單來說, 是能夠讓試算表與集合資料(lists, hashes)做雙向資料交換, 透過一個對映集合設定(mapping collections configuration, MCC)來轉換。

已完成的是概念雛形的驗證, 就是在 google code 頁面的範例。陸續會做一些修正, 使用雲端試算表, 以及與 ERP, BPM 連接。

Tabledown 目前是組 Python 的程式庫, 希望有機會改頭換面成為一般工具。而 Tabledown 命名的點子是從 Markdown 而來。



參考

2010/11/27

OFBiz 完全中文安裝教學

OFBiz 是 ERP, CRM, eCommerce, SCM, MRP, … 以 Apache 授權的企業自動化軟體。之前可能不太容易上手, 一方面這種軟體需要關注的層面太多, 另一方面沒有中文化(有簡體中文)。

以上在這兩週有些改變。上週(11/18) Bakker 先生提供了快速設定的方式(r1036323), 包含: 公司, 倉儲, 商店, 電子商務網站, 第一位客戶, 第一筆產品 … 只要走過幾個 Web 畫面就可完成 OFBiz 基本資料設定。而這週中文化進入 trunk (r1039574), 應該能降低語言的隔閡。

大部分這類軟體要設定 網站伺服器,資料庫以及系統本身。而 OFBiz 由於 Java 語言的優勢, 嵌入了網站伺服器與資料庫, 只要一個指令就可啟動, 假使需要也可用常見的網站伺服器或資料庫替代。除了降低入門門檻, 同時也具備擴充性。

更多的 OFBiz 介紹可參考: 什麼是 OFBiz, 專案概觀 (各模組介紹), OFBiz 適合我嗎?

下面把 OFBiz 在 Windows 完整安裝過程 (從下載檔案開始), 包含必要的修正, 並簡單示範了銷貨訂單, 採購訂單的建立與使用 … 做成影片放到 Youtube 頻道中 ... OFBiz 線上教學

2010/11/13

應用開發的簡化

容易的方式

雖然常把實用新穎的技術簡化, 想辦法放入既有系統中, 讓夥伴、客戶都能上手使用, 但現實中卻還是不夠。

前幾天幫客戶除錯, 看問題時, 才知道他們做了什麼 … 有點類似 Web Services (偽), 卻是用 PHP。他們在生產過程中, 要把某個事件記錄在另一個資料庫。當然用 PHP 沒什麼問題, 只是把所有執行相關工作都寫在一個檔案裡頭的做法, 很明顯是從書上抄下來的範例, 再改一改的成果。

對許多人來說, 書上有類似的範例, 能照本宣科就拿來用就好。這大概是某些語言長年佔據 排行榜 的原因, 但時至今日這股『只要能動』的風潮漸漸改變。在 Web 時代大部分拿 SQL 就直接用, 到了 Web Services 時代, 分工愈來愈細, 要求愈來愈多, 許多程式的運作都以物件為基礎。並非談物件的優劣, 而是評估現實中若使用物件比 SQL 方便, 比如資料的呈現(xml, json), 處理(鷹架), 以及檢核這些作業, 自然而然趨勢也跟著改變。

這裡還有一個關鍵點, 以上面出問題的 PHP 來說, 不管怎樣只要一個檔案就做完收工。原有系統在程式方面雖然也能簡單做到, 但要連到他們內部使用的資料庫(MySQL)這種配置就不太容易。因為原系統採 N 階層架構, 要多接個資料庫, 雖然可做到, 但得更動不少層。
或許從仿 PHP 單一檔案開發起個頭, 比較容易些。

簡單的實現

PHP 帶領 LAMP 的風潮, 在 約定優於配置 之前, 受到許多開發人員喜愛。著重四個方面: 簡單編寫, 簡單散佈, 本機開發, 便宜且到處可託管。除了最後一個外, 前三項直接讓開發的人獲得好處。預設與 MySQL 搭配(以 5.3.3 來說, 還有 PostgreSQL, Oracel, Sqlite), 因此只要資料庫能夠運作, 程式就能寫, 能動, 能測。程式執行後, 也能立即從資料庫看看結果是否正確。

再複雜些的系統, 除了語言本身, 還得準備更多暖身課程。

在今天之前, 也一直覺得 PHP 劃下簡單的境界, 是無法挑戰的。原本的 Groovy 知識, 只想做到很接近, 但查了查資料, 發現結果還不錯。

前提是有個 MySQL 在正常運作, 假設有資料庫 mydb 以及表格 mytbl 如下:
simp_mysql.png

有兩欄(name, tel), 以及兩列資料。

先確定裝妥 JDK 1.6 以上版本, 再到 Groovy 首頁 下載 1.7 之後版本, 然後執行 bin/ 目錄下的 groovyConsole 能直接寫程式。

拷貝、貼上程式碼:


@Grapes([
@Grab('mysql:mysql-connector-java:5.1.13'),
@GrabConfig(systemClassLoader=true)
])
import groovy.sql.Sql

def dbUrl="jdbc:mysql://localhost/mydb?useUnicode=yes&characterEncoding=UTF-8"
def driverClass="com.mysql.jdbc.Driver"
def sql=Sql.newInstance(dbUrl,"root","root",driverClass)
sql.eachRow("select * from mytbl") {
println it
}


注意, 資料庫位置 localhost, 名稱 mydb, 帳號/密碼 root/root, 還有表格名稱 mytbl 可能需要置換。然後選擇執行, 可用工具列右邊屬來第二個圖示, 或選單裡頭 Script/Run。第一次可能久一點, 因為缺少連接 db 的程式庫(不像 PHP 有附加), 要花些時間下載, 之後就正常。LAMP 要義的第一項簡單編寫, 第三項本機開發, 可順利達成。整個結果, 應該和下圖差不多:
simp_groovy.png

除了讀取資料庫, 其它新增、更新、刪除的 SQL 也都有, 請參考 Groovy SQL。確定沒問題, 就存檔保留。

不過這時候或許有人會問: PHP 在命令列(command line)下執行很快的, Groovy 那能比? 那請試試 GroovyServ, 雖然有點作弊, 但就像 IE 比其他瀏覽器快, Office 比其他工具快, 差不多就是那種的方式 …

換不同資料庫, 應該只要改上面截圖中第 2 列程式庫, 第 7 列連接資料庫網址, 第 8 列資料庫套件名稱, 可能再加上第 9 列的帳號、密號, 其它步驟類推即可。

以上示範, 算真正的單一檔案寫完收工, 也簡單到少有的地步。

那放到網站是否很複雜?

在 Java 使用 Tomcat 會比 LAMP 中 Apache 容易。相同方式 tomcat 5, 6, 7 版本可通用, 這裡以 tomcat 6.0.29 示範。下載後解開, 把長長的目錄改為 tomcat6/。

在 tomcat6/ 下的 webapps/ 裡頭建 groovy/ 目錄, 再建 WEB-INF/。

把 Groovy 1.7 的 lib/ 複製到 WEB-INF/ 裡頭。

在 WEB-INF/ 增加 web.xml 檔案, 內容如下:


<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<display-name>Groovy Web Apps</display-name>

<servlet>
<servlet-name>Groovy</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Groovy</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>
</web-app>


而把上面讀取資料庫的 groovy 程式, 前幾列 @Grab 改一些 (有點尷尬, 之前寫法在 Web 不能用), 不過下列是通用的。(日後應該會針對此點修補 @Grab 才是)


ClassLoader.systemClassLoader.class.name = 'groovy.lang.GroovyClassLoader'
groovy.grape.Grape.grab(classLoader:ClassLoader.systemClassLoader
,group:'mysql', artifact:'mysql-connector-java', version:'5.1.13')
import groovy.sql.Sql

def dbUrl="jdbc:mysql://localhost/mydb?useUnicode=yes&characterEncoding=UTF-8"
def driverClass="com.mysql.jdbc.Driver"
def sql=Sql.newInstance(dbUrl,"root","root",driverClass)
sql.eachRow("select * from mytbl") {
println it
}


整個做法的結果應該和下圖相同:
simp_tomcat.png

以上方法做完, 執行 tomcat 6 … 一般用 bin/catalina.sh run 即可。

此時瀏覽器看到結果如下:
simp_web.png

單機寫完應用程式, 執行驗證完後, 隨即放上網站目錄去, LAMP 要義第二項的簡單散佈也可達陣。

簡單還要更簡單

原先想寫關於資料庫程式遷徙到 grails 的方式, 因為客戶的問題轉到另一個題目上, 與 PHP 的某種(通用?)做法比劃一下。

除此之外, 還有更積極的意義 … PHP 固然是寫資料庫和網頁程式的主流, 其相關資源可略窺一二。但 Java 連接的 IT 資源更廣泛, 像負責生產管理的 MES, 或財務處理的 AIS, 都由於加上 Groovy 的協助, 讓原本的系統有更大彈性, 也讓部份客製門檻降低, 例如一些報表、檢核的作業讓更多 IT 人員參與。可以想像一下 … 上面 SQL 資料讀入與 Web 輸出部份, 換成來自不同系統流程的資料, 以及 csv, xml, xls 或 pdf 輸出, 輔以適當的權限與稽核, 就可讓原本要獨立開發的程式變成簡單的腳本擋。

且如同 PHP 一般即改即用, 很簡單的滿足許多需求。

參考

2010/11/08

應用系統的版本管理

一段歷史

經過幾年軟體版本管理工具爆炸性的競合, 如果不考慮控制的問題, 我們可以自由選用 subversion(svn), mercurial(hg) 以及 git。svn 存在時間最早, 在有一些歷史的專案和中小公司比較常見; hg 由於簡單明確, 大型源碼社群如 sourceforge, codeplex, google code 普遍接受; 而 git 強大穩定, 則是技客首選。

這三者陸續在用, 雖然深淺各有不同, 從歷史角度來看: 最早通用的 cvs 是管理檔案版本, 所以會有 v1.0, v1.1, v1.2, ….。svn 側重整個專案版本, 標示版本以整個儲存庫為準 r123, r223, r323, … (r=revision)。大概是 cvs 時期一個檔案就可做完一件事, 到了 svn 得靠一堆檔案 … 請參考『軟體工程師的進化』一文。

到了 dvcs(hg, git) 回歸功能面管理, 版本像是 229a46966a72, 13a7d2806d50, 64d88c389b67, … 的 uuid。意義不再是檔案版本編號(v1.0), 或由儲存庫變更序號(r123)做認定。應該沒有人可從 dvcs 裡版本號碼看出任何意義。一方面在每次提交版本(commit)輔以適當註解, 而整體來看, 端視儲存庫擁有者認定版本的意義。因為是 dvcs … 只要有心, 人人都可以是儲存庫擁有者 … peace!

對一個專案來說, 針對檔案變更追蹤是過小, 像流行的 MVC (Model-View-Controller)在概念上就跨了三層。若針對儲存庫變更追蹤又太大, 變更頻繁的話, revision 就如同雪片般, 好看是好看, 但一般也只是好看。因此, dvcs 當是比較符合趨勢的選擇。

一種問題

交待完歷史, 回頭看主題。假設專案有源碼要管理, 這個應用系統是承上啟下, 也就是依據上游源碼為基礎, 提供下游客戶穩定、加強、或客製的版本。是種常見模型:
上游儲存庫 UR - Upstream Repository
我的儲存庫 MR - My Repositroy

源碼儲存庫畢竟是技術人員才會接觸到, 大部分狀況以策略解決: 有時將上游源碼設定為程式庫, 簡化問題; 或以廠商分枝(Vendor Braches)將上游源碼納入專案; 而產品類專案, 可忽略 n 個客戶問題。

但如果使用開放源碼 CMS, CRM 或 ERP 這類應用為主的系統, 上游持續加強版本, 下游因應需求不斷變更 … 會爆炸的點大概就是位居中間的儲存庫。
在網路上, 看到相關問題討論有:
  1. 非官方 hg 流程 中 Offsite working on dynamic websites。其中『Upgrading Drupal with Git』(部落格已落幕, 可參考 archive.org 資料)。
  2. 也是 drupal 開發, 教學視訊 Git With Drupal 7
  3. opentaps(ERP) 的建議 Managing Customizations with Upgrades, 大抵是分為四個層次: a. 瞭解現有的, 將異動最小化 b. 貢獻源碼, 免除版本差異, 透過社群改進 c. 獨立應用程式在特定目錄下 d. 若修改核心及社群不接受的源碼, 得注意合併問題。最末項不建議, 因容易出包。
上面第三項 "在特定目錄下" 放應用程式, 是大部分應用系統普遍的做法, 像 SugarCRM 也有類似的機制。

通常專案會設定上游的版本, 但長期提供服務, 必然會面對上游版本變更。而下游的需求, 投入行業時間夠久, 一般也會有共通方式解決, 例如提供一個檔案上傳或流程整合的功能, 應該也不希望一家處理過版本提升後, 還得要處理其他家客戶相同問題。

技術上, 沒有通用做法的話, 能抑制爆炸的源碼就大概只有爆炸的肝。(以爆制爆?)

一項解法

如果著眼於儲存庫, 所有問題都成為一團。首先區分上游變更, 與下游需求這兩個變動的來源。其他像共通功能的開發, 問題的修正, … 先納入下游需求。

再來, 如版本管理的演化(csv → svn → dvcs), 因時制宜般, 上游變更以分枝(branches)處理, 下游需求以變更佇列(patchs queue)對付, 再建立一個儲存庫負責照拂需求的變更佇列, 是為『變更儲存庫』。
變更儲存庫PR - Patch Repository
變更佇列在 git 中有外掛 stgit, quilt, 至於 hg 是內建 mq (mercurial queues)。

在手上實際 ERP 案例中, 上游儲存庫每個月大約有 800kb 左右的差異檔(diff), 而變更佇列除了中文化有 5mb 的差異檔, 其他加起來不到 300kb。每月同步上游儲存庫後, 再更新變更佇列, 也就是 UR 與 PR 會有版本對應的關係。只要 UR 與 PR 同步後, 就可一體適用其他相同系統的客戶。節省下的資源可專注差異化部份。

一方面是變更的大小與不同機制的搭配, 另一方面是變更佇列對每項修補差異的處理, 比分枝來得直覺。例如把中文化和其他修補一起放入同一個分枝中, 當上游版本更新, 要合併到分枝時, 假使自動合併無效, 要看到檔案才能處理, 同時可能也要處理 API 差異之類的。簡單來說, 就是要有經驗的工程師才能處理版本合併的事務。如果是以變更佇列處理的規劃, 就很方便分工, 中文化部份安排通中/英文, 細心的工程助理打點即可。

參考

2010/08/31

Bonjour 你好

Bonjour蘋果zeroconf 免設定網路產品, 協助使用者更容易用網路。

雖然 Bonjour 與 zerconf 目標是各種網路服務, 這裡的範圍限制在網頁。免設定網路目前解決三個問題: 設備(名稱)的IP(網路位置)指定, 自動取得名稱與IP關連(廣播法 mDNS), 自動取得網路服務(dns-sd)。

技術上有點繞口, 實務上就如同一個 Wiki 工具 Voodoo Pad 寫妥許多內容, 要分享只要點選 Start 按鈕:
voodoopad_web.png

其他人利用 Safari 的書籤頁就可以看到:
safari_bonjour.png

不用網址、埠號、目錄, 看到名稱點下去, 立即瀏覽網頁。

除 Safari 外, Firefox 的 BonjourFoxy Plug-in 有相同功能, 目前支援 Windows 與 OSX。(Windows 安裝前須先裝妥 Apple Bonjour 套件)
bonjourfoxy.png

BonjourFoxy 另附有 Bonjour Browser 可觀察 dns-sd 詳細內容:
bonjour_browse.png

寫到這裡都是使用者操作面上。手上也有許多各式各樣網頁, 是否能建立 Bonjour 項目瀏覽資料?

最簡單方法大概利用 OSX 中 /usr/bin/dns-sd (Bonjour 套件) 在 Terminal 下指令:

$ dns-sd -R "Plone" _http._tcp "" 7070 "Plone 4 Here"

會佔住 Terminal, 要結束就直接按 ctrl-C。

dns-sd 除了為本機建立 Bonjour 服務項目, 也可代理(Proxy):

$ dns-sd -P "Zoo Keeper" _http._tcp local 80 hadoop.apache.org "" path=/zookeeper "你好 Zoo Keeper"

注意 path 可指定 URL 主機、埠號後的部份。

分享網址除了剪貼、美味書籤、社群工具, Bonjour 也是個方式, 而且是立即的。