2010-04-07 10 views
6

Ich habe eine Sinatra-Anwendung in Sinatra::Base beigefügt und ich möchte etwas Code ausführen, sobald der Server gestartet hat, wie soll ich das tun?Code einmal ausführen Sinatra-Server läuft

Hier ist ein Beispiel:

require 'sinatra' 
require 'launchy' 

class MyServer < Sinatra::Base 
    get '/' do 
    "My server" 
    end 

    # This is the bit I'm not sure how to do 
    after_server_running do 
    # Launches a browser with this webapp in it upon server start 
    Launchy.open("http://#{settings.host}:#{settings.port}/") 
    end 
end 

Irgendwelche Ideen?

+0

Unter Umständen müssen Sie genauer sein, um etwas Hilfe zu bekommen. – Beanish

+0

Sie haben wahrscheinlich Recht - ich dachte, es war selbsterklärend! Sehen wir uns an, wie diese Änderungen helfen –

+1

Das ist nicht das, was Sie gefragt haben, aber Sie sollten 'sinatra/base', nicht' sinatra' verlangen. Von http://www.sinatrarb.com/intro.html#Sinatra::Base%20-%20Middleware,%20Libraries,%20and%20Modular%20Apps: "Ihre Datei sollte Sinatra/Base anstelle von Sinatra erfordern; andernfalls alle von Sinatras DSL-Methoden werden in den Hauptnamensraum importiert. " – mwp

Antwort

4

Die Verwendung des Konfigurationsblocks ist nicht die richtige Vorgehensweise. Wann immer Sie die Datei laden, werden die Befehle ausgeführt.

Versuchen erstreckt run!

require 'sinatra' 
require 'launchy' 

class MyServer < Sinatra::Base 

    def self.run! 
    Launchy.open("http://#{settings.host}:#{settings.port}/") 
    super 
    end 

    get '/' do 
    "My server" 
    end 
end 
+2

Wenn Sie möchten, dass Ihr Code nach dem Start ausgeführt wird, möchten Sie möglicherweise zuerst den Aufruf von "super" in der Methode aufrufen. – matt

+1

Dies ist auch besser als die Verwendung von 'configure' blockiert Ihren Code zum Ausführen nach dem Serverstart, aber funktioniert nur für den eingebauten Server - er funktioniert nicht, wenn Sie z. 'Rackup' oder' Thin Start'. – matt

+0

@matt tatsächlich, wenn Sie Launchy nach Super anrufen, wird es nie erreicht werden, habe ich es ausprobiert. settings.host funktionierte nicht so gut, ich ersetzte es zu localhost, da ich es nur lokal verwende. –

2

Dies ist, wie ich es tun; im Grunde entweder sinatra oder anderen Code in einem separaten Thread ausgeführt wird:

require 'sinatra/base' 

Thread.new { 
    sleep(1) until MyApp.settings.running? 
    p "this code executes after Sinatra server is started" 
} 
class MyApp < Sinatra::Application 
    # ... app code here ... 

    # start the server if ruby file executed directly 
    run! if app_file == $0 
end 
0

Die einzige gültige Antwort in Stackoverflow auf diese Frage (die 3-4 mal gefragt wird) durch levinalex auf Start and call Ruby HTTP server in the same script gegeben ist, und ich zitiere:

run! in current Sinatra versions nimmt einen Block, der aufgerufen wird, wenn die App gestartet wird.

Mit Hilfe dieser Rückruf Sie können dies tun:

require 'thread' 

def sinatra_run_wait(app, opts) 
    queue = Queue.new 
    thread = Thread.new do 
    Thread.abort_on_exception = true 
    app.run!(opts) do |server| 
     queue.push("started") 
    end 
    end 
    queue.pop # blocks until the run! callback runs 
end 

sinatra_run_wait(TestApp, :port => 3000, :server => 'webrick') 

Diese für WEBrick als zuverlässig scheint, aber bei der Verwendung von Thin der Rückruf ist noch manchmal ein wenig, bevor der Server-Verbindungen akzeptiert.

1

Wenn Sie mit Rack (die Sie wahrscheinlich sind) Ich habe gerade herausgefunden es eine Funktion ist können Sie in config.ru nennen (es ist technisch eine Instanzmethode von Rack::Builder), die Sie nach dem Server ausführen einen Code-Block lässt wurde gestartet. Es ist warmup genannt, und hier ist das dokumentierte Anwendungsbeispiel:

warmup do |app| 
    client = Rack::MockRequest.new(app) 
    client.get('/') 
end 

use SomeMiddleware 
run MyApp 
+0

Das funktioniert wirklich gut mit dem Launchy.open() - Aufruf in der ursprünglichen Frage. Obwohl es wahrscheinlich eine gute Idee ist, zuerst nach ENV ['RACK_ENV'] == "development" zu suchen, da Sie diesen Lauf in der Produktion wahrscheinlich nicht wollen. – dwkns