Module: Flydata::Command::ExclusiveRunnable::ClassMethods

Defined in:
lib/flydata/command/exclusive_runnable.rb

Instance Method Summary collapse

Instance Method Details

#command(subcommand, options = {}) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/flydata/command/exclusive_runnable.rb', line 69

def command(subcommand, options = {})
  return options[:command] if options[:command]

  modules = self.name.split('::')

  cmd = modules.last.downcase
  subcommand == :run ? cmd : "#{cmd}:#{subcommand}"
end

#delete_exclusive_run_infoObject



64
65
66
67
# File 'lib/flydata/command/exclusive_runnable.rb', line 64

def delete_exclusive_run_info
  path = exclusive_run_info_path
  File.delete(path) if File.exists?(path)
end

#exclusive_run_homeObject



42
43
44
# File 'lib/flydata/command/exclusive_runnable.rb', line 42

def exclusive_run_home
  @@exclusive_run_home
end

#exclusive_run_home=(value) ⇒ Object



45
46
47
# File 'lib/flydata/command/exclusive_runnable.rb', line 45

def exclusive_run_home=(value)
  @@exclusive_run_home = value
end

#exclusive_run_info_pathObject



48
49
50
# File 'lib/flydata/command/exclusive_runnable.rb', line 48

def exclusive_run_info_path
  File.join(exclusive_run_home, "exclusive_run.info")
end

#load_exclusive_run_infoObject



52
53
54
55
56
57
# File 'lib/flydata/command/exclusive_runnable.rb', line 52

def load_exclusive_run_info
  path = exclusive_run_info_path
  return nil unless File.exists?(path)

  JSON.parse(File.open(path){|f| f.read})
end

#run_exclusive(method, options = {}) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/flydata/command/exclusive_runnable.rb', line 14

def run_exclusive(method, options = {})
  saved_method = :"__#{method}"
  alias_method saved_method, method

  define_method(method) do |*args|
    result = nil
    exclusive_run_info = nil
    begin
      info = self.class.load_exclusive_run_info
      if info
        #TODO If the previous command terminates abnormally, 
        # 'exclusive_run.info' file won't be deleted even the pid 
        # doesn't exist anymore. 
        # This prevents execution of any commands afterwards, and 
        # the user will see this misleading error message. 
        # Introducing "--force-run" option can be a solution. 

        raise "Command `#{info['command']}` is already running.  Wait until the command completes or stop the command.  (pid:#{info['pid']})"
      end
      exclusive_run_info = { command: self.class.command(method, options), pid: Process.pid }
      self.class.save_exclusive_run_info(exclusive_run_info)
      result = send(saved_method, *args)
    ensure
      self.class.delete_exclusive_run_info if exclusive_run_info
    end
    result
  end
end

#save_exclusive_run_info(info) ⇒ Object



59
60
61
62
# File 'lib/flydata/command/exclusive_runnable.rb', line 59

def save_exclusive_run_info(info)
  path = exclusive_run_info_path
  File.open(path, "w"){|f| f.write(info.to_json)}
end