0

I am still very new to rails and programming in general please help me in anyway, thanks ahead of time!

I wrote a small bot that works perfectly on my local system but then does nothing when I upload it.

My html.erb just calls the bot method below. It is an infinite loop but on the local server it just allows the bot to basically run in the background while the page is loading forever, which works for me. I know that the app is deployed correctly because I commented out the bot method and just had things print on a blank page and that works perfectly. So it has to do with something in my bot method. The only problem is that when I leave the bot method running on the heroku environment a page pops up saying "We're sorry something went wrong" and tells me to check log, except the log doesn't give me any errors only a ping notification:

Apr 26 23:34:08 guarded-falls-5003 heroku/router: at=info method=GET path="/" host=guarded-falls-5003.herokuapp.com request_id=ae3616c7-2ff6-4bdd-9738-03a2cc291f96 fwd="50.31.164.139" dyno=web.1 connect=2ms service=13ms status=500 bytes=1754

This is the controller.rb

require 'rubygems' 
require 'watir-webdriver' 
require 'phantomjs'

def time(t)
      mm, ss = t.divmod(60)
      hh, mm = mm.divmod(60)        
      dd, hh = hh.divmod(24)       
      return "%d days, %d hours, %d minutes and %d seconds  " % [dd, hh, mm, ss]
  end 

  def remaining_time(delay)
    time = Time.now.to_f
    fin = delay + time

    while fin > time
      time = Time.now.to_f
      @finished = "Current delay is #{time(fin-time)} \r"
      sleep 1;
    end
    print "\n"
  end


  ####################################################################
  #                          bot                                     #
  ####################################################################

def bot

  # bots login information
  name = "*******"
  email = "**********"
  password = "*********"

  #channel they are posting to on output website
  channel = "Sports"


  ####################################################################
  # set the following url to the channel you would like to pull from #
  ####################################################################

  # input website (video)
  url = "**************"

  ####################################################################
  #                          bot code                                #
  ####################################################################

  video = ""

  ########################### Loop ###################################

  loop do

    # Starts the Browser, enters URL, and goes to the videos page
    browser = Watir::Browser.new :phantomjs
    browser.goto(url + "/videos")
    # click on the class for the link of the video. Note that this just clicks on the first one it finds
    browser.link(:class, "yt-uix-sessionlink yt-uix-tile-link  spf-link  yt-ui-ellipsis yt-ui-ellipsis-2").click

    # Checks if the current video is already stored as the video variable 
      if video != browser.url

        # Set video variable to current url
        video = browser.url

        # Close and open a new video because phantomjs bugs out when you try 
        # to change websites on an already existing window
        browser.close
        browser = Watir::Browser.new :phantomjs

        # goto output website sign in page and sign in
        browser.goto "**************" 
        browser.text_field(:id, "user_email").set(email)
        browser.text_field(:id, "user_password").set(password)
        browser.button(:value,"Sign in").click

        # Upload the video (resize because search bar is hidden at default size)
        browser.window.resize_to(1600, 1000)
        browser.text_field(:id, "q").set(video)
        browser.button(:text, "Upload").click
        browser.select_list(:id, "video_channel_id").select(channel)
        # browser.button(:text,"Create Video").click

        puts "uploaded #{video}"
        remaining_time(delay)

        $stdout.flush
        sleep(delay)

        # Exit Browser
        browser.close 

      else

        browser.close

        puts "Did not upload anything. The video has already been uploaded." 
        remaining_time(delay) 

        $stdout.flush
        sleep(delay)

      end



  end 

end

Gemfile

source 'https://rubygems.org'

gem 'newrelic_rpm'
gem 'phantomjs'
gem 'watir-webdriver'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc

# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Unicorn as the app server
# gem 'unicorn'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'

  # Access an IRB console on exception pages or by using <%= console %> in views
  gem 'web-console', '~> 2.0'

  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

Any ideas?

Alex
  • 317
  • 3
  • 14
  • hi and welcome to stack overflow. So my first easy recommendation would be "printf debugging"... ie, add logger calls at each of the major branches (before the loop, just inside of the loops etc) each with different messages explaining what point in the code you're up to... and see at what point the code gets to before it dies. – Taryn East Apr 27 '15 at 06:53
  • My other recommendation would be to: remove the loop... test what happens if the bot just tries this once and then ends... – Taryn East Apr 27 '15 at 06:54

2 Answers2

0

Heroku has a request timeout of 30 seconds for HTTP requests that can not be changed. So while leaving the page loading will work, it will eventually terminate when the request is timed out.

The Heroku way of running this would be to use a background worker.

Drenmi
  • 8,492
  • 4
  • 42
  • 51
  • Do you know if there is a way to structure the app so that it can all only use the worker type dyno as my 1 free dyno rather then having to use the web dyno since the entire process I am looking to create is happing server side anyways? – Alex Apr 28 '15 at 00:39
  • Or is there a way to automatically stop everything from running if I reach a certain dyno hour limit in heroku so that I can just shut everything down at their 750 free hour limit? which, if I am running this program continuously with two dynos I assume would have to be half way through the month. – Alex Apr 28 '15 at 00:43
0

Are you using Watir ?

To use PhantomJS on Heroku, you'll need to use a Heroku PhantomJS buildpack

Check this answer as well:

Can you deploy Watir on Heroku to generate HTML Snapshots? If so, how?

Community
  • 1
  • 1
mohamed-ibrahim
  • 10,837
  • 4
  • 39
  • 51
  • I was trying but I think this pages solution fixed it. http://stackoverflow.com/questions/12495463/how-to-run-phantomjs-on-heroku – Alex Apr 28 '15 at 00:28
  • Thanks for pointing me in the right direction! and now it looks like I'm running into what the other comment was saying where my page is timing out. – Alex Apr 28 '15 at 00:29
  • Heroku timeout issue is a known issue, your request should spend at max 30 sec, if you expect your request will take more you have 2 options, 1- make it a delayed job and run it in the background so your request will respond fast, 2- if you really need to proecess it now and you can divide the request into more than 1 request that each can take less than a 30 sec so keep sending requests form front-end using ajax and in success of each you can send the second or even you can send them all and track when they all completed. – mohamed-ibrahim Apr 28 '15 at 11:04