ruby-on-railsrubyoracle-databasedashing

Undefined local variable or method `conn' for main:Object (NameError) on Dashing start


I am trying to setup a Dashing dashboard for some monitoring. The data to be used to populate the dashboards widgets will be coming from an Oracle database. Dashing has been installed and the test dashboards are working fine but when I created my own job to populate a widget with data from the Oracle instance dashing fails to start, the following error is displayed

<pre>/home/{home}/dashboard/jobs/new.rb:25:in `<top (required)>': undefined local variable or method `conn' for main:Object (NameError)
    from /usr/local/lib/ruby/gems/2.0.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in `require'
    from /usr/local/lib/ruby/gems/2.0.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in `require_with_backports'
    from /usr/local/lib/ruby/gems/2.0.0/gems/dashing-1.3.7/lib/dashing/app.rb:171:in `block in require_glob'
    from /usr/local/lib/ruby/gems/2.0.0/gems/dashing-1.3.7/lib/dashing/app.rb:170:in `each'
    from /usr/local/lib/ruby/gems/2.0.0/gems/dashing-1.3.7/lib/dashing/app.rb:170:in `require_glob'
    from /usr/local/lib/ruby/gems/2.0.0/gems/dashing-1.3.7/lib/dashing/app.rb:181:in `<top (required)>'
    from /usr/local/lib/ruby/gems/2.0.0/gems/dashing-1.3.7/lib/dashing.rb:3:in `require'
    from /usr/local/lib/ruby/gems/2.0.0/gems/dashing-1.3.7/lib/dashing.rb:3:in `<top (required)>'
    from config.ru:1:in `require'
    from config.ru:1:in `block in <main>'
    from /usr/local/lib/ruby/gems/2.0.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in `instance_eval'
    from /usr/local/lib/ruby/gems/2.0.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in `initialize'
    from config.ru:1:in `new'
    from config.ru:1:in `<main>'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/lib/rack/adapter/loader.rb:33:in `eval'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/lib/rack/adapter/loader.rb:33:in `load'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/lib/thin/controllers/controller.rb:182:in `load_rackup_config'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/lib/thin/controllers/controller.rb:72:in `start'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/lib/thin/runner.rb:200:in `run_command'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/lib/thin/runner.rb:156:in `run!'
    from /usr/local/lib/ruby/gems/2.0.0/gems/thin-1.6.4/bin/thin:6:in `<top (required)>'
    from /usr/local/bin/thin:23:in `load'
    from /usr/local/bin/thin:23:in `<main>'</pre>

The ruby code (new.rb) being run is

<pre>require 'rubygems'
require 'oci8'

# :first_in sets how long it takes before the job is first run. In this case, it is run immediately
SCHEDULER.every '15m', :first_in => 0 do |job|

tnsname = '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = {ORACLE_SERVER})(PORT = 1521)) (CONNECT_DATA = (SID = {SID})))'

conn = OCI8.new('{USER}', '{PASS}', tnsname)

last_value = rowitem

cursor = conn.parse("SELECT count(status) AS status_count FROM generation WHERE billcycle is NULL AND status = '13'")
cursor.define(1, Integer)
cursor.exec()
rowitem = []

while r = cursor.fetch()
        rowitem = r
end

send_event('new', { current: rowitem, last: last_value } )
cursor.close()
end
conn.logoff</pre>

Commenting out the SCHEDULER & send_event lines allows the script to be run manually and results are returned as expected.

This is my 1st time using Ruby so excuse any obvious mistakes but if anyone can help getting this to work I will be grateful.


Solution

  • The error message tells you everything you need to know: The conn variable is not defined, on line 25:

    SCHEDULER.every '15m', :first_in => 0 do |job|
      # ...
    
      conn = OCI8.new('{USER}', '{PASS}', tnsname)
    
      # ...
    end
    
    conn.logoff
    

    You defined conn inside the scope of the block, then tried to access it from outside. That is not how variables work - you cannot access them from outside of where they are defined.

    A trivial fix is to move the logoff method call up inside the block:

    SCHEDULER.every '15m', :first_in => 0 do |job|
      # ...
    
      conn = OCI8.new('{USER}', '{PASS}', tnsname)
    
      # ...
    
      conn.logoff
    end