用Git會行既flow

[Git][今日望緊d用Git會行既flow有少少想法,歡迎指正]

尋日同事講起Git Flow,所以我今日都睇左睇

Git Flow:
http://nvie.com/posts/a-successful-git-branching-model/

簡單講就係:
1) 有條master branch但永遠只做merge不會直接commit change。
2) 有條long-live既Dev branch專做integration (CI)。
3) 所有change feature都由dev branch開branch去做,做完merge返去dev。
4) dev既changes做到咁上下就分支出一條release branch (RC)。
5) release branch冇乜問題confirm左ok就merge返去master。
6) long live既永遠只係得1條master同1條dev branch。
我講完都係講到一舊舊,所以你最好都係睇返條link入面張圖同d解釋比較好。

不過我覺得會有個問題就係,
佢有個assumption係dev既changes係一定要eventually做到stable之後出release merge返去master。
而個問題係,現實中好多project既release過程都係dev做做下時adhoc加減features。
加feature就冇乜問題,咪開多條branch做完咪merge。
但減feature可能比較麻煩,例如當某feature做完後merge左落dev,但依個時候又話唔要include依個feature咁點?

我諗到可能有幾個workaround:
(1) rebase/reset攪
(2) 人手reverse返果個features既changes
(3) 出release時cherry-pick淨係揀要出既feature先出release & merge去master
(4) 唔會remove feature,會照release merge去master,但會用feature toggle去disable相關feature

而幾種做法都分別有佢地各自既drawbacks。
(1):會攪一大輪野比較麻煩,同埋如果decentralized既repo之間可能會有branch conflict問題未必攪到
(2):勁核突夾硬黎
(3):唔出release果個feature留左o係dev但又唔知點,會唔會過左段時間之後冇左回事?
(4):feature toggle本身其實係technical debt,積住d feature toggle o係code base入面會影響到software本身quality

———————————————————————————

後黎我睇到有人講另一種flow model (2012年sosad)

Another Git branching model

我覺得依種flow好似比較better handle adhoc feature加減既問題。

簡單講就係:
1) 有條master branch但永遠只做merge不會直接commit change。
2) 所有feature branch都由master分支出黎。
3) 有一條integration branch,所有feature branch定時定侯都會merge落integration branch做CI。但同Git Flow唔同既係依條branch永遠唔會merge返轉頭,純粹CI。
4) 有一條staging branch。所有準備出release既feature ready後都會merge去staging。staging ready for release就merge返去master出release。呢條branch係RC branch。

佢本身個model似係long live既branch係master﹑integration﹑staging。
如果我冇理解錯,其實本身就咁依個model都未必handle到adhoc加減feature。
但我覺得可以改一改:
1) for出某個release,可以有一個for果個release既integration branch做staging
2) 當要adhoc減features時,可以dump左原本條integration branch,然後再開過另一條integration branch,merge返新requirement需要既feature落去。
3) 同樣地,等staging ready就release去maste。
4) Integration branch由於乜垃圾都pack晒入去,但唔會remove垃圾亦唔會merge back,所以耐左都係變垃圾站。所以同樣地,可以隔一排就dump左原本條integration,開過條新既integration branch。

我覺得咁樣既model好似比較好,因為:
1) 開branch/dump branch對git黎講其實rather non-expensive。
2) adhoc加減個case時,唔駛cherry pick/rebase。
3) 今次冇release到既feature可以唔駛鏟,照獨立keep住先,等將來先再merge/dump。

———————————————————————————

other references:
http://dymitruk.com/blog/2012/02/05/branch-per-feature/

#個人理解 #如果有錯請指正 #need_validation

Java紫微斗數排盤open source library

其實我一早就想把Fortel的core部份open source的了,不過現在才比較有空整理一下project,寫一點test case及doc。

Github: https://github.com/airicyu/Fortel

 

Fortel

Java紫微斗數排盤Library

Author: Eric Yu


Samples

排盤

排盤:一九五二年十二月十五日早子時天盤,男性

JSON Output(Formatted):


檢查宮垣

排盤:一九九零年三月十一日午時地盤,男性

檢查命盤命宮是否: 會見廉貞, 並且同時”天魁或天鉞同宮”或”不見化忌”

Output:


檢查命盤命宮是否: 會見廉貞, 並且同時”天魁或天鉞同宮”或”不見化忌”

Output:


JavaDoc:

You can view the Javadoc page at “\fortelcore\javadoc\index.html”

關於machine learn/AI智能發展趨勢的一些看法

其實直至現時,最勁的machine learn都只是能機械式處理分類﹑predict類問題,machine learn/AI本身沒有邏輯推理能力。
它靠的就是算法與強大運算能力去分析probability,但不是歸納式邏輯。
而人類還有著歸納式邏輯能力,而機械沒有這能力,這是目前來說machine learn/AI的bottleneck,而這也是人類面對AI浪潮下暫時的少數立足點。

尋日見到d slide的infographic,講machine learn之類的智能能力(唔記得個exact wording係乜)估算,條curve 2020年exponentially爆到上唔知邊度。
但graph/curve反映了什麼?智能的能力究竟是什麼?

簡單地看問題,就可能會把問題簡單歸納為類比人類IQ之類。
但實情是,若突破不了歸納式邏輯,AI的智力條curve點爆上去,都只是quantitative change而非revolution(qualitative) change,也就意義不像infographic圖表效果那麼大。

若突破不了”歸納式邏輯能力”這技術bottleneck,AI/machine learn能解決的問題種類類別其實可能是反而會在未來日子中轉趨飽和。
這可能會比較反映在machine learn R&D走得最前的data scientist/data engineer的視野之中,因為他們是在理論層面最edge最把技術用盡的人,但一般人不會太看到這件事。

