我需要對地址對象進行地理編碼,然後將更新後的地址存儲在搜索引擎中。這可以簡化爲接受一個對象,對該對象執行一個長時間運行的操作,然後保持該對象。這意味着操作順序要求第一次操作在持續發生之前完成。在Akka排序一對外部服務調用的最佳方法
我想使用Akka將其移出主執行線程。
我最初的想法是使用一對期貨來實現這一點,但Futures documentation並不完全清楚哪些行爲(摺疊,地圖等)保證一個未來在另一個之前被執行。
我開始時創建了兩個函數,分別爲defferedGeocode
和deferredWriteToSearchEngine
,這兩個函數爲相應操作返回Futures。我把它們連在一起使用Future<>.andThen(new OnComplete...)
,不過這樣會笨重的速度非常快:
Future<Address> geocodeFuture = defferedGeocode(ec, address);
geocodeFuture.andThen(new OnComplete<Address>() {
public void onComplete(Throwable failure, Address geocodedAddress) {
if (geocodedAddress != null) {
Future<Address> searchEngineFuture = deferredWriteToSearchEngine(ec, addressSearchService, geocodedAddress);
searchEngineFuture.andThen(new OnComplete<Address>() {
public void onComplete(Throwable failure, Address savedAddress) {
// process search engine results
}
});
}
}
}, ec);
然後deferredGeocode
實現這樣的:
private Future<Address> defferedGeocode(
final ExecutionContext ec,
final Address address) {
return Futures.future(new Callable<Address>() {
public Address call() throws Exception {
log.debug("Geocoding Address...");
return address;
}
}, ec);
};
deferredWriteToSearchEngine
是相當類似deferredGeocode
,不同的是它的搜索引擎服務作爲附加的最終參數。
我的理解是,期貨應該用於執行計算,不應該有副作用。在這種情況下,對地址進行地理編碼就是計算,所以我認爲使用Future是合理的,但寫入搜索引擎肯定是一個副作用。
Akka的最佳做法是什麼?我怎樣才能避免所有的嵌套調用,但要確保地理編碼和搜索引擎都是在主線程之外完成的?
是否有更合適的工具?
更新:
基於以下維克托的意見,我想了下面這段代碼:
ExecutionContext ec;
private Future<Address> addressBackgroundProcess(Address address) {
Future<Address> geocodeFuture = addressGeocodeFutureFactory.defferedGeocode(address);
return geocodeFuture.flatMap(new Mapper<Address, Future<Address>>() {
@Override
public Future<Address> apply(Address geoAddress) {
return addressSearchEngineFutureFactory.deferredWriteToSearchEngine(geoAddress);
}
}, ec);
}
這似乎是工作,除了一個問題,這我不興奮與確定。我們在Spring IOC代碼庫中工作,所以我想將ExecutionContext注入到FutureFactory對象中,但是這個函數(在我們的DAO中)需要知道ExecutionContext似乎是錯誤的。
對於我來說flatMap()函數完全需要一個EC似乎很奇怪,因爲這兩個期貨都提供了一個。
有沒有辦法保持關注的分離?我是不是很糟糕地構建代碼,還是僅僅是它需要的方式?
我想在FutureFactory中創建一個允許鏈接FutureFactory的接口,所以flatMap()調用將被封裝在FutureFactory基類中,但是這好像是故意顛覆了Akka設計決策的故意。
這是deferredWriteToSearchEngine執行副作用的問題嗎?而且我對map()調用有點困惑......就是我們在寫入之後需要做另一個操作嗎? – JBCP
不,這不是deferredWriteToSearchEngine執行副作用的問題。是的,最後一張地圖是在副作用之後做某事的一個例子。 –
Hi @Viktor,請參閱我的更新評論。我對如何保護國際奧委會的主體並繼續使用期貨有點困惑。也許這應該是一個單獨的問題,但似乎相關。 – JBCP