2012-07-27 28 views
2

沒有流慢流我寫了一個小腳本流字節每字節的文件與西納特拉和薄:與薄或根本

#!/usr/bin/env ruby 

require 'sinatra' 
require "sinatra/streaming" 

get '/' do 
    stream do |out| 
    File.open("/usr/share/doc/ia32-libs/copyright", "r") do |fd| 
     fd.each_byte do |byte| 
     break if out.closed? 
     putc byte.chr 
     out << byte.chr unless out.closed? 
     end 
    end 
    end 
end 

可正常工作:

% ruby streamer.rb 
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from Thin 
>> Thin web server (v1.4.1 codename Chromeo) 
>> Maximum connections set to 1024 
>> Listening on 0.0.0.0:4567, CTRL+C to stop 


% curl http://127.0.0.1:4567 

並將文件內容寫在雙方的標準輸出

如果我刪除行putc byte.chr然後服務器崩潰,並被殺害kill -9


另一個意外的行爲,打我,如果我改變這個腳本以模塊化的風格並添加config.ru

#!/usr/bin/env ruby 

require 'sinatra/base' 
require "sinatra/streaming" 

class TestStreamer < Sinatra::Base 
    helpers Sinatra::Streaming 

    get '/' do 
    stream do |out| 
     File.open("/usr/share/doc/ia32-libs/copyright", "r") do |fd| 
     fd.each_byte do |byte| 
      break if out.closed? 
#   putc byte.chr 
      out << byte.chr unless out.closed? 
     end 
     end 
    end 
    end 
end 

config.ru:

$:.unshift(File.join(File.dirname(__FILE__))) 

require 'rubygems' 
require 'sinatra/base' 
require 'streamer_modular' 

map '/' do 
    run TestStreamer 
end 

它啓動:

% thin start 
>> Using rack adapter 
>> Thin web server (v1.4.1 codename Chromeo) 
>> Maximum connections set to 1024 
>> Listening on 0.0.0.0:3000, CTRL+C to stop 

但是當我在做一個請求,文件發送非常緩慢,並在30秒後關閉。 Sinatra在這種情況下不會崩潰。

% time curl -v http://127.0.0.1:3000 
* About to connect() to 127.0.0.1 port 3000 (#0) 
* Trying 127.0.0.1... connected 
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0) 
> GET/HTTP/1.1 
> User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6 
> Host: 127.0.0.1:3000 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
< X-Frame-Options: sameorigin 
< X-XSS-Protection: 1; mode=block 
< Content-Type: text/html;charset=utf-8 
< Connection: close 
< Server: thin 1.4.1 codename Chromeo 
< 
* Closing connection #0 
This package was cre 
curl -v http://127.0.0.1:3000 0,01s user 0,00s system 0% cpu 32,559 total 

當我刪除流輔助的文件被寫入到服務器端標準輸出沒有任何延遲:

#!/usr/bin/env ruby 

require 'sinatra/base' 
require "sinatra/streaming" 

class TestStreamer < Sinatra::Base 
    helpers Sinatra::Streaming 

    get '/' do 
# stream do |out| 
    begin 
     File.open("/usr/share/doc/ia32-libs/copyright", "r") do |fd| 
     fd.each_byte do |byte| 
     # break if out.closed? 
      putc byte.chr 
     # out << byte.chr unless out.closed? 
     end 
     end 
    end 
    end 
end 

% ruby -v 
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux] 

% gem list 

*** LOCAL GEMS *** 

backports (2.6.2) 
bundler (1.1.5, 1.1.3) 
daemons (1.1.8) 
eventmachine (0.12.10) 
rack (1.4.1) 
rack-protection (1.2.0) 
rack-test (0.6.1) 
sinatra (1.3.2) 
sinatra-contrib (1.3.1) 
thin (1.4.1) 
tilt (1.3.3) 

% gem update 
Updating installed gems 
Nothing to update 

% ls -al /usr/share/doc/ia32-libs/copyright 
-rw-r--r-- 1 root root 607403 2. Jan 2012 /usr/share/doc/ia32-libs/copyright 

% head -n2 /usr/share/doc/ia32-libs/copyright 
This package was created by Daniel Jacobowitz <[email protected]> on Sun, Aug 
8th, 2004. It was based on the ia32-libs package by Bdale Garbee 

我缺少的東西?你能重現這一點,也許爲我解決了一個變通方法嗎?

+0

嘗試麒麟作爲服務器。薄與流不工作 - [邁克](http://stackoverflow.com/users/1584911/mike) – Dustin 2012-08-08 14:16:04

+0

它被聲明爲工作在[自述](http://www.sinatrarb.com/intro#Streaming %20Responses)。用薄型越野車進行流式傳輸? – krissi 2012-08-21 11:33:25

+0

不知道。我只是重新發佈一個非回答作爲新用戶的評論。他在4天內沒有見過,所以他不太可能澄清。 – Dustin 2012-08-22 00:36:16

回答

1

在這種模式下,Thin上的字節流式傳輸字節效率有點低,因爲由於Thin基於EventMachine有很多調度和推遲需要(因此Mike對流式傳輸的評論並未在Thin上工作,Mike可能有Rails背景這樣的稀薄流傳輸確實不起作用)。

然而,薄(以及任何機架服務器)應該能夠直接串流文件:

get '/' do 
    File.open("/usr/share/doc/ia32-libs/copyright", "r") 
end 
+0

不幸的是,版權文件只是一個例子。生產中會有/ dev/random。另外,我需要根據源再次填滿的速度來降低我的寫入速度。對不起,忘了提這個 – krissi 2012-09-04 11:17:48