Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add lifecycle callbacks #1184

Closed
tobymurray-nanometrics opened this issue Sep 16, 2016 · 5 comments
Closed

Add lifecycle callbacks #1184

tobymurray-nanometrics opened this issue Sep 16, 2016 · 5 comments

Comments

@tobymurray-nanometrics
Copy link

Description

Looking at the (admittedly not super popular) questions on StackOverflow like this and this, I think it'd be handy to have some usable lifecycle callbacks for Sinatra. In particular, a callback when Sinatra is completely set up and a callback when Sinatra has completely stopped.

Use case

We use JRuby for a Rails application, but we also use Java code. The Ruby code calls out to a Java HTTP client, so when we're writing tests for that code we can't use any Ruby mocking libraries. Instead of an elaborate refactor whereby a mock Java HTTP client can be injected for testing, we use a number of tiny Sinatra servers that have very simple and predetermined responses to "mock" the third party servers. So far it has worked excellently, and allows us to keep our testing and production code very similar (mocks have bitten us by not failing in ways their production equivalents would).

To accomplish this, we've mashed together something like the linked answers above whereby we block until Sinatra has started. Unfortunately, there doesn't seem to be a similar solution for stop!, so rapidly starting and stopping Sinatra servers occasionally fails (client can't connect). My suspicion right now is that the previous Sinatra server has not fully stopped before the next one is attempting to start.

For us it'd be extremely useful to have an on_start and on_quit (with whatever names are appropriate for the lifecycle which would indicate Sinatra is completely up, running, and ready to go and completely stopped).

@zzak
Copy link
Member

zzak commented Dec 14, 2016

@tobymurray-nanometrics I am open to the idea. Could you submit a patch?

@zzak zzak added this to the Beyond milestone Dec 14, 2016
@tobymurray-nanometrics
Copy link
Author

I could take a look at it, sure. No guarantees on timeliness...

If anyone is looking for the same functionality from the current Sinatra, we've added an extra layer on top of Sinatra::Base to give us the start the server, execute some code, then stop the server. It's a bit hacky, but it's worked very well for us - exclusively in a test environment. Here's the code:

require 'sinatra/base'

class TestSinatraBase < Sinatra::Base
  SERVER_STARTED_SUCCESSFULLY = true
  SERVER_FAILED_TO_START = false

  def self.start_and_block_until_running(opts)
    queue = Queue.new
    @@server_thread = Thread.new do
      begin
        run!(opts) do
          queue.push SERVER_STARTED_SUCCESSFULLY
        end
      ensure
        queue.push SERVER_FAILED_TO_START if queue.empty?
      end
    end
    successful = queue.pop # Blocks until the the app has started and the block provided to `run!` executes
    raise "Sinatra server failed to start, look at the logs for more information." unless successful
  end

  def self.execute_test(opts)
    start_and_block_until_running(opts)

    begin
      yield if block_given?
    ensure
      stop!
      @@server_thread.join(10) if @@server_thread&.alive?
    end
  end
end

@jevin
Copy link
Contributor

jevin commented Mar 17, 2023

Taking this! Will have something early next week.

@jevin
Copy link
Contributor

jevin commented Mar 26, 2023

The PR is ready for this. If anyone could have a look that would be wonderful!

dentarg added a commit that referenced this issue Jul 11, 2023
This PR adds lifecycle events to Sinatra. Related issue: #1184

Co-authored-by: Patrik Ragnarsson <patrik@starkast.net>
@dentarg
Copy link
Member

dentarg commented Jul 11, 2023

Resolved by #1913

@dentarg dentarg closed this as completed Jul 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants