2016-11-06 4 views
2

Ruby on Rails에서 본질적으로 동기식이라는 것을 깨달았습니다. 동기식 비동기식 작업을 수행하는 것은 개발자의 몫입니다. 일부 웹 개발자의 경우, 외부 API에 대한 GET 요청과 같이 여러 작업을 시작했으며, 둘 다 다른 작업의 결과에 의존하지 않기 때문에 두 작업을 동시에 시작하기를 원합니다. 나는 잘 작동하는 것 같다 concurrent-ruby library을 발견했다. 클래스를 작성한 클래스와 혼합하면 클래스의 메소드에 백그라운드 스레드에서 실행되는 비동기 버전이 생깁니다. 이것은 내가 FirstAsyncWorker와 SecondAsyncWorker가 코딩 한 클래스이고, Concurrent :: Async 모듈을 혼합하고 HTTP 요청을 보내는 "work"라는 메서드를 코딩 한 다음과 같은 코드를 작성하게합니다.Ruby on Rails에서 응답을 보내기 전에 여러 비동기 작업이 완료 될 때까지 기다리는 방법은 무엇입니까?

def index 
    op1_result = FirstAsyncWorker.new.async.work 
    op2_result = SecondAsyncWorker.new.async.work 

    render text: results(op1_result, op2_result) 
end 

그러나 컨트롤러는 동작 메서드가 끝날 때 암시 적으로 응답을 렌더링합니다. 따라서 op1_result 및 op2_result가 값을 가져 오기 전에 응답이 전송되고 브라우저로 전송되는 것은 "#"입니다.

내 해결책은 Ruby 스레드를 사용하는 것입니다. 두 개의 스레드가 같은 메모리에 액세스하지 않기 때문에 내가 뮤텍스를 사용하지 않는

def index 
    op1_result = nil 
    op2_result = nil 

    op1 = Thread.new do 
    op1_result = get_request_without_concurrent 
    end 

    op2 = Thread.new do 
    op2_result = get_request_without_concurrent 
    end 

    # Wait for the two operations to finish 
    op1.join 
    op2.join 

    render text: results(op1_result, op2_result) 
end 

: 내가 좋아하는 코드를 작성합니다. 그러나 이것이 최선의 접근 방법인지 궁금합니다. 동시 루비 라이브러리 또는이 상황에 더 적합한 다른 라이브러리를 사용하는 더 좋은 방법이 있습니까?

답변

5

동시 루비 라이브러리에 대한 더 많은 연구가 끝나고 나 자신이 대답했다. "미래"는 결국 내가 한 것! 간단히 말해, 백그라운드 스레드에서 코드 블록을 실행하고 Future의 계산 된 값에 액세스하려고하면 백그라운드 스레드가 작업을 완료 할 때까지 주 스레드를 차단합니다. 내 레일 컨트롤러 액션이처럼 보이는 끝낼 :

def index 
    op1 = Concurrent::Future.execute { get_request } 
    op2 = Concurrent::Future.execute { another_request } 

    render text: "The result is #{result(op1.value, op2.value)}." 
end 

점 "결과"를 실행 시작할 수있는 모두 비동기 작업이 완료 될 때까지 "렌더링"블록과 라인입니다.

누구나 이런 종류의 프로그래밍을하고 있다면, 이것을 찾아서 두 비동기 기술을 모두 구현 한 Rails 앱의 예를보고 싶습니다. public example을 호스팅했습니다.

관련 문제