本系列的文章為 Modern Java in Action / Project Reactor 的讀書筆記,因此內容可能會有點跳躍。
Software entities (class, modules, functions, etc.) should be open for extension, but closed for modification.
- Bertrand Meyer
Junior programmers create simple solutions to simple problems. Senior programmers create complex solutions to complex problems. Great programmers find simple solutions to complex problems.
- Charles Connell
註1:本部落格的範例程式碼在 2015 年以前的文章中,大多是以全型空白做縮排。如需服用,請自行用文字編輯器的取代功能把全型空白取代成半型空白。
註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 官方文件中會講到的例子。
1 |
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 並且真的啟動伺服器。
1 2 |
docker run --detach --name sample-vespa -- hostname vespa-container --privileged --volume g:\git\vespa-sample-apps: /vespa-sample-apps --publish 8080:8080 vespaengine /vespa |
首先如前所說,我們先以 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 指令來確認。如果正常的話會獲得類似這樣的回覆:
1 2 3 4 |
HTTP /1 .1 200 OK Date: Sun, 01 Mar 2020 11:31:41 GMT Content-Type: application /json Content-Length: 9232 |
接著就是要在裡面部署和啟動指定的 Vespa Application 了。
1 2 |
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。
1 2 3 4 5 6 7 8 9 10 |
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 狀態時,可以獲得:
1 2 3 4 |
HTTP /1 .1 200 OK Date: Sun, 01 Mar 2020 11:34:39 GMT Content-Type: application /json Transfer-Encoding: chunked |