Class: PerfectSched::RDBBackend

Inherits:
Backend
  • Object
show all
Defined in:
lib/perfectsched/backend/rdb.rb

Constant Summary collapse

MAX_SELECT_ROW =
4

Instance Method Summary collapse

Methods inherited from Backend

#add, #close, #modify_data

Constructor Details

#initialize(uri, table, config = {}) ⇒ RDBBackend

Returns a new instance of RDBBackend.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/perfectsched/backend/rdb.rb', line 6

def initialize(uri, table, config={})
  super()
  require 'sequel'
  require 'uri'
  @uri = uri
  @table = table

  u = URI.parse(@uri)
  options = {
    max_connections: 1,
    user: u.user,
    password: u.password,
    host: u.host,
    port: u.port ? u.port.to_i : 3306
  }
  options[:sslca] = config[:sslca] if config[:sslca]
  db_name = u.path.split('/')[1]
  @db = Sequel.mysql2(db_name, options)

  #init_db(@uri.split('//',2)[0])
  connect {
    # connection test
  }
end

Instance Method Details

#acquire(timeout, now = Time.now.to_i) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/perfectsched/backend/rdb.rb', line 67

def acquire(timeout, now=Time.now.to_i)
  connect {
    while true
      rows = 0
      @db.fetch("SELECT id, timeout, next_time, cron, delay, data, timezone FROM `#{@table}` WHERE timeout <= ? ORDER BY timeout ASC LIMIT #{MAX_SELECT_ROW};", now) {|row|

        n = @db["UPDATE `#{@table}` SET timeout=? WHERE id=? AND timeout=?;", timeout, row[:id], row[:timeout]].update
        salt = timeout
        if n > 0
          return [row[:id],salt], Task.new(row[:id], row[:next_time], row[:cron], row[:delay], row[:data], row[:timezone])
        end

        rows += 1
      }
      if rows < MAX_SELECT_ROW
        return nil
      end
    end
  }
end

#add_checked(id, cron, delay, data, next_time, timeout, timezone) ⇒ Object



96
97
98
99
100
101
102
103
104
105
# File 'lib/perfectsched/backend/rdb.rb', line 96

def add_checked(id, cron, delay, data, next_time, timeout, timezone)
  connect {
    begin
      n = @db["INSERT INTO `#{@table}` (id, timeout, next_time, cron, delay, data, timezone) VALUES (?, ?, ?, ?, ?, ?, ?);", id, timeout, next_time, cron, delay, data, timezone].insert
      return true
    rescue Sequel::DatabaseError
      return nil
    end
  }
end

#create_tablesObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/perfectsched/backend/rdb.rb', line 31

def create_tables
  sql = ''
  sql << "CREATE TABLE IF NOT EXISTS `#{@table}` ("
  sql << "  id VARCHAR(256) NOT NULL,"
  sql << "  timeout INT NOT NULL,"
  sql << "  next_time INT NOT NULL,"
  sql << "  cron VARCHAR(128) NOT NULL,"
  sql << "  delay INT NOT NULL,"
  sql << "  data BLOB NOT NULL,"
  sql << "  timezone VARCHAR(256) NULL,"
  sql << "  PRIMARY KEY (id)"
  sql << ");"
  # TODO index
  connect {
    @db.run sql
  }
end

#delete(id) ⇒ Object



107
108
109
110
111
112
# File 'lib/perfectsched/backend/rdb.rb', line 107

def delete(id)
  connect {
    n = @db["DELETE FROM `#{@table}` WHERE id=?;", id].delete
    return n > 0
  }
end

#finish(token, next_time, timeout) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/perfectsched/backend/rdb.rb', line 88

def finish(token, next_time, timeout)
  connect {
    id, salt = *token
    n = @db["UPDATE `#{@table}` SET timeout=?, next_time=? WHERE id=? AND timeout=?;", timeout, next_time, id, salt].update
    return n > 0
  }
end

#get(id) ⇒ Object



114
115
116
117
118
119
120
121
# File 'lib/perfectsched/backend/rdb.rb', line 114

def get(id)
  connect {
    @db.fetch("SELECT id, timeout, next_time, cron, delay, data, timezone FROM `#{@table}` WHERE id=?;", id) {|row|
      return row[:cron], row[:delay], row[:data], row[:timezone], row[:next_time]
    }
    return nil
  }
end

#list(&block) ⇒ Object



59
60
61
62
63
# File 'lib/perfectsched/backend/rdb.rb', line 59

def list(&block)
  @db.fetch("SELECT id, timeout, next_time, cron, delay, data, timezone FROM `#{@table}` ORDER BY timeout ASC") {|row|
    yield row[:id], row[:cron], row[:delay], row[:data], row[:next_time], row[:timeout], row[:timezone]
  }
end

#modify(id, cron, delay, data, timezone) ⇒ Object

Overrides parent method in order to pass the calculated next run time into modify_checked



124
125
126
127
128
129
# File 'lib/perfectsched/backend/rdb.rb', line 124

def modify(id, cron, delay, data, timezone)
  cron = cron.strip
  next_time = @croncalc.next_time(cron, Time.now.to_i/60*60, timezone)
  modify_checked(id, cron, delay, data, timezone, next_time)
  return next_time, next_time + delay
end

#modify_checked(id, cron, delay, data, timezone, next_time) ⇒ Object



140
141
142
143
144
145
# File 'lib/perfectsched/backend/rdb.rb', line 140

def modify_checked(id, cron, delay, data, timezone, next_time)
  connect {
    n = @db["UPDATE `#{@table}` SET cron=?, delay=?, data=?, timezone=?, next_time=?, timeout=? WHERE id=?;", cron, delay, data, timezone, next_time, next_time + delay, id].update
    return n > 0
  }
end

#modify_data_checked(id, data) ⇒ Object



154
155
156
157
158
159
# File 'lib/perfectsched/backend/rdb.rb', line 154

def modify_data_checked(id, data)
  connect {
    n = @db["UPDATE `#{@table}` SET data=? WHERE id=?;", data, id].update
    return n > 0
  }
end

#modify_sched(id, cron, delay) ⇒ Object

Overrides parent method in order to pass the calculated next run time into modify_sched_checked



132
133
134
135
136
137
138
# File 'lib/perfectsched/backend/rdb.rb', line 132

def modify_sched(id, cron, delay)
  cron_, delay_, data_, timezone, next_time = get(id)
  cron = cron.strip
  next_time = @croncalc.next_time(cron, Time.now.to_i/60*60, timezone)
  modify_sched_checked(id, cron, delay, next_time)
  return next_time, next_time + delay
end

#modify_sched_checked(id, cron, delay, next_time) ⇒ Object



147
148
149
150
151
152
# File 'lib/perfectsched/backend/rdb.rb', line 147

def modify_sched_checked(id, cron, delay, next_time)
  connect {
    n = @db["UPDATE `#{@table}` SET cron=?, delay=?, next_time=?, timeout=? WHERE id=?;", cron, delay, next_time, next_time + delay, id].update
    return n > 0
  }
end