Module: Led

Defined in:
lib/led.rb

Class Method Summary collapse

Class Method Details

.add_script(name, script) ⇒ Object



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

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



12
13
14
# File 'lib/led.rb', line 12

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

.conn=(conn) ⇒ Object



8
9
10
# File 'lib/led.rb', line 8

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

.handle_command_error(e, method) ⇒ Object



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

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



83
84
85
86
# File 'lib/led.rb', line 83

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

.method_missing(m, *args) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/led.rb', line 26

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



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

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



69
70
71
72
73
# File 'lib/led.rb', line 69

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



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

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



79
80
81
# File 'lib/led.rb', line 79

def self.script_dir
  @script_dir
end

.script_dir=(dir) ⇒ Object



75
76
77
# File 'lib/led.rb', line 75

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