2010-04-07 7 views
6

Tengo una aplicación Sinatra incluida en Sinatra::Base y me gustaría ejecutar algún código una vez que el servidor ha comenzado, ¿cómo debo hacer esto?Ejecutar el código una vez que se ejecuta el servidor Sinatra

He aquí un ejemplo:

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 

¿Alguna idea?

+0

Es posible que necesite ser más específico para obtener ayuda. – Beanish

+0

Tienes razón, pensé que se explicaba por sí mismo. veamos cómo estas modificaciones ayudan a –

+1

Esto no es lo que pediste, pero deberías estar requiriendo 'sinatra/base', no' sinatra'. De http://www.sinatrarb.com/intro.html#Sinatra::Base%20-%20Middleware,%20Libraries,%20and%20Modular%20Apps: "Su archivo debe requerir sinatra/base en lugar de sinatra; de lo contrario, todos de los métodos DSL de Sinatra se importan en el espacio de nombres principal ". – mwp

Respuesta

4

Usar el bloque de configuración no es la forma correcta de hacerlo. Siempre que cargue el archivo, se ejecutarán los comandos.

Try extendiendo 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

Si desea que su código se ejecute _después_ de inicio, es posible que desee tener la llamada a 'super' primero en el método. – matt

+1

Además, esto es mejor que usar 'configure' para que su código de obtención se ejecute después del inicio del servidor, pero solo funcionará para el servidor integrado: no funcionará si usa p. Ej. 'rackup' o' thin start'. – matt

+0

@matt en realidad si llamas a Launchy después de super nunca se alcanzará, lo probé. settings.host no funcionaba tan bien, lo reemplacé a localhost ya que lo estoy usando solo localmente. –

2

Así es como lo hago; básicamente que ejecuta Sinatra u otro código en un hilo separado:

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

La única respuesta válida en stackoverflow a esta pregunta (que se preguntó 3-4 veces) viene dada por levinalex en Start and call Ruby HTTP server in the same script, y cito:

run! in current Sinatra versions toma un bloque que se llama cuando se inicia la aplicación.

El uso de devolución de llamada que usted puede hacer esto:

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') 

Ésta parece ser fiable para WEBrick, pero cuando se utiliza la devolución de llamada delgada está siendo llamado a veces un poco antes de que el servidor acepta conexiones.

1

Si está utilizando rack (que probablemente son) Me acabo de enterar que hay una función que puede llamar en config.ru (que es técnicamente un método de instancia de Rack::Builder) que le permite ejecutar un bloque de código después de que el servidor ha comenzado. Se llama warmup, y aquí está el ejemplo de uso documentado:

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

use SomeMiddleware 
run MyApp 
+0

Esto funciona muy bien con la llamada Launchy.open() en la pregunta original. Aunque probablemente sea una buena idea comprobar primero ENV ['RACK_ENV'] == "desarrollo", ya que probablemente no desee que esta ejecución se produzca. – dwkns

Cuestiones relacionadas