2013-01-03 42 views
8

जब play2 प्रलेखन पर पढ़ने मैं इस पाया में अक्का भविष्य और खेलने का वादा किया का इस्तेमाल करते हैं की कोशिश: जिस तरह सेमेरी Play2 आवेदन

2,0 काम करता है खेलते हैं, कार्रवाई कोड के रूप में तेजी से के रूप में होना चाहिए संभव (यानी गैर अवरोधन)। तो हमें परिणाम के रूप में क्या लौटना चाहिए यदि हम अभी तक इसकी गणना करने में सक्षम नहीं हैं? प्रतिक्रिया परिणाम का वादा होना चाहिए!

वाह! इसने मुझे 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; 
    } 
} 

searchword:

@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; 
    } 


} 

कोड बहुत काम करता है अच्छा लेकिन मुझे कहना होगा कि मुझे यकीन नहीं है कि मैंने इसे सही तरीके से कार्यान्वित किया है। मैं वास्तव में दस्तावेज़ीकरण को समझने के लिए संघर्ष कर रहा हूं। तो मेरे सवालों का मूल रूप से कर रहे हैं:

  1. मैं भविष्य और वादा सही ढंग से लागू है?
  2. यह एक कस्टम अभिनेता बनाने के लिए बेहतर होगा, और कहा कि अभिनेता में, सूचकांक खोज प्रदर्शन डॉक्स में उदाहरण की तरह:

=====

return async(
     Akka.asPromise(ask(myActor,"hello", 1000)).map(
      new Function<Object,Result>() { 
      public Result apply(Object response) { 
       return ok(response.toString()); 
      } 
      } 
     ) 
    ); 
  1. हो सकता है कि आपके पास कुछ शानदार उदाहरण है जो मुझे अभी तक नहीं मिला है?
+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())); 
} 
0

यद्यपि आप सही ढंग से वादा और भविष्य को लागू किया है, मैं "गैर अवरुद्ध" होने के लिए इस कोड पर विचार नहीं होता ...

ऐसा लगता है कि अवरुद्ध कॉल

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)); 
     } 
    }); 
} 

आशा इस मदद करता है:

ओह, और एक गैर अवरुद्ध कार्रवाई विधि एक परिणाम के एक वादा लौटना चाहिए, न कि परिणाम ...

यह मैं कैसे अपना कोड लिखना चाहिए !

+0

ओह, केवल यह देखा गया कि यह एक साल पहले पूछा गया था ... सोचा था कि यह सिर्फ 5 दिन पुराना था ;-) – stikkos