Ruby Rack adapter request

Discussion in 'Feedback/Feature Requests' started by zhesto, Jan 11, 2008.

  1. zhesto

    zhesto New Member

    Rack [ http://rack.rubyforge.org/ ] - provides an minimal interface between webservers supporting Ruby and Ruby frameworks. Almost all recently releazed ruby frameworks (Ramaze, Sinatra etc.) using it. Creating LSAPI adapter for it will enable all of them (and the new onces comming) to run on litespeed.

    What need to be done:
    1. Rack Litespeed handler - {rack_path}/lib/rack/handler/litespeed.rb - i tryed to patch the CGI handler with:
    Code:
    def self.run(app, options=nil)
            while LSAPI.accept != nil
              serve app
            end
          end
    but for some reason it not worked.

    2. {lsws}/fcgi-bin/RackRunner.rb , similar to the RailsRunner.rb one. It will call the Rack::Handler::Litespeed directly or via {project_home}/start.rb

    3. EasyRackWithSuEXEC VH Template
  2. mistwang

    mistwang LiteSpeed Staff

    have you added "require lsapi" ?
    other changes need to be made are
    rack.run_once=false

    LSAPI uses hash to store ENV, so need to do env=ENV.to_hash, just env=ENV
  3. zhesto

    zhesto New Member

    What i've done until now:

    1. Handler modified:

    Code:
    require 'lsapi'
    
    module Rack
      module Handler
        class Litespeed
          def self.run(app, options=nil)
            while LSAPI.accept != nil
              serve app
            end
          end
    
          def self.serve(app)
            env = ENV
            ...
                         "rack.run_once" => false,
    2. Handler added to the {rack_path}/lib/rack.rb:
    Code:
    module Handler
        autoload :CGI, "rack/handler/cgi"
        autoload :Litespeed, "rack/handler/litespeed"
        ...
      end
    3. External application created:
    Code:
    Name	 			rbLsapi
    Address	 			uds://tmp/lshttpd/lsruby.sock
    Notes	 			Not Set
    Max Connections 		5	
    Environment	
    				LSAPI_MAX_REQUESTS=500
    				LSAPI_CHILDREN=5
    Initial Request Timeout (secs)	180
    Retry Timeout (secs)		0
    Persistent Connection		Not Set
    Connection Keepalive Timeout	Not Set
    Response Buffering		No
    Auto Start			Yes
    Command				$SERVER_ROOT/fcgi-bin/lsruby_runner.rb
    Back Log			50
    Instances			1
    Run On Start Up			Not Set
    Max Idle Time			Not Set
    Priority	 		3
    Memory Soft Limit (bytes)	250M
    Memory Hard Limit (bytes)	300M
    Process Soft Limit		200
    Process Hard Limit		200
    4. Ruby scripts bound to the rbLsapi:
    Code:
    rb	LiteSpeed API	[Server Level]: rbLsapi
    5. Simple script in $SERVER_ROOT/DEFAULT/html/simple.rb:
    Code:
    require 'rubygems'
    require 'rack'
    require 'lsapi'
    
    class HelloWorld
      def call(env)
        [ 200, # HTTP Response Code
          { "Content-Type"=>"text/plain" }, # HTTP Headers
          [ "Hello, World!" ] # Body
        ]
      end
    end
    
    # Instantiate your app
    app = HelloWorld.new
    
    Rack::Handler::Litespeed.run app
    The result: 500 Internal Server Error

    In the error.log:
    Code:
    2008-01-11 12:54:47.088 [INFO] [rbLsapi] add child process pid: 3094
    2008-01-11 12:54:47.088 [INFO] [rbLsapi] pid list size: 1
    2008-01-11 12:54:47.218 [NOTICE] [192.168.3.81:54602-0#Example] Premature end of response header.
    2008-01-11 12:55:03.555 [WARN] [192.168.3.81:54604-0#Example] LSAPI Packet header is invalid,('S','t','a','t','u','s',':',' ')
    2008-01-11 12:55:03.555 [INFO] [192.168.3.81:54604-0#Example] connection to [uds://tmp/lshttpd/lsruby.sock] on request #0, error: Input/output error!
    2008-01-11 12:55:03.555 [INFO] [uds://tmp/lshttpd/lsruby.sock] Connection error: Input/output error, adjust maximum connections to 4!
  4. aemadrid

    aemadrid New Member

    There is already a rack handler in the repo. I should know because I submitted it. I'm including my code that I know it works. I only changed one line in rack.rb and created lsws.rb myself. I changed the .rb extensions to .txt to upload.

    Hope this helps,


    AEM

    Attached Files:

  5. mistwang

    mistwang LiteSpeed Staff

    Do not use lsruby_runner.rb, just run simple.rb directly by changing the command configuration, use a LSAPI context instead of *.rb script handler to invoke the app.

    AEM's code should work.

    And if you want to make your code works, I think you need a little more changes need to Hanlder::LiteSpeed,
    All references to STDIN, STDOUT should be changed to use the object return by LSAPI.accept.
  6. zhesto

    zhesto New Member

    Thanks a lot mistwang and aemadrid. Problem solved - i used the aemadrid code. Working + no need to reinvent the wheel ;). Just a small question (or maybe i need to repost it in the usual RoR forum, not here):

    Need I to create different socket for every external application I started in that way (LSAPI Ext App + Context)?

    Best regards and thanks again
  7. aemadrid

    aemadrid New Member

    Glad to help. Let me know if you find something to improve.

    AEM
  8. mistwang

    mistwang LiteSpeed Staff

    Yes, that's correct. The same for each rails application behind the scene.

    If you guys can make it into the official rack package, it will be great.
  9. zhesto

    zhesto New Member

  10. Dru

    Dru New Member

    Sorry to resurrect a slightly old thread but how well was this working for you guys as currently, being a bit green when it comes to the whole rack thing, the only way I've managed to run a merb app on my server is by starting a thin or mongrel instance and then setting up a webserver proxy as an external app in my vhost.

    It feels like more of a hack than anything (although it does offer remarkably good performance) so I'd like to be able to serve it via lsapi/rack but after playing around with the configuration used in here and trying numerous other things I've yet to have any success.
    Last edited: May 27, 2008
  11. aemadrid

    aemadrid New Member

    I can attest that it works because I have a small test app running but it surely isn't as easy to deploy like a normal rails app. You basically have to adapt this http://www.litespeedtech.com/support/wiki/doku.php?id=litespeed_wiki:ruby_rails to make it work for oyur rack script. These days I'm using thin or Ebb for my non-rails projects so I don't have the time for it but the real solution would be to generate a template similar to the Rails template but to deploy Rack scripts. That would actually make more sense and go a long way to make things easier.

    AEM

  12. Dru

    Dru New Member

    Thanks for the reply, I might experiment with it a bit. The solution I have currently is fairing quite well , the only thing that's bothering me is that I can't get litespeed to reliably serve the static assets and cached pages in my merb app, doubtless something I'm doing wrong though.
  13. aemadrid

    aemadrid New Member

    What you need is static contexts for your static assets (/images, /stylesheets, etc).
  14. ctran73

    ctran73 New Member

    Would you mind re-post the instructions step-by-step? It's kind of hard to follow with all the threads going on

  15. obrie572

    obrie572 New Member

    Any chance anyone has step-by-step directions for how to do this on the latest revs of LiteSpeed / Rack? I'm having trouble following the instructions documented earlier in this thread and have been unable to find any other examples.
  16. fantasydreaming

    fantasydreaming New Member

    Bump! Any tips on this? Rails 3 is coming soon and this tutorial would be nice to have.

    Any pros/cons on using rack vs. the default lsapi?

Share This Page