在阅读play2文档时,我发现了这个:
由于Play 2.0的工作方式,动作代码必须尽可能快 可能的(即非阻塞)。那么如果我们应该如何回归呢? 还不能计算吗?回应应该是a的承诺 导致!
哇!这当然让我对playakka和akka感兴趣。 我目前正在构建一个与elasticsearch集成的自动完成应用程序, 所以这将是一个完美的契合!
控制器:
public class AutoComplete extends Controller {
@BodyParser.Of(value = BodyParser.Json.class)
public static Result complete(final String term) {
F.Promise<List<String>> list = Akka.future(new Callable<List<String>>() {
public List<String> call() throws Exception {
List<String> list = IndexService.find(term);
return list;
}
});
return async(list.map(new F.Function<List<String>, Result>() {
@Override
public Result apply(List<String> list) throws Throwable {
return ok(Json.toJson(list));
}
}));
}
服务
public static List<String> find(final String term) {
IndexQuery < SearchWord > query = SearchWord.find.query();
query.setQuery("{\n" +
" \"bool\": {\n" +
" \"should\": [\n" +
" {\n" +
" \"text\": {\n" +
" \"search_word.ngrams\": {\n" +
" \"operator\": \"and\",\n" +
" \"query\": \""+term+"\"\n" +
" }\n" +
" }\n" +
" },\n" +
" {\n" +
" \"text\": {\n" +
" \"search_word.full\": {\n" +
" \"boost\": 1,\n" +
" \"query\": \""+term+"\"\n" +
" }\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}");
IndexResults<SearchWord> indexResults = SearchWord.find.search(query);
List<String> list = new ArrayList<String>();
for(SearchWord word : indexResults.getResults()){
list.add(word.getWord());
}
return list;
}
}
搜索内容:
@IndexType(name = "search_word")
public class SearchWord extends Index {
// Find method static for request
public static Index.Finder<SearchWord> find = new Index.Finder<SearchWord>(SearchWord.class);
public enum WordType {
NAME,
STRONG_SEARCH_WORD,
WEAK_SEARCH_WORD,
BANNED
}
private String word;
private WordType wordType;
public SearchWord() {
}
public SearchWord(IndexWord indexWord) {
super.id = ""+indexWord.getId();
this.word = StringUtils.lowerCase(indexWord.getWord());
this.wordType = WordType.valueOf(indexWord.getType());
}
public String getId() {
return super.id;
}
public void setId(String id) {
super.id = id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public WordType getWordType() {
return wordType;
}
public void setWordType(WordType wordType) {
this.wordType = wordType;
}
@Override
public Map toIndex() {
HashMap map = new HashMap();
map.put("id", super.id);
map.put("word", word);
map.put("word_type", wordType.toString());
return map;
}
@Override
public Indexable fromIndex(Map map) {
if (map == null) {
return this;
}
this.word = (String) map.get("word");
this.wordType = WordType.valueOf((String)map.get("word_type"));
return this;
}
}
代码运行良好,但我必须说我不确定我是否正确实现了这一点。我真的很难理解文档。 所以我的问题基本上是:
=====
return async(
Akka.asPromise(ask(myActor,"hello", 1000)).map(
new Function<Object,Result>() {
public Result apply(Object response) {
return ok(response.toString());
}
}
)
);
答案 0 :(得分:2)
AFAIK,你的代码完全可以。
我可能错了,但我认为第二个选项与第一个选项完全相同,因为Akka.future()
方法是Akka.promise()
方法的包装。
来自Akka class source code of Play 2.0.4:
/**
* Executes a block of code asynchronously in the application Akka Actor system.
*/
public static <T> Promise<T> future(java.util.concurrent.Callable<T> callable) {
return asPromise(akka.dispatch.Futures.future(callable, system().dispatcher()));
}
答案 1 :(得分:0)
虽然你已经正确实现了Promise和Future,但我不认为这段代码是“非阻塞的”......
似乎阻止呼叫是
List<String> list = IndexService.find(term);
虽然现在已经包含在一个承诺/未来中,但它仍然是一个封锁电话...... 如果你想要真正的非阻塞(具有所有好处),你必须使你的数据访问(查询)无阻塞......
哦,非阻塞动作方法应该返回结果的承诺,而不是结果......
这就是我应该编写代码的方式:
@BodyParser.Of(value = BodyParser.Json.class)
public static F.Promise<Result> complete(final String term) {
scala.concurrent.Future<List<String>> listFuture = IndexService.find(term);
F.Promise<List<String>> listPromise = F.Promise.wrap(listFuture);
return listPromise.map(new F.Function<List<String>, Result>() {
@Override
public Result apply(List<String> list) throws Throwable {
return ok(Json.toJson(list));
}
});
}
希望这有帮助!