참고 : 여기서 명백한 대답은 "완료하는 데 20 분이 걸리는 것을 수정합니다"입니다. 내가 여기에서 루트 병목 현상 인 실제 메커니즘 (아래의 WidgetProcessor
참조)에 대한 제어권이 없기 때문에 이것이 내가 찾는 대답이 아닙니다.Grails에서 장기 실행 비동기 호출 및 서버 푸시
HTML5와 JS를 통해 대부분의 처리를 클라이언트 쪽에서 처리하는 Grails (2.4.3) 응용 프로그램이 있습니다. 이제 사용자가 버튼을 클릭 할 필요가 있으며,이 이벤트가 매우 긴 시간 (어디에서 3 분에서 20 분까지) 비동기 프로세스로 시작되는지 궁극적으로 사용자의 화면이 동적으로 표시되어야합니다 (페이지 새로 고침) 결과가 업데이트되었습니다.
class FizzController {
FizzServiceClient fizzServiceClient = FizzServiceFactory.newFizzServiceClient()
// ... lots of other stuff
// This is called when the button above is clicked.
def kickOffBigJob(params) {
// Send the request off to a RESTful web service. This service is what
// handles the asynchronous process and ultimately returns a result
// (a String). The service endpoint returns immediately (< 500ms) but
// the actual result can take up to 20 minutes to be computed.
fizzServiceClient.kickOffBigJob(convertToWidget(params))
}
}
FizzService#kickOffBigJob()
내부 :
// This code is deployed to a different JVM/WAR that exposes RESTful endpoints that
// respond to 'fizzServiceClient.kickOffBigJob(Widget)'.
class FizzService {
ExecutorService executor = initExecutor()
// This method submits the 'widget' to an executor and then returns an HTTP response
// to the service client. Note that this response is not the 'result' we're looking
// for, it's just a quick indication that the request was received OK.
def kickOffBigJob(Widget widget) {
WidgetJob widgetJob = new WidgetJob(widget)
executorService.submit(widgetJob) // WidgetJob extends Runnable
}
}
그리고 마지막으로
클릭에$(".my-button").click(function(e){
var btn = $(this);
$.ajax({
type: 'GET',
url: "/myapp/fizz/kickOffBigJob",
data: {fizz: $(btn).attr('fizz')},
success: function (data) {
}
})
});
이 내 FizzController#kickOffBigJob()
방법에 보내 클라이언트 측 (jQuery를)에
:
class WidgetJob implements Runnable {
Widget widget
WidgetProcessorFactory wpf = new WidgetProcessorFactory()
// Constructors, etc.
@Override
def run() {
WidgetProcessor processor = wpf.newWidgetProcess()
// Where the magic happens; this is what takes up to 20 minutes to
// compute the 'result'.
String result = processor.process(widget)
}
}
그래서 지금은이 문제가 :
- (가) '
result
은'우리 내부의 Grails의 컨트롤러 (FizzController
) 다시WidgetJob#run()
을 계산 통신하는 방법; 그리고 - Grails 컨트롤러의 '
result
'을 클라이언트 측 으로 동적으로 밀어 넣는 방법으로 페이지를 새로 고치지 않고 사용자의 UI가 갑자기 'result
'값으로 업데이트됩니다.
어떻게하면이 작업을 수행 할 수 있습니까?
당신이 asynch를 통해 할 수 있는지 의심 스럽습니다. 이것은 별도의 프로세스를 시작하기 때문입니다. 프론트 엔드가 업데이트를 위해 폴링하는 db 테이블을 업데이트하는 비동기 작업을 얻을 수 있습니다. 또는 웹 소켓을 볼 수도 있고, 상황에 따라 작동하는지 확실하지 않을 수도 있습니다. jssh 플러그인을 살펴보십시오. - 웹 소켓을 사용하여 상호 작용합니다. 백엔드 서버 및 실제 실시간 결과. – Vahid