2

Trying to send an event from within Rufus Schedulers results in this error:

{ 70231586340180 rufus-scheduler intercepted an error:
  70231586340180   job:
  70231586340180     Rufus::Scheduler::IntervalJob "2s" {}
  70231586340180   error:
  70231586340180     70231586340180
  70231586340180     NameError
  70231586340180     undefined local variable or method `connections' for main:Object
  70231586340180       picture-frame.rb:31:in `send_event'
  70231586340180       picture-frame.rb:24:in `block in <main>'
...

It seems like I can't access connections from within the Rufus Job. How can I fix this? This is my code:

require 'sinatra'
require 'rufus-scheduler'
require 'json'


set :server, :thin
connections = []
scheduler = Rufus::Scheduler.new


get '/' do
    erb :index
end

get '/events', provides: 'text/event-stream' do
  stream :keep_open do |out|
    connections << out
    connections.reject!(&:closed?)
  end
end

scheduler.interval '2s' do
    random = (0...8).map { (65 + rand(26)).chr }.join
    send_event('random', { random: random })
end

def send_event(id, body)
  body[:id] = id

  event = "data: #{body.to_json}"
  connections.each { |out| out << event }
end
multiholle
  • 3,050
  • 8
  • 41
  • 60
  • 2
    `connections` is local to the file but is out of context in the method (change in lexical scope). If you really must then make it an instance variable `@connections` this will change the scope but `@connections` will now be an instance variable in the context of `main` which seems unwieldy. – engineersmnky Apr 18 '17 at 17:19
  • another way to do it would be to capitalize the c so it is a constant. – max pleaner Apr 19 '17 at 02:07
  • @engineersmnky How do I put connections in the context of my Sinatra application? – multiholle Apr 19 '17 at 08:27

1 Answers1

2

And here is a version with global variables.

How do I put connections in the context of my Sinatra application?

Sorry, with this $connections and $scheduler it's in the context of the whole Ruby process, but for a limited script/service, it's OK.

require 'sinatra'
require 'rufus-scheduler'
require 'json'


set :server, :thin
$connections = []
$scheduler = Rufus::Scheduler.new


get '/' do
    erb :index
end

get '/events', provides: 'text/event-stream' do
  stream :keep_open do |out|
    $connections << out
    $connections.reject!(&:closed?)
  end
end

def send_event(id, body)

  body[:id] = id

  event = "data: #{body.to_json}"
  $connections.each { |out| out << event }
end

$scheduler.interval '2s' do

  random = (0...8).map { (65 + rand(26)).chr }.join
  send_event('random', { random: random })
end
jmettraux
  • 3,511
  • 3
  • 31
  • 30