顯示具有 Reactive Programming 標籤的文章。 顯示所有文章
顯示具有 Reactive Programming 標籤的文章。 顯示所有文章

2020年7月26日 星期日

解決 switchIfEmpty() 每次都被執行的問題

紀錄一下最近發現的有點意外的 Reactor 反應。

Mono.justOrEmpty(getXXX())
    .switchIfEmpty(fallbackXXX())
    ...

本來預期的行為是,getXXX() 會回覆一個 Optional 物件,當回覆的 Optionalempty 時,才會觸發 fallbackXXX() 去呼叫外部服務。但結果在測試時發現 fallbackXXX() 每次都必然會被執行,雖然最後結果會是對的,如果 getXXX() 有回覆時,走到後面的 stream 內容會是 getXXX() 回覆的東西,但這樣就等於每次執行時都會呼叫外部服務了,而且呼叫後拿到的結果還不一定會用到。

查了好一段時間之後,發現問題好像是出在 Java 本身的 method evaluation 行為上,然後解決方法是必須把 fallbackXXX()Mono.defer() 包裝起來,以達成讓 fallbackXXX() 推遲被執行的目的。

Mono.justOrEmpty(getXXX())
    .switchIfEmpty( Mono.defer(fallbackXXX()) )
    ...
參考資料
  1. Mono switchIfEmpty() is always called

2020年3月29日 星期日

Reactive Programming(三):Project Reactor

本系列的文章為 Modern Java in Action / Project Reactor 的讀書筆記,因此內容可能會有點跳躍。

2019年12月29日 星期日

Reactive Programming(二):Flow API

本系列的文章為 Modern Java in Action / Project Reactor 的讀書筆記,因此內容可能會有點跳躍。

2019年11月6日 星期三

Reactive Programming(一)

本系列的文章為 Modern Java in Action / Project Reactor 的讀書筆記,因此內容可能會有點跳躍。

2019年7月18日 星期四

Spring WebFlux:Reactive Programming(持續更新中…)

最近開始認真在讀 Spring WebFlux 的文件,所以稍微做一點筆記~。

何謂 Reactive?

在 Spring 的定義來說,Reactive 包含兩件重要的事情:「Reacting」以及「Non-blocking back pressure」。在 Reacting 的部份,Spring 的描述如下:

The term, “reactive,” refers to programming models that are built around reacting to change — network components reacting to I/O events, UI controllers reacting to mouse events, and others. In that sense, non-blocking is reactive, because, instead of being blocked, we are now in the mode of reacting to notifications as operations complete or data becomes available.

重點在於最後面的描述,我們現在處於「回應通知」的模式,在操作完成或者是資料可以存取的時候才採取反應。而對於 Non-blocking back pressure 的部份,則是以下的描述:

In synchronous, imperative code, blocking calls serve as a natural form of back pressure that forces the caller to wait. In non-blocking code, it becomes important to control the rate of events so that a fast producer does not overwhelm its destination.

這個在我以前一開始聽到的時候,其實不太能理解它的重要性,不過聽過很多次以後,慢慢地有了一點感覺~XD。在同步操作中,因為呼叫者會需要等待,所以呼叫者通常可以很明確地知道接收者什麼狀況開始受不了了;但在非同步的模式中,呼叫者跟接收者並沒有直接性的連接,所以基本上容易落入完全不知道對方狀況的情境,然後一股腦地一直發送事件,讓接收者被塞爆~。而在 Reactive Programming 的概念中,應該要包含接收者必須要具備 back pressure 的能力,有點像是在必要時壓制呼叫者,叫它停下來這樣。

Spring WebFlux 對於 Reactive 的支援

Spring 的體系中,現在分成兩大類:Spring MVC 和 Spring WebFlux,如下圖所示。兩邊都同時有支援 Annotated Controller 的模式,也就是可以用類似於過去的 Spring MVC 的方式使用 Spring WebFlux。不過如果要使用類似 Java 8 Lambda 的那種 Functional Programming 的 model 的話,就得採用 Functional Endpoints 的方式來開發了。


參考資料
  1. Web on Reactive Stack