2011-12-14 12 views
8

क्या नियंत्रक के बाहर प्रतीक्षा() तंत्र का उपयोग करने का कोई तरीका है?एसिंक्रोनस डब्ल्यूएस कॉल और प्रतीक्षा() एक नियंत्रक के बाहर

मैं नियंत्रक में एसिंक्रोनस कॉल बनाने के लिए कोड नहीं रखना चाहता, लेकिन इसके बजाय उस सेवा वर्ग में वह कोड है जिसे कई नियंत्रकों द्वारा पुन: उपयोग किया जा सकता है, हालांकि, नियंत्रक के बाहर प्रतीक्षा करने का कोई तरीका नहीं है विधि संरक्षित है।

तो नियंत्रक में उदाहरण के लिए:

ServiceClass service = new My ServiceClass(); 
    MyObject myObject= service.getMeAnObject(); 
    render(myObject); 

और सेवा वर्ग:

public class ServiceClass 
    { 
     ... 
     public MyObject getMeAnObject() 
     { 
     String url = "http://..."; 
     Promise<HttpResponse> promise = url(url).getAsync(); 

     // do something here similar to await in a controller 
     // that suspends the code waiting for the response 
     // to be retrieved 

     HttpResponse response = promise.get(); 
     return buildMyObjectFromResponse(reponse); 
     } 
     ... 
    } 

वहाँ ऐसा ही कुछ प्राप्त करने के लिए कोई तरीका है?

आपकी मदद के लिए धन्यवाद।


संपादित: मैं पेरे की सलाह का पालन किया और सेवा वर्ग को लागू नियंत्रक बनाया है, यह फिर भी काम करता है, यह आवश्यक का उपयोग कर कि नियंत्रक यह बढ़ाया जा रहा है। ऐसा करने का एकमात्र तरीका यह है कि कॉल करने वाले नियंत्रक वर्ग में प्रतीक्षा विधि() के बाद कम से कम एक बार आह्वान किया जाता है।

हालांकि, मैंने अभी भी सत्यापित नहीं किया है कि कोड वास्तव में निलंबित कर दिया गया है।


संपादित करें 2: एक सुझाव मैं गूगल समूह से मिला है कि मैं वास्तव में कोशिश करते हैं और नियंत्रक का इंतजार करना चाहिए, तो शायद एक बेहतर समाधान सेवा एक वापस जाने के लिए के लिए होगा वादा करें और नियंत्रक इसके लिए प्रतीक्षा करें लेकिन फिर मेरे पास ऐसा करने का कोई तरीका नहीं है?

तो नियंत्रक में उदाहरण के लिए

:

ServiceClass service = new My ServiceClass(); 
    Promise<MyObject> promise = service.getMeAnObject(); 
    MyObject myObject = await(promise); 
    render(myObject); 

और सेवा वर्ग:

public class ServiceClass 
    { 
    ... 
    public Promise<MyObject> getMeAnObject() 
    { 
     String url = "http://..."; 
     // Somehow Build a Promise<MyObject> 
    } 
    ... 
    } 

}

उत्तर

3

अब तक, मुझे लगता है कि यह सबसे अच्छा तरीका है जो मुझे लगता है, जब तक कि प्ले इंस्टेंस के भीतर अलग थ्रेड पूल प्रबंधित करने में कोई समस्या न हो।

मैंने उदाहरण दिया है कि WSAsync.WSAsyncRequest कक्षा में Play क्या करता है और ऐसा लगता है।

संक्षेप में, नियंत्रक के भीतर इंतजार किया जाता है, लेकिन सेवा वर्ग वस्तु का वादा करता है, मुझे उम्मीद है कि सेवा वापस लौटने की उम्मीद है जो ठीक है क्योंकि मुझे यह नहीं पता कि इस ऑब्जेक्ट को कैसे पुनर्प्राप्त किया गया था नियंत्रक स्तर।

नियंत्रक में:

ServiceClass service = new My ServiceClass(); 
Promise<MyObject> promise = service.getMeAnObject(); 
MyObject myObject = await(promise); 
render(myObject); 

और सेवा वर्ग:

public class ServiceClass 
{ 
    public Promise<MyObject> getMeAnObject() 
    { 
     String url = "http://..."; 
     return execute(WS.url(url).getAsync()); 
    } 

    private Promise<MyObject> execute(final Promise<HttpResponse> promise) 
    { 
     try 
     { 
      final Promise<MyObject> smartFuture = new Promise<MyObject>(); 
      ScheduledThreadPoolExecutor executor = MyAppThreadPools.getServiceThreadPool(); 

      executor.submit(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         try 
         { 
          smartFuture.invoke(new MyObject(promise.get())); 
         } 
         catch (Throwable e) 
         {     
          smartFuture.invokeWithException(e); 
         } 
        } 
       }); 

      return smartFuture; 
     } 
     catch (Exception e) 
     { 
      throw new RuntimeException(e); 
     } 
    } 
} 

तो यह अभी के लिए मेरी समस्या का समाधान करने लगता है।

धन्यवाद सब कुछ।

1

आप उल्लेख किया है इंतजार एक नियंत्रक में ही उपलब्ध है।

सेवा वर्ग नियंत्रक का विस्तार करें, वहां कई संरक्षित समर्थन विधियां बनाएं और इसे नियंत्रकों के लिए मूल श्रेणी के रूप में उपयोग करें।

इस तरह आप सभी नियंत्रक विधियों (प्रतीक्षा, प्रस्तुत, आदि) तक पहुंच के दौरान, नियंत्रकों में कार्यान्वयन साझा कर सकते हैं।

+3

आपके उत्तर के लिए धन्यवाद। ऐसा लगता है कि यह काम करता है। हालांकि, यह वास्तव में मेरी राय में सबसे अच्छा समाधान नहीं है, क्योंकि सेवा वर्ग अवधारणात्मक रूप से नियंत्रक नहीं है। आदर्श रूप से, कोड बाधा के इस तंत्र कहीं से भी उपलब्ध होगा। –

1

यह शायद आप मदद करने के लिए :) लेकिन जिस तरह से यह Promise.onRedeem() विधि का उपयोग कर एक नया वादा है कि वे वापस लौटे और नियंत्रक में प्रतीक्षित है आह्वान करने के लिए कर रहा है करने के लिए ... बहुत देर हो चुकी है

public Promise<Boolean> deauthorise() { 
    final Promise<Boolean> promise = new Promise<>(); 

    WS.url("https://connect.stripe.com/oauth/deauthorize") 
      .setParameter("client_secret", play.Play.configuration.getProperty("stripe.secretKey")) 
      .setParameter("client_id", play.Play.configuration.getProperty("stripe.clientId")) 
      .setParameter("stripe_user_id", this.stripeUserId) 
      .postAsync() 
      .onRedeem(new Action<Promise<HttpResponse>>() { 
       @Override 
       public void invoke(Promise<HttpResponse> result) { 
        HttpResponse response = result.getOrNull(); 
        promise.invoke(response != null && response.success()); 
       } 
      }); 
    return promise; 
} 
संबंधित मुद्दे