Class: Exedb

Inherits:
Object
  • Object
show all
Defined in:
lib/exedb.rb,
lib/exedb/version.rb

Overview

Database-like interface for long-running tasks.

Each instance can run single command (get). If two or more instances with the same command do ‘get’, then only first will really execute command, all others will wait for result (flock is used).

Results of command execution (stdout) is cached. Next ‘get’ will return cached results (unless cache timeout happened).

You can force execution, calling ‘update’ method.

Exit code is available via ‘code’ method

Constant Summary collapse

SLEEP_TIME =
1
DEF_DIR =
'/tmp/Exedb'
DEF_CACHE_TIMEOUT =
60
VERSION =
"0.1.1"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str = '') ⇒ Exedb

Constructor



31
32
33
34
35
36
37
38
# File 'lib/exedb.rb', line 31

def initialize(str='')
  @update_time=Time.parse("1970-01-01")
  @cache_timeout=DEF_CACHE_TIMEOUT
  @cache_dir=DEF_DIR
  @code=-1
  Dir.mkdir DEF_DIR unless File.directory? DEF_DIR
  self.update_method=(str)
end

Instance Attribute Details

#cache_dirObject

Returns the value of attribute cache_dir.



25
26
27
# File 'lib/exedb.rb', line 25

def cache_dir
  @cache_dir
end

#cache_timeoutObject

Returns the value of attribute cache_timeout.



25
26
27
# File 'lib/exedb.rb', line 25

def cache_timeout
  @cache_timeout
end

#update_timeObject (readonly)

Returns the value of attribute update_time.



26
27
28
# File 'lib/exedb.rb', line 26

def update_time
  @update_time
end

Instance Method Details

#cache_stateObject

Returns symbol of cache state:

  • updated = actual

  • need_update = new command execution needed

  • need_reread = just cache file reread is neede



131
132
133
134
135
136
137
138
139
# File 'lib/exedb.rb', line 131

def cache_state
  if File.exists? @path
    mtime=File.mtime(@path)
    return :need_update if mtime+@cache_timeout<Time.now
    return :need_reread if @update_time<mtime
    return :updated
  end
  :need_update
end

#codeObject

Get last execution return code. NOTE!!! It is also cached, even on error.



108
109
110
111
# File 'lib/exedb.rb', line 108

def code
  actualize
  @code
end

#getObject

Get last execution result (stdout), or start new command execution and return result if cache is invalid.



99
100
101
102
# File 'lib/exedb.rb', line 99

def get
  actualize
  @content
end

#peekObject

Do not execute command - just peek in cache file… Usefull for intermediate command output peeking



117
118
119
120
121
122
123
# File 'lib/exedb.rb', line 117

def peek
  begin
    File.read(@path)      
  rescue
    ''
  end
end

#put(str) ⇒ Object

Just alias for update_method=



90
91
92
# File 'lib/exedb.rb', line 90

def put(str)
  self.update_method=(str)
end

#updateObject

Force command execution. If another instance with the same command is in progress, no new execution will be started



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/exedb.rb', line 43

def update
  @content=''
  File.open(@path, File::RDWR|File::CREAT, 0644) { |file|
    if file.flock(File::LOCK_EX|File::LOCK_NB)
      begin
        IO.popen(@update_method){|pipe|
          line=pipe.gets
          while line
            file.puts line
            file.flush
            @content = @content+line
            line=pipe.gets
          end
        }
        @code=$?.exitstatus
        #warn "UPDATED: #{@content}/#{@code}"
      rescue
        @content=''
        @code=-1
      end
      file.write @content
      file.flush
      File.open("#{@path}.code",File::RDWR|File::CREAT, 0644){|code_file|
        code_file.puts @code
      }
      file.flock(File::LOCK_UN)
    else
      warn "CANNOT LOCK"
      read_cache
    end
    @update_time=Time.now
  }
  #!!!warn "UPDATED!'"
  @content
end

#update_in_progress?Boolean

Returns:

  • (Boolean)


141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/exedb.rb', line 141

def update_in_progress?
  if File.exists? @path
    File.open(@path, File::RDONLY) { |file|
      if file.flock(File::LOCK_EX|File::LOCK_NB)
        file.flock(File::LOCK_UN)
        return false
      end
    }
    return true
  end
  return false
end

#update_method=(str) ⇒ Object

Replace executing command



82
83
84
85
86
87
# File 'lib/exedb.rb', line 82

def update_method=(str)
  @update_method=str
  @key=generate_key str
  @path=File.join(DEF_DIR, @key)
#    warn "key=#{@key}; path=#{@path}; u=#{str}"
end