1

My Sinatra-based ruby app works just fine locally, however, when I push it to CloudFoundry, the page times out before the app prints the results on the page (Says: "hc.run.company.com took too long to respond. HTTP ERROR 504). This is my main.rb:

require 'rest-client'
require 'sinatra'
require 'open-uri'
require 'net/http'
require 'dir'
require 'json'
# require 'sinatra/async'
# require 'socket'

class DevMonit < Sinatra::Base
    # register Sinatra::Async

    @@services = Array.new

    def self.register(service)
        @@services << service
    end

    get '/url/:url' do
        url = params[:url].to_s # Store 'url' parameter
        is_verbose = params[:v].to_s # Store 'v' parameter

    # stream :keep_open do |out|
    #   print 'out = '  # DEBUG
    #   p out # DEBUG
    #   check_status(url, is_verbose) do |x|
    #       out << "x=#{x}"
    #       out.close
    #  end
    # end

    return check_status(url, is_verbose)
    end

    def verbose(is_verbose)
        if !is_verbose.nil? && is_verbose == 'true'
            return true
        else
            return false
        end
    end

    def check_status(uri_str, is_verbose, limit = 10)
    response = RestClient.get "#{uri_str}"

        case response.code
            when 200...300
                @@services.each do |service|
                    if service.is_matched?("#{uri_str}")
                        tool_name = service.class.name.split('::').last.downcase # Fetch the name of the Class for the tool_name
                        @@result = service.check_tool_specific("#{tool_name}","#{uri_str}", "#{verbose(is_verbose)}")
                    end
                end

                if @@result.nil?
                    return 'No results, something went wrong!'
                end

                return "#{@@result.to_json}"

      when Net::HTTPRedirection then
                location = response['location']
                check_status(location, limit - 1)
            else
                puts "It doesn't work!"
                puts "#{response.code}"
    end
  rescue SocketError => e; #do something with e.message
    return {
        :url => uri_str,
        :timestamp => Time.now.strftime('%Y-%m-%d %T'),
        :results => 'Cannot resolve the hostname'
    }
    end
    run! if app_file == $0
end

I am trying to have a thread that feeds the browser something to keep it alive (HTTP CODE 200?) while it's executing the return check_status(url, is_verbose) or at if service.is_matched?("#{uri_str}"). The reason why I am trying to do this is because the app triggers a Jenkins job and waits for it to finish which then the app takes the necessary information puts it in a json format (which is the output), then outputs it from return "#{@@result.to_json}".

I've been reading on how to do this but, I can't make it work, (I've tried doing something with sockets and that failed miserably, I also tried doing something like this and that didn't work either).

Any kind of guidance is appreciated.

UPDATE:

This is the code where it takes the longest time (waits for Jenkins job to finish to pull required information):

# require 'em-http-request'

class WaitForJob
  def self.job(current_build_json, last_build_json, start_job)
    job_result_hash = Hash.new{|hsh,key| hsh[key] = {} } # Initialize a Hash for storing the results
    start_job.send_request # Start the Jenkins Job
    get_current_build_number = CheckJSON.get_from_json("#{current_build_json.send_request}", 'nextBuildNumber') # Fetch the nextBuildNumber as soon as the job starts (as that doesn't increment while it's in queue); the nextBuildNumber is going to be the currentBuildNumber
    current_build_number = get_current_build_number.to_i # Save that nextBuildNumber to a separate variable for comparison
    get_last_build_number = CheckJSON.get_from_json("#{last_build_json.send_request}", 'number')
    get_last_build_duration = CheckJSON.get_from_json("#{last_build_json.send_request}", 'duration')
    get_last_build_result = nil
    loop do
      Timeout::timeout(120) do
        # EM.run do
          sleep(5) # DEBUG
          get_last_build_number = CheckJSON.get_from_json("#{last_build_json.send_request}", 'number')
          get_last_build_result = CheckJSON.get_from_json("#{last_build_json.send_request}", 'result')
          get_last_build_duration = CheckJSON.get_from_json("#{last_build_json.send_request}", 'duration')

          # conn = EM::HttpRequest.new('http://localhost:9000/')
          # start = Time.now

          # r1 = conn.get :query => {delay: 1.5}, :keepalive => true
          # r2 = conn.get :query => {delay: 1.0}

          # r2.callback do
          #   p Time.now - start # =>  1.5 - keep-alive + pipelining
          #   EM.stop
          # end
        # end
      end
      break if !get_last_build_result.nil? && !get_last_build_duration.zero? && (current_build_number == get_last_build_number) # End the loop when job is done
    end

    job_name = "#{CheckJSON.get_from_json("#{last_build_json.send_request}", 'fullDisplayName')}" # Fetch job's name
    job_name = job_name.split(/ |\./) # Splits the job_name using '.' and ' ' as delimiters

    job_result_hash['job_type'] = "#{job_name[3]}" # This takes the last part of the jenkins job name (Ex: Dev.eng-paas.devtools.TESTING_INTEGRATION_JOB)
    job_result_hash['build_number'] = "#{current_build_number}" # Return the build number also which can be used in different situations
    job_result_hash['job_duration'] = "#{CheckJSON.get_from_json("#{last_build_json.send_request}", 'duration')}" # Fetches the duration of job
    job_result_hash['job_result'] = "#{CheckJSON.get_from_json("#{last_build_json.send_request}", 'result').downcase}" # Fetches if the job was successful/unstable/failure
    return job_result_hash
  end
end
Community
  • 1
  • 1
Fadi
  • 1,329
  • 7
  • 22
  • 40
  • What part of the request is taking so long? How long, exactly, is it taking before it times out? You could try the [Sinatra::Streaming](http://www.sinatrarb.com/contrib/streaming.html) module to respond incrementally. – Jordan Running Nov 10 '16 at 22:28
  • Here's three options for you: 1. Try and configure your server's KEEP_ALIVE time 2. Have the client ping the server for a response via AJAX 3. Try again with websockets! – max pleaner Nov 11 '16 at 00:34
  • Check the update Jordan. I've put the part of where it takes the longest. And it takes about 60 seconds then times out.. – Fadi Nov 11 '16 at 14:08

0 Answers0