本系列的文章為 Modern Java in Action / Project Reactor 的讀書筆記,因此內容可能會有點跳躍。
Software entities (class, modules, functions, etc.) should be open for extension, but closed for modification. Junior programmers create simple solutions to simple problems. Senior programmers create complex solutions to complex problems. Great programmers find simple solutions to complex problems. 註1:本部落格的範例程式碼在 2015 年以前的文章中,大多是以全型空白做縮排。如需服用,請自行用文字編輯器的取代功能把全型空白取代成半型空白。
- Bertrand Meyer
- Charles Connell
註2:本部落格的內容授權請參閱部落格底部的授權宣告。
2020年3月29日 星期日
Reactive Programming(三):Project Reactor
2020年3月18日 星期三
在 Spock Framework 測試包含 parallel stream 的標的時卡住
紀錄一下最近解了幾天的問題,程式碼大體上類似 [1] 裡面的 MyRecordProcessor 和 MyRecordProcessorTest 那樣。因為本來是要建置環境比較簡單的測試來重現問題,而原本的問題是發生在開發 Kinesis 的 RecordProcessor 中遇到的,因此 [1] 的範例也沿用了這個關係。不過實際上最後發現的原因跟 Kinesis 沒有關係就是了。
問題的徵兆是,當要測試的標的內部改寫成有 parallel 的狀況時,Spock 這邊執行測試就可能會出現測試整個卡在某個地方的狀況。卡住時會完全沒有回應,但也沒有拋出錯誤或者停止執行。這個問題好像遇到的人並不是那麼多,所以可以找到的資料也非常少。不過主要參考了 [2-3],最後確認的原因是因為測試時用了 Spy。Spy 好像存在某些限制(在 [3] 的回答中有提到,雖然他沒提到到底是什麼限制),實際上似乎導致在 parallel 的狀況時,Spy 的 dynamic proxy 似乎有時會生效、但有時會無效。所以最後解決方法就是~不要用 Spy。
參考資料
2020年3月1日 星期日
Vespa 入門(一):在本機建立 containerized Vespa
因為在公司持續地在用 Vespa,所以打算寫個系列文章慢慢紀錄 Vespa 的一些使用、調校經驗。(雖然說過去寫的系列文章大多…寫到第二或第三篇就………。)
本篇會紀錄在本機啟動 Vespa 的 container 的方法,通常這麼做可以在開發階段用來測試 Vespa 的語法。可以參考 Vespa 官方文件 [1]。
環境準備
依照 [1] 的描述,Docker 環境最重要的就是需要有至少 6GB 的記憶體。而在我的環境中,我是在 Windows 10 上跑 Docker 的,因此至少要是個有支援 Hyper-V 的 Windows 版本,才能夠執行 Docker。
取得 Vespa 範例
首先,Vespa 有提供一些簡單的範例 Application,可以從以下的 Github 取得。裡面有很多資料夾,包含了數種在 Vespa 官方文件中會講到的例子。
git clone https://github.com/vespa-engine/sample-apps.git
這裡假設我把這個 repository 放在 G:\git 裡。
建立並啟動 Vespa container
要啟動 Vespa 之前,我們需要執行兩個動作。第一個是先啟動一個 Vespa 的 container,這個步驟只會準備好 Vespa 需要的執行環境而已。接著第二個是部署 Vespa Application,這個動作就像是在 RDBMS 裡執行 CREATE DATABASE 一樣,是讓 Vespa 準備好 schema 並且真的啟動伺服器。
docker run --detach --name sample-vespa --hostname vespa-container --privileged --volume g:\git\vespa-sample-apps:/vespa-sample-apps --publish 8080:8080 vespaengine/vespa docker exec sample-vespa bash -c 'curl -s --head http://localhost:19071/ApplicationStatus'
首先如前所說,我們先以 vespaengine/vespa 的 image 啟動一個 Vespa container,這裡我們把這個 container 命名為 sample-vespa,並且把資料夾 g:\git\vespa-sample-apps 掛到 container 的 /vespa-sample-apps 路徑上,方便之後我們在這個 container 中部署與啟動 Vespa。
container 開好以後,可以透過第二行指令來確認 Vespa 的狀態。不過因為 container 雖然綁了 port,但卻還沒有啟動任何服務,因此我們要確認狀態只能利用在 container 裡執行 curl 指令來確認。如果正常的話會獲得類似這樣的回覆:
HTTP/1.1 200 OK Date: Sun, 01 Mar 2020 11:31:41 GMT Content-Type: application/json Content-Length: 9232
接著就是要在裡面部署和啟動指定的 Vespa Application 了。
docker exec sample-vespa bash -c '/opt/vespa/bin/vespa-deploy prepare /vespa-sample-apps/album-recommendation-selfhosted/src/main/application/ && /opt/vespa/bin/vespa-deploy activate' curl -s --head http://localhost:8080/ApplicationStatus
這邊我們先部署 album-recommentation-selfhosted 這個 Vespa Application。因為 Vespa 的 Search Definition 是放在 src/main/application 裡的,因此在部署的時候要指定路徑是這個資料夾。第一個指令會獲得類似這樣的反應,表示已經順利地啟用 Vespa Application。
Uploading application '/vespa-sample-apps/album-recommendation-selfhosted/src/main/application/' using http://localhost:19071/application/v2/tenant/default/session Session 3 for tenant 'default' created. Preparing session 3 using http://localhost:19071/application/v2/tenant/default/session/3/prepared WARNING: Host named 'vespa-container' may not receive any config since it is not a canonical hostname. Disregard this warning when testing in a Docker container. Session 3 for tenant 'default' prepared. Activating session 3 using http://localhost:19071/application/v2/tenant/default/session/3/active Session 3 for tenant 'default' activated. Checksum: 71cf99ec40a0a08c8edbd1aa3cee03ed Timestamp: 1583062394458 Generation: 3
再使用第二個指令確認 Application 狀態時,可以獲得:
HTTP/1.1 200 OK Date: Sun, 01 Mar 2020 11:34:39 GMT Content-Type: application/json Transfer-Encoding: chunked