2011-01-10 4 views
6

이제 며칠 동안 이벤트 머신을위한 비 - 에코 - 서버 예제를 찾았지만 아무 것도 보이지 않습니다. 의 내가 파일을 받아 들여 임시 파일에 기록합니다 서버 작성하고자한다고 가정 해 봅시다 :Ruby Eventmachine으로 파일을 작성하는 방법 (큰)

require 'rubygems' 
require 'tempfile' 
require 'eventmachine' 

module ExampleServer 

    def receive_data(data) 
    f = Tempfile.new('random') 
    f.write(data) 
    ensure 
    f.close 
    end 

end 

EventMachine::run { 
    EventMachine::start_server "127.0.0.1", 8081, ExampleServer 
    puts 'running example server on 8081' 
} 

을 원자로를 차단하는 것 파일에 쓰기를,하지만 난 'Eventmachine 스타일'그것을 어떻게하지 않습니다. 데이터를 청크로 읽고 각 청크를 Em.next_tick 블록 내의 디스크에 기록해야합니까? 어떤 도움

감사 안드레아스

docs에서

답변

1

, 당신이 당신이 지적으로, 즉 유효하지 않을 수 있지만, 옵션이 file.write가를 사용하는 것 (파일을 attach해야 할 것 같습니다/ie blocking ...) 및 send_data입니다.

난 당신이 차단/EM과 IO 비 - 블로킹 (non-blocking) :(소스 데이터 감안할 때

소켓입니다 혼합 할 수 있다고 생각하지만, 나는이 EventMachine에 의해 처리 될 것 같아요. 아마

질문 google group ...

~ 크리스

+0

Chris, 답변 해 주셔서 감사합니다. [이 답변] (http://stackoverflow.com/questions/2749503/what-is-the-best-way-to-read-files-in-an-eventmachine-based-app)에 의해 tmm1은 문서와 충돌합니다. 말 (또는 내가 오해 한 것). 기본적으로 나는 아주 간단한 파일 전송 (소켓에서 읽기 및 디스크에 쓰는 중 ...)을하려고합니다. – Andreas

0

에 대한이 (하지만 효율적으로 파일을 읽는 방법을 알고 싶어) What is the best way to read files in an EventMachine-based app? 매우 유사하다. 그래서, 비 차단 파일 API있을 것 같지 않습니다 일 전자가 가장 좋은 방법은 next_tick으로 짧은 버스트를 작성하거나 (defer) 쓰기를 지연하여 별도의 스레드에서 실행되도록하는 것입니다 (그러나 그 솔루션이 얼마나 성능이 좋은지는 잘 모릅니다).

1

파일은 선택 인터페이스에 잘 응답하지 않습니다. IO # 쓰기보다 더 효율적인 것이 필요한 경우 (가능성이 낮음) EIO을 사용할 수 있습니다.

EIO는 실제로 원자로를 가볍게 차단 해제하고 약간의 완충 작용을 제공합니다. 특정 대기 시간이 문제가되거나 디스크 속도가 느린 경우 도움이 될 수 있습니다. 대부분의 다른 경우에, 그것은 아마도 작은 장점을위한 노력의 무리입니다.

3

두 답변 :

지연 응답 : 차단 쓰기 만 사용하십시오. EM은 이미 하나의 거대한 문자열이 아닌 개별 데이터 덩어리를 전달하고 있습니다. 그래서 당신의 예제 구현 조금 떨어져있을 수 있습니다. EM이 당신에게 건네는 모든 단일 청크에 대해 새로운 임시 파일을 만들고 싶습니까? 그러나 샘플 코드가 의도 한대로 작동한다는 가정하에 계속하겠습니다.

틀린 접근법은 쓰고있는 장치에 달려 있지만 동시에 여러 개의 큰 스트림을 동시에 디스크에 쓰려고하면 큰 병목이 될 수 있으며 이벤트가 발생하면 장점을 잃을 것입니다 어쨌든 기반 서버. 결국 디스크 검색을 저글링으로 끝내고 입출력 성능이 떨어지며 서버의 성능도 향상됩니다. 한 번에 많은 것들을 처리하는 것은 RAM에서도 가능하지만 일단 블록 장치 및 IO 스케줄링을 시작하면 무엇을 하든지간에 성능 병목 현상이 발생합니다.

그러나 디스크에 긴 쓰기 작업을하면서 다른 IO 요청이 아닌 다른 요청에 대한 대기 시간이 짧기를 원할 수도 있습니다. 그럼, 아마도 좋은 대답 :

defer을 사용하십시오.

require 'rubygems' 
require 'tempfile' 
require 'eventmachine' 

module ExampleServer 

    def receive_data(data) 
    operation = proc do 
     begin 
     f = Tempfile.new('random') 
     f.write(data) 
     ensure 
     f.close 
     end 
    end 

    callback = proc do 
     puts "I wrote a file!" 
    end 

    EM.defer(operation, callback) 
    end 

end 

EventMachine::run { 
    EventMachine::start_server "127.0.0.1", 8081, ExampleServer 
    puts 'running example server on 8081' 
} 

예, 스레딩을 사용합니다. 이 경우에는별로 좋지 않습니다. 스레드 간 동기화에 대해 걱정할 필요가 없습니다. EM은이 문제를 처리 할만큼 충분히 유용하기 때문입니다. 응답이 필요한 경우 콜백을 사용하십시오.이 콜백은 작업자 스레드가 완료 될 때 주 원자로 스레드에서 실행됩니다. 또한 GIL은 여기에서 IO 블로킹을 처리하고 CPU 동시성을 얻으려고하지 않기 때문에이 경우에는 별 문제가되지 않습니다.

하지만 동일한 파일에 모든 것을 쓰려고한다면 스레드가 동일한 파일에 동시에 쓰기를 시도 할 때 동기화 문제가 발생하므로 지연에주의해야합니다.

관련 문제