但另一方面,即使解決問題種類類別暫趨飽和;但因為技術應用在現實生活中的adoption rate其實未算成熟,所以未來日子中,仍會看到技術應用越來越多,而且是爬升的curve(f”(x)>0, f'(x)>0的curve)。

“技術”與”技術應用”其實是兩條curve,而後者是濟後於前者。
在”技術”未成熟時,”技術應用”是too early adoptor(risky)。
“技術”開始看到軌道時,”技術應用”是early adoptor(risky)。
“技術”開始成熟時,”技術應用”是早期上升期。
“技術”開始飽和時,時間中可能剛剛碰著”技術應用”爆升期,然後再慢慢follow “技術” curve而飽和。
而”技術”會有一代又一代的突破技術,所以整體”技術應用”還是會不斷進化吧。

整體看的話,整體AI/machine learn形勢還是樂觀的,因為這始終是大趨勢。
我指的不是技術趨勢,而是時代大趨勢,就像電腦對人類生活的革命一樣那種。
2020年我相信人類還是在享受技術應用「坐火箭」的過程吧,所以形勢不錯吧。

其實歸納式邏輯能力,一定會有日會被突破,只是遲早問題而已。
不過我比較保守,所以我覺得至少十年內未必突破到。
所以我估計在技術應用飽和期前,也未必突破到。屆時人類/data-scientist就可能要面對技術飽和期一段時間吧。
(戴頭盔:這只是個人ff估計,未必為將來之事實。)

[Nodejs] FB Page post comment/reply event engine

岩岩寫左隻FB Page post comment/reply event engine既Nodejs module。

個module目的係幫FB page owner去mon住個FB page係咪有新comment,然後generate event & 俾個位d人自己去寫callback logic。

實際做法就係佢背底會行個schedule job去call FB graph API黎check post既new comments。

NodeJS module for keep track Facebook Page Posts New Comments

NodeJS module “fb-page-comment-event”

This module can keep track your Facebook page posts’ first level comment events. Hence, if someone commented on your post, you will be notified by an event.

This module support running an event-engine which would manage a background schedule job to check new comment and generating events. This module also support raw APIs which you can check new comments and digest as events by yourself via APIs.

 

Related Pages

Github page: https://github.com/airicyu/fb-page-comment-event
NPM: https://www.npmjs.com/package/fb-page-comment-event

 

Description

This module can keep track your Facebook page posts’ first level comment events. Hence, if someone commented on your post, you will be notified by an event.

This module support running an event-engine which would manage a background schedule job to check new comment and generating events. This module also support raw APIs which you can check new comments and digest as events by yourself via APIs.


Running the event engine

You may use the lib.pageCommentEventApp(options) API to get a event engine app and then start it with run function. This event engine app would manage a schedule job to auto pull data.

Sample:

  • Remarks: pageId is the facebook page ID. postId is the facebook page post ID of post which you want to monitor its comment. accessToken is the Facebook page access token(remember to use the long live token) which Facebook page owner can generate in developer dashboard.

Sample console log output:


(DIY) Use the APIs to check new comments and generating events

Sample:


event engine APIs

let app = lib.pageCommentEventApp({accessToken, pullInterval})

Description:

Initializing the event engine app.

parameters:

  • accessToken: The required accessToken(need permission manage_pages) for the API calls.
  • pullInterval: The sleep time(ms) interval between each scheduled page post new comment checking.

return:

The event engine app.

app.registerMonitorPost({pageId, postId})

Description:

Registering a page post which the event engine would tracking for new comments

parameters:

  • pageId: The page ID.
  • postId: The post ID.

app.run(eventsCallback)

Description:

Start running the event engine and register the new-comment-events callback. Once users write new comments, new-comment-events would be fired and handled by the callback.

parameters:

  • eventsCallback: The batch new-comment-events handling function.

app.stop()

Description:

Stop the event engine


DIY APIs

let queryPostCommentAgent = lib.api.getQueryPostCommentAgent(options)

Description:

Initialize a agent for query post comments.

parameters:

  • options: object with attribute accessToken which holding the required accessToken(need permission manage_pages) for the API calls.

return:

The agent object.

let postCommentFetcher = lib.api.getPostCommentFetcher(queryPostCommentAgent)

Description:

Initialize a fetcher for fetching new post comment.

parameters:

  • queryPostCommentAgent: The agent object which come from lib.api.getQueryPostCommentAgent(options)

return:

The fetcher object.

let postCommentObj = await postCommentFetcher.fetch(postObjId, since)

Description:

Use the fetcher object to fetch post object with comments. We can use this API to get all new comments under the target post which those comments are created since the since time.

parameters:

  • postObjId: The post object ID which is in format of ${pageId}_${postId} in Facebook Graph API.
  • since: The timestamp in second

return:

The post object with comments (All comments child objects are new comments).

let postDigestor = lib.api.getPostDigestor();

Description:

Getting a digestor object which can turn the post-comment object from postCommentFetcher.fetch() result into new-comment-events.

return:

The digestor object.

let newCommentEvents = await postDigestor.digest(postWithNewComments)

Description:

Use the digestor object to digest post-comment object into new-comment-events

parameters:

  • postWithNewComments: The post object with attaching new comments.

return:

New comment event objects

關於呂麗瑤事件的評論

關於呂麗瑤事件,
我認為,對(疑似)受害者最大的支持,不是訴諸同情地輕信,而是求法制上﹑社會上的公平對待﹑保護。

法制那些我不熟悉就且不多說。
就「社會上的公平對待」而言,我認為社會是該用正面肯定的角度去對待受害者肯站出來面對的這件事。
但肯定受害者站出來面對,這件事從來不應簡單地等同於輕信單方面片面之詞,這是完完全全的兩件事。

好些人可能會說,大眾若持有這種理性批評,不輕信受害人,這對疑似受害人構成壓力,是一般被非禮/強姦者不願站出來的原因。
我get到的言下之意(如果冇get錯)好像就是說,你若不信疑似受害人所說的內容,就是在壓迫疑似受害人。
姑勿論是真非禮還是老作,女方較易受同情及信任,這是社會客觀現實。
但觀感上的同情情緒並不等於真相。
呂麗瑤選擇公開處理這件事,雖然沒有點名那名教練,但已令對方被辭退。(好似係)
若事件不明不白只是半透明地處理,其實大眾只是被借助社會壓力向校方施壓。
借助大眾的社會壓力本身無可厚非,但若件事不明不白地就發生,則這種訴諸同情而非真相的culture/做法對社會長遠有害無益。

很多人看待件事,可能是很簡化地either選擇了男方或女方立場。
件事內情其實至今仍然是外人大眾不大清楚,所以只能用推測角度去看,難以下定論,不用跟車太貼。
觀乎一般大眾那種「歸邊」,以及把「支持受害者站出來」以及「確信其所指內容」兩者的綑綁,在一片爭議之中對疑似非禮/被非禮方都是不公平的。

在這種處理不當﹑對雙方也有欠公允的情況下,我覺得社會大眾是應該再反省一下hashtag “metoo”的意義及社會大眾對待這些事的態度。
單單是一個hashtag “metoo”,加上一個人的片面之詞,是否就代表著真相與充分的證據??我看法是有點保留的。
陶傑那篇文,是有點抽水諷刺意味,寫出來引起嘩然。但他就社會輕信處理metoo hashtag的這個point而言,是有一定道理的。

關於blockchain的少少個人理解與想法

講少少個人理解,blockchain大概是一種在處理asset擁有及轉移的應用技術。
對於這種應用,傳統社會的做法牽涉大量trust與資訊交換機制與成本。而因為trust issue, 所以形態上是很多parties各自的centralized trust機制,所以加大了交易成本。

blockchain的做法,是去中心化的trust(rathet than only data storage層面)機制。
藉着公有公開驗證的做法,所有資產轉移都是自帶驗證。
所以大大解決了trust與驗證的成本。(這是blockchain的最大價值)

但當然,技術還技術上的價值,應用上仍然可以是空殼廢紙,所以把資產本質由實體($)轉為虛擬貨幣的應用,用家進入市場有很大風險。

另外,在應用層面,blockchain一定是資產轉移流水帳的use case。若否,則blockchain技術不會帶來太大價值。

另外,blockchain需要公開帳目,我沒仔細研究過,但我懷疑仍有可能由transaction之間去trace back到account持有者身份。
例如,我是e store, 我賣了一件貨給某人,進行了某bitcoin交易,那應該有一條transaction是若干bit coin由某人銀包轉移到我銀包。那我是否能由“某人銀包”去識別出其他關於某人的bitcoin交易?若我掌握大量銀包識別資訊,那會否讓我能知道大眾的帳目資訊?
(我不熟這範疇,純粹ff 想想而已)

Lesson learnt: 從audience角度去present對對方有意義的內容

做開engineer,有時對於一件事件,本能慣性地往往就先從事件分析角度去看。

例如某次關於某事件的一串email裡,我查明了一個issue的root cause。
於是我回覆了給其他人,而回覆的內容是從調查論證的角度去說。
首先是重述問題,然後是初步搜證,然後是推論證明root cause。然後在所有推論完成之後,再加上對應的solution options分析及recommendation。
很正路吧?

其實對於一個及格的engineer來說,是應該看得明白的。
如果人們看事物的角度是求真相,這樣的email presentation也應該是洽當的。

但結果是,一個manager級的人跟我說,他看不明白我在說什麼。

——————————————————————

那個email其實本身no big deal,我reply的內容個manager其實都沒什麼大不了,之後我們在電話講左陣就應付了。
但在講完個電話之後,我其實做了一些反省,亦覺得學懂了一些道理。

對方不夠technical看不明白,公道而言,對方有對方不足。
但對我而言,我其實也有點責任。
我沒有責任去遷就對方的理解水平,但我絕對有責任去思考如何從audience角度去present對對方有意義的內容。

——————————————————————

然後我用這個角度去再思考一次,其實對方(management level的人)的思維對於真不真相﹑technical底層發生的事,是不concern也不想去concern的。
一個issue,root cause是什麼,他們just don’t care,那是對他們沒有任何價值的。

任何事對於他們來說,認知﹑measure的角度就是一件事物對於他們own的application/product/project有什麼benefits & impacts。
一個issue,會為他們的application帶來什麼impact,那才是他會concern的事。
針對那issue的impact而去resolve的solution,solution本身的risk﹑time/technical/$ cost,那才是他會concern的事。
solution execution時,所牽涉到的parties﹑人﹑做法….那execution plan,那才是他會concern的事。

所以結論是,針對這類audience的話,長email的話too long didn’t read,所以最重要的事/conclusion/summary就要在最開頭就說。
中間查明論證的東西不需太清楚,隨便說說就夠,而且可以加indent方便人們too long didn’t read去skip。

Airic API Gateway

Just for fun.
最近斷斷續續前後用左幾個星期左右,自己用NodeJS寫左個REST API Gateway。
 
簡單講隻REST API Gateway做d乜就是:
有個API config server,可以o係上面register隻app+import個swagger,
之後就可以create client同reg API key,
之後就可以用d API key經gateway去call果d REST API。
 
隻Gateway帶黎既benefits係:
– 隔左一層as protection layer,
– 有得落Quota rule去set quota (quota rule =/= spikearrest),
– 會收集到usage stat (1minute bucket),事後可以睇得到某時間內咩人call過邊個app邊個rest operation幾多次。
 
 

Project code name:

Airic API Gateway
 
 
 

基本Features:

 
– 冇UI…(其實依個唔係feature…)
因為我好怕攪frontend野太煩sosad, 所以直頭完全冇攪UI。
CRUD app API﹑CRUD client﹑register API key全部management operation靠REST API去做。
 
– app API definition係食swagger。
 
– support quota rule (1m, 5m, 1h, 1d, 1week, 1Month)。
quota rule可以apply落app level, operation tag level, 或者operation level。(app/tag/operation係跟據swagger spec而判斷)
 
– support對應同一app之下,唔同client分別用唔同quota plan (可以同時apply多個quota plan)
 
– 會log低API usage statistic & 可以用REST API query返出黎,睇到每隻app/operation/client o係某段時間內call左幾多次之類。
 
 

Performance

 
load test今日有試過下。
local PC用jmeter做load test (200 Testing thread), nodejs cluster x 4, 有enable 3條quota rule。
 
throughput都做到~2800 req/s。
random take sample既純粹入gateway processing直至response完成時間(而唔計proxy call背後API既時間)大約係0.x ms至10ms之間。
 
之後我再試多次,code果度直頭完全唔proxy call後面API,直接response返去,咁就真係可以計到純粹gateway processing直至response既時間& throughput。
咁樣load test係可以去到~5200 res/s。
random sample 入gateway到response時間都大約係0.x至10ms之間。
 

project status:

 
算係做左prototype,functionally基本叫做workable…
不過test我都只係人手test冇mocha unit test, 亦都冇寫doc。
(遲D執返好晒D野少少, 得閒先放上github吧~XD)
 
 

Component有邊幾樣野?

1) API config server – 儲住App﹑API config definition既核心。
2) API gateway – 就係隻gateway
3) API stat server – 儲住usage stat
(原本諗住寫多隻key server由config server拆出黎, 但我發覺key同config好難拆得開,我懶+怕煩就冇攪喇)
 
 
 

Database用左乜

1) App Config可以用MySQL或者Mongo或者Memory (好似Mongo方便dd, 不過我MySQL都係用json type儲, 所以差唔多)
 
2) API key可以用MySQL或者Mongo或者Memory (MySQL或者Mongo都冇所謂)
 
3) API call quota可以用Redis或者Mongo或者Memory (Prefer Redis, 好似快好多咁, 依part是用key-value lookup的)
 
4) API usage stat可以用MySQL或者Memory (Prefer MySQL, 只用來事後Aggregate, 其實用Mongo做都ok不過我冇整到)
 

世界很複雜,尤其是人事的﹑政治的問題…

我自己個人的想法其實比較單純。
我喜歡寫code,我希望能幫到人們的生活,我希望能為人們解決到問題。
我希望我能一直地做這些喜歡做的事。
就算有天我老了,能力與適應力退化,遠遠被年輕人拋離;我也希望我能間中在家裡寫寫code做些玩具。