2011-10-26 22 views
5

@Async görevDönüş @Async yöntemi Spring MVC ile sonuçlanır ve Ajax istemcisine geri döner

@Async 
public Future<String> getResultFromServer(){ 
    String result = ...... 
    return new AsyncResult<String>(result); 
} 

yürüten Denetleyicimin içinde bazı yöntemler var. Yöntem yürütme süresi 1o dakikaya kadar. Tek yapmam gereken sonuç AJAX/JQuery kullanılarak bağlanacak olan müşteri tarafına geri dönmek.

İstemcinin @Async yönteminin yürütülüp yürütülmediğini her saniye sunucumdan istemesini istemiyorum. Sadece bağlantımı açık tutmak istiyorum ve sonra sadece "itme" sonucu Sunucu'ya.

@RequestMapping(value="/async.do", method=RequestMethod.POST) 
public void getResult(HttpServletResponse res){ 
    String result = null; 
    PrintWriter out = res.getWriter(); 
    Future<String> future = getResultFromServer(); 
    try { 
     if (future.isDone()) 
      result = future.get(); 
     out.println(result); 
     out.close(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
    } 
} 

Bu Comit modeline çok yakın olduğunu anlıyorum, ancak genel olarak kuyruklu yıldızı bilmiyorum.

Sorum şu: JavaScript/JQuery kullanarak bağlantıyı istemci tarafında nasıl açık tutabilirim?

ve @RequestMapping(value="/async.do", method=RequestMethod.POST) metodu istemciye itme sonucu verecek mi?

+1

En sonunda bu/bölüm 2'yi nasıl çözdünüz? – happybuddha

cevap

2

En kolay yol, yöntemi eşzamansız bir şekilde çağırmak değil, bunun yerine doğrudan denetleyiciden eşzamanlı olarak çağırmasıdır. Daha sonra, yöntemin sonucu hesaplanana kadar isteğin "bekle" olması ve oluşturulduktan sonra iade edilebilmesi gerekir. Tabii ki bu, bağlantının ne kadar sürdüğü (1 dakika) için bağlantının açık olacağı anlamına gelir.

+0

cevabınız için teşekkür ederiz ve yöntemi doğrudan yürütme fikriniz için başka bir endişem var: Anladığım kadarıyla Tomcat, isteğimi HTTP bağlantım için açılan ayrı bir iş parçacığından gerçekleştiriyor. İsteğim 15 dakika devam ederse, Tomcat iş parçacığının tüm bu zaman boyunca çalışacağı anlamına mı geliyor? Bu işlemin istek için 2 iş parçacığı ve Async görevi için ikincisi gerektirdiği anlamına mı geliyor? ikinci iş parçacığı (async görev) yürütülürken, ilk iş parçacığı askıya almak için herhangi bir yolu var mı? –

+0

Eğer '@ async' işlevini kullanırsanız, '@ async' tarafından eklenmiş ve hemen döndüren yöntemin çağrıldığı iki iş parçacığınız vardır ve bu,' @ async 'yöntemindeki öğeleri gerçekten yerine getirir. İlk iş parçacığını askıya almak için, sadece future.get() işlevini çağırırsanız, sonuç çağrılana kadar iş parçacığını engeller. Ama bunu yaparsanız: '@ async'ı çağırıp doğrudan geldikten sonra future.get() işlevini çağırın, daha sonra' @ ascync' öğelerinin tümü işe yaramaz, çünkü bir yöntem çağrısının normal davranışını birçok teknikle simüle edersiniz (neredeyse) şey. – Ralph

+0

@ danny.lesnik: Ancak, hesabınız 15 dakika sürecekse, bu zaman dilimi için bir bağlantıya sahip olmaktan başka bir çözüm bulmanız gerekiyor! – Ralph