Module: Led

Defined in:
lib/led.rb,
lib/model.rb

Defined Under Namespace

Classes: Model

Class Method Summary collapse

Class Method Details

.add_script(name, script) ⇒ Object



18
19
20
21
22
23
24
25
26
# File 'lib/led.rb', line 18

def self.add_script(name, script)
  @shas ||= {}
  @scripts ||= {}

  script = preprocess(script)
  
  @shas[name.to_sym] = conn.script('load', script)
  @scripts[name.to_sym] = script
end

.connObject



14
15
16
# File 'lib/led.rb', line 14

def self.conn
  @conn ||= Redis.new
end

.conn=(conn) ⇒ Object



10
11
12
# File 'lib/led.rb', line 10

def self.conn= (conn)
  @conn = conn
end

.handle_command_error(e, method) ⇒ Object



48
49
50
51
52
53
54
55
56
57
# File 'lib/led.rb', line 48

def self.handle_command_error(e, method)
  if e.message =~ /^ERR.+user_script\:([0-9]+)\: (.+)$/
    raise e, "#{method}.lua:#{$1}: #{$2}"
  elsif e.message =~ /^([A-Z][a-zA-Z_0-9]+)(?:\:(.+))?/
    klass = (Object.const_get($1) rescue Redis::CommandError)
    raise klass, ($2 || '')
  else
    raise e
  end
end

.load_script(name) ⇒ Object



85
86
87
88
# File 'lib/led.rb', line 85

def self.load_script(name)
  script = IO.read(File.join(script_dir, "#{name}.lua"))
  add_script(name, script)
end

.method_missing(m, *args) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/led.rb', line 28

def self.method_missing(m, *args)
  unless @shas && @shas[m]
    @script_dir ? load_script(m) : super
  end
  
  run_script(m, *args)
end

.preprocess(script) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/led.rb', line 59

def self.preprocess(script)
  script.
    # redis.call shorthand
    gsub(/([A-Z]+)\(/) {"redis.call('#{$1}',"}.
    # string interpolation
    gsub(/\#\{([^\}]+)\}/) {"\" .. #{$1} .. \""}.
    # remove empty string concatenation
    gsub(/\s\.\.\s''/, ' ').
    gsub(/[^\\]''\s\.\.\s/, ' ').
    gsub(/\__include '([^\s]+)'/) {process_include($1)}
end

.process_include(file) ⇒ Object



71
72
73
74
75
# File 'lib/led.rb', line 71

def self.process_include(file)
  raise "Script directory not specified" unless @script_dir
  
  IO.read(File.join(@script_dir, "#{file}.lua"))
end

.run_script(m, *args) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/led.rb', line 36

def self.run_script(m, *args)
  conn.evalsha(@shas[m], [], args)
rescue Redis::CommandError => e
  # detect if script needs to be reloaded
  if e.message =~ /NOSCRIPT/
    @shas[m] = conn.script('load', @scripts[m])
    conn.evalsha(@shas[m], [], args)
  else
    handle_command_error(e, m)
  end
end

.script_dirObject



81
82
83
# File 'lib/led.rb', line 81

def self.script_dir
  @script_dir
end

.script_dir=(dir) ⇒ Object



77
78
79
# File 'lib/led.rb', line 77

def self.script_dir=(dir)
  @script_dir = dir
end