pampa_workers 0.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/basedivision.rb +5 -0
- data/lib/baseworker.rb +5 -0
- data/lib/client.rb +245 -0
- data/lib/division.rb +46 -0
- data/lib/login.rb +7 -0
- data/lib/mybotprocess.rb +348 -0
- data/lib/mychildprocess.rb +9 -0
- data/lib/mycrawlprocess.rb +49 -0
- data/lib/mylocalprocess.rb +164 -0
- data/lib/myparentprocess.rb +141 -0
- data/lib/myprocess.rb +264 -0
- data/lib/myremoteprocess.rb +128 -0
- data/lib/pampa-local.rb +41 -0
- data/lib/pampa_workers.rb +261 -0
- data/lib/params.rb +50 -0
- data/lib/remotedivision.rb +8 -0
- data/lib/remoteworker.rb +8 -0
- data/lib/role.rb +8 -0
- data/lib/timezone.rb +151 -0
- data/lib/user.rb +25 -0
- data/lib/userdivision.rb +5 -0
- data/lib/userrole.rb +8 -0
- data/lib/worker.rb +234 -0
- metadata +229 -0
data/lib/remoteworker.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
module BlackStack
|
2
|
+
|
3
|
+
class RemoteWorker
|
4
|
+
attr_accessor :id, :process, :last_ping_time, :name, :active, :id_division, :assigned_process, :id_object, :division_name, :ws_url, :ws_port, :division
|
5
|
+
include BlackStack::BaseWorker
|
6
|
+
end # Remote Worker
|
7
|
+
|
8
|
+
end # module BlackStack
|
data/lib/role.rb
ADDED
data/lib/timezone.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
module BlackStack
|
2
|
+
class Timezone < Sequel::Model(:timezone)
|
3
|
+
BlackStack::Timezone.dataset = BlackStack::Timezone.dataset.disable_insert_output
|
4
|
+
|
5
|
+
# Recibe un string con formato "+HH:MM".
|
6
|
+
# Retorna la cantidad de horas como un numero real, con decimales.
|
7
|
+
def self.descToFloat(s)
|
8
|
+
sign = s[0]
|
9
|
+
if (sign=="+")
|
10
|
+
n = 1.0
|
11
|
+
else
|
12
|
+
n = -1.0
|
13
|
+
end
|
14
|
+
hours = s[1..2]
|
15
|
+
minutes = s[4..5]
|
16
|
+
int_part = hours.to_f
|
17
|
+
dec_part = minutes.to_f / 60.00
|
18
|
+
ret = n*(int_part + dec_part)
|
19
|
+
return ret.to_f
|
20
|
+
end
|
21
|
+
|
22
|
+
# Recibe la cantidad de horas como un numero real, con decimales.
|
23
|
+
# Retorna un string con formato "+HH:MM".
|
24
|
+
def self.floatToDesc(x)
|
25
|
+
int_part = x.to_i
|
26
|
+
dec_part = (x-int_part.to_f).round(2).abs
|
27
|
+
hours = int_part
|
28
|
+
minutes = (dec_part * 60.00).to_i
|
29
|
+
if (hours<0)
|
30
|
+
desc = "%03d" % hours
|
31
|
+
else
|
32
|
+
desc = "+" + "%02d" % hours
|
33
|
+
end
|
34
|
+
desc += ":" + "%02d" % minutes
|
35
|
+
return desc
|
36
|
+
end
|
37
|
+
|
38
|
+
# Example: '-03:00'
|
39
|
+
# Example: ' 08:00'
|
40
|
+
def self.getDatabaseOffset()
|
41
|
+
dbtime = DB["select SYSDATETIMEOFFSET() AS o"].first[:o].to_s
|
42
|
+
#puts ""
|
43
|
+
#puts ""
|
44
|
+
#puts "dbtime:#{dbtime.to_s}:."
|
45
|
+
#puts ""
|
46
|
+
#puts ""
|
47
|
+
ret = "#{dbtime[-5..-3]}:#{dbtime[-2..-1]}"
|
48
|
+
ret[0] = '+' if ret[0]!='-'
|
49
|
+
#puts ""
|
50
|
+
#puts ""
|
51
|
+
#puts "dbtime:#{ret.to_s}:."
|
52
|
+
#puts ""
|
53
|
+
#puts ""
|
54
|
+
return ret
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convierte el atributo offset en un string con formato de hora.
|
58
|
+
# Ejemplos: 5.0 => 05:00, 5.5 => 05:30, -5.75 => -05:45
|
59
|
+
def offsetDescription()
|
60
|
+
return BlackStack::Timezone.floatToDesc(self.offset.to_f)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convierte una hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
|
64
|
+
# Recibe un string con formato "+HH:MM".
|
65
|
+
# Retorna un string con formato "+HH:MM".
|
66
|
+
def convertFromThisTimeZoneToDatabaseTime(s_time_in_client_timezone)
|
67
|
+
f_time_in_client_timezone = BlackStack::Timezone.descToFloat(s_time_in_client_timezone)
|
68
|
+
s = BlackStack::Timezone.getDatabaseOffset()
|
69
|
+
x = BlackStack::Timezone.descToFloat(s) # database offset
|
70
|
+
y = self.offset # client offset
|
71
|
+
z = y - x
|
72
|
+
return BlackStack::Timezone.floatToDesc((f_time_in_client_timezone.to_f + z.to_f).modulo(24))
|
73
|
+
end
|
74
|
+
|
75
|
+
# Convierte una hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
|
76
|
+
# Recibe un string con formato "+HH:MM".
|
77
|
+
# Retorna un string con formato "+HH:MM".
|
78
|
+
def convertFromDatabaseTimeToThisTimeZone(s_time_in_database)
|
79
|
+
f_time_in_database = BlackStack::Timezone.descToFloat(s_time_in_database)
|
80
|
+
s = BlackStack::Timezone.getDatabaseOffset()
|
81
|
+
x = BlackStack::Timezone.descToFloat(s) # database offset
|
82
|
+
y = self.offset # client offset
|
83
|
+
z = y - x
|
84
|
+
return BlackStack::Timezone.floatToDesc((f_time_in_database.to_f - z.to_f).modulo(24))
|
85
|
+
end
|
86
|
+
|
87
|
+
# Convierte una fecha-hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
|
88
|
+
# Recibe un string con formato "YYYY-MM-DD HH:MM:SS".
|
89
|
+
# Retorna un string con formato "YYYY-MM-DD HH:MM:SS".
|
90
|
+
def convertFromDatabaseDateTimeToThisTimeZone(s_datetime_in_database)
|
91
|
+
s = BlackStack::Timezone.getDatabaseOffset() # Example: '-03:00'
|
92
|
+
#puts ""
|
93
|
+
#puts ""
|
94
|
+
#puts "s:#{s.to_s}:."
|
95
|
+
#puts ""
|
96
|
+
#puts ""
|
97
|
+
x = BlackStack::Timezone.descToFloat(s) # database offset. Number of hours, with decimals
|
98
|
+
#puts ""
|
99
|
+
#puts ""
|
100
|
+
#puts "x:#{x.to_s}:."
|
101
|
+
#puts ""
|
102
|
+
#puts ""
|
103
|
+
y = self.offset # client offset
|
104
|
+
#puts ""
|
105
|
+
#puts ""
|
106
|
+
#puts "y:#{y.to_s}:."
|
107
|
+
#puts ""
|
108
|
+
#puts ""
|
109
|
+
z = y - x
|
110
|
+
#puts ""
|
111
|
+
#puts ""
|
112
|
+
#puts "z:#{z.to_s}:."
|
113
|
+
#puts ""
|
114
|
+
#puts ""
|
115
|
+
ret = DB["SELECT DATEADD(HH, #{z.to_s}, '#{s_datetime_in_database}') AS o"].first[:o].to_s[0..18]
|
116
|
+
#puts ""
|
117
|
+
#puts ""
|
118
|
+
#puts "convertFromDatabaseDateTimeToThisTimeZone:#{ret}:."
|
119
|
+
#puts ""
|
120
|
+
#puts ""
|
121
|
+
|
122
|
+
return ret
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
def get_now()
|
127
|
+
datetime1 = DB["SELECT GETDATE() AS o"].first[:o].to_s[0..18]
|
128
|
+
datetime2 = self.convertFromDatabaseDateTimeToThisTimeZone(datetime1)
|
129
|
+
#puts ""
|
130
|
+
#puts ""
|
131
|
+
#puts "timezone:#{self.large_description}:."
|
132
|
+
#puts "datetime1:#{datetime1}:."
|
133
|
+
#puts "datetime2:#{datetime2}:."
|
134
|
+
#puts ""
|
135
|
+
#puts ""
|
136
|
+
yy = datetime2[0..3] # yyyy-mm-dd hh:mi:ss
|
137
|
+
mm = datetime2[5..6]
|
138
|
+
dd = datetime2[8..9]
|
139
|
+
hh = datetime2[11..12]
|
140
|
+
mi = datetime2[14..15]
|
141
|
+
ss = datetime2[17..18]
|
142
|
+
#puts ""
|
143
|
+
#puts ""
|
144
|
+
#puts "get_now:#{yy}-#{mm}-#{dd} #{hh}:#{mi}:#{ss}:."
|
145
|
+
#puts ""
|
146
|
+
#puts ""
|
147
|
+
return Time.new(yy,mm,dd,hh,mi,ss)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end # module BlackStack
|
data/lib/user.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module BlackStack
|
2
|
+
class User < Sequel::Model(:user)
|
3
|
+
BlackStack::User.dataset = BlackStack::User.dataset.disable_insert_output
|
4
|
+
many_to_one :client, :class=>:'BlackStack::Client', :key=>:id_client
|
5
|
+
one_to_many :user_roles, :class=>:'BlackStack::UserRole', :key=>:id_user
|
6
|
+
|
7
|
+
# TODO: agregar todos los arrays de un usuario
|
8
|
+
# => one_to_many :searches, :class=>:Search, :key=>:id_user
|
9
|
+
# => one_to_many :emlist, :class=>:EmList, :key=>:id_user
|
10
|
+
# => one_to_many :emlist, :class=>:EmList, :key=>:id_user
|
11
|
+
# => etc.
|
12
|
+
|
13
|
+
# retorna la primera division habilitada a la que pertenezca este usuario
|
14
|
+
def division
|
15
|
+
row = DB[
|
16
|
+
"SELECT d.id " +
|
17
|
+
"FROM division d WITH (NOLOCK) " +
|
18
|
+
"JOIN user_division ud WITH (NOLOCK) ON (d.id=ud.id_division AND ud.id_user='#{self.id}') " +
|
19
|
+
"WHERE ISNULL(d.available,0) = 1 "
|
20
|
+
].first
|
21
|
+
return nil if row.nil?
|
22
|
+
return BlackStack::Division.where(:id=>row[:id]).first if !row.nil?
|
23
|
+
end
|
24
|
+
end # class User
|
25
|
+
end # module BlackStack
|
data/lib/userdivision.rb
ADDED
data/lib/userrole.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
module BlackStack
|
2
|
+
class UserRole < Sequel::Model(:user_role)
|
3
|
+
BlackStack::UserRole.dataset = BlackStack::UserRole.dataset.disable_insert_output
|
4
|
+
many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
|
5
|
+
many_to_one :role, :class=>:'BlackStack::Role', :key=>:id_role
|
6
|
+
|
7
|
+
end
|
8
|
+
end # module BlackStack
|
data/lib/worker.rb
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
module BlackStack
|
2
|
+
|
3
|
+
#
|
4
|
+
class WorkerJob < Sequel::Model(:workerjob)
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
#
|
9
|
+
class Worker < Sequel::Model(:worker)
|
10
|
+
include BlackStack::BaseWorker
|
11
|
+
BlackStack::Worker.dataset = BlackStack::Worker.dataset.disable_insert_output
|
12
|
+
many_to_one :division, :class=>:'BlackStack::Division', :key=>:id_division
|
13
|
+
many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
|
14
|
+
=begin
|
15
|
+
# deprecated
|
16
|
+
# Actualiza la la lista de workers que estan asignados esta division
|
17
|
+
def self.updateAllFromCentral()
|
18
|
+
uri = URI("#{WORKER_API_SERVER_URL}/api1.3/pampa/get_all.json")
|
19
|
+
res = Net::HTTP.post_form(uri, {:api_key => BlackStack::Pampa::api_key,})
|
20
|
+
parsed = JSON.parse(res.body)
|
21
|
+
if (parsed['status'] != "success")
|
22
|
+
raise parsed['status'].to_s
|
23
|
+
else
|
24
|
+
parsed['workers'].each { |worker|
|
25
|
+
if ( worker['division_name']!=DATABASE )
|
26
|
+
q = "UPDATE worker SET active=0, division_name='#{worker['division_name']}' WHERE name='#{worker['name']}'"
|
27
|
+
DB.execute(q)
|
28
|
+
else # worker['division_name']==DIVISION_NAME
|
29
|
+
|
30
|
+
worker = BlackStack::Worker.where(:name=>worker['name']).first
|
31
|
+
if (worker==nil)
|
32
|
+
worker = BlackStack::Worker.new()
|
33
|
+
worker.id = worker['id']
|
34
|
+
worker.name = worker['name'].to_s
|
35
|
+
worker.last_ping_time = now() # esta fecha es actualiada por el mismo worker, para indicar que esta vivo y trabajando
|
36
|
+
worker.id_division = worker['id_division']
|
37
|
+
worker.process = worker['assigned_process']
|
38
|
+
worker.assigned_process = worker['assigned_process']
|
39
|
+
worker.id_object = worker['id_object']
|
40
|
+
worker.division_name = worker['division_name']
|
41
|
+
worker.save()
|
42
|
+
else
|
43
|
+
#puts "update" ?
|
44
|
+
end
|
45
|
+
|
46
|
+
DB.execute("UPDATE worker SET active=1 WHERE name='#{worker['name'].to_s}'")
|
47
|
+
|
48
|
+
if (worker['id_division'] != nil)
|
49
|
+
DB.execute("UPDATE worker SET id_division='#{worker['id_division'].to_s}' WHERE name='#{worker['name'].to_s}'")
|
50
|
+
end
|
51
|
+
|
52
|
+
if (worker['assigned_process'] != nil)
|
53
|
+
DB.execute("UPDATE worker SET process='#{worker['assigned_process'].to_s}', assigned_process='#{worker['assigned_process'].to_s}' WHERE name='#{worker['name'].to_s}'")
|
54
|
+
end
|
55
|
+
|
56
|
+
if (worker['id_object'] != nil)
|
57
|
+
DB.execute("UPDATE worker SET id_object='#{worker['id_object'].to_s}' WHERE name='#{worker['name'].to_s}'")
|
58
|
+
end
|
59
|
+
|
60
|
+
if (worker['division_name'] != nil)
|
61
|
+
DB.execute("UPDATE worker SET division_name='#{worker['division_name'].to_s}' WHERE name='#{worker['name'].to_s}'")
|
62
|
+
end
|
63
|
+
|
64
|
+
if (worker['type']==nil || worker['type'].to_i==MyProcess::TYPE_LOCAL)
|
65
|
+
DB.execute("UPDATE worker SET type=#{MyProcess::TYPE_LOCAL.to_s} WHERE name='#{worker['name'].to_s}'")
|
66
|
+
else
|
67
|
+
DB.execute("UPDATE worker SET type=#{MyProcess::TYPE_REMOTE.to_s} WHERE name='#{worker['name'].to_s}'")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# release resources
|
72
|
+
DB.disconnect
|
73
|
+
GC.start
|
74
|
+
}
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# actualiza el rol y objeto asignado a este worker
|
80
|
+
def updateFromCentral()
|
81
|
+
uri = URI("#{WORKER_API_SERVER_URL}/api1.3/pampa/get.json")
|
82
|
+
res = Net::HTTP.post_form(uri, {'api_key' => BlackStack::Pampa::api_key, 'name' => self.name})
|
83
|
+
parsed = JSON.parse(res.body)
|
84
|
+
if (parsed['status'] != "success")
|
85
|
+
raise parsed['status'].to_s
|
86
|
+
else
|
87
|
+
# map response
|
88
|
+
self.id_division = parsed['id_division']
|
89
|
+
self.assigned_process = parsed['assigned_process']
|
90
|
+
self.id_object = parsed['id_object']
|
91
|
+
self.division_name = parsed['division_name']
|
92
|
+
self.active = true
|
93
|
+
|
94
|
+
if (parsed['id_object'].to_s.size>0)
|
95
|
+
aux_id_object = "'#{parsed['id_object']}'"
|
96
|
+
else
|
97
|
+
aux_id_object = "NULL"
|
98
|
+
end
|
99
|
+
|
100
|
+
# NOTA: DEBO HACER EL UPDATE POR FUERA DE SQUEL, DEBIDO AL BUG DE MAPEO DE SEQUEL
|
101
|
+
q =
|
102
|
+
"UPDATE worker SET " +
|
103
|
+
"active=1, id_division='#{parsed['id_division']}', assigned_process='#{parsed['assigned_process'].to_s.gsub("'","''")}', id_object=#{aux_id_object}, division_name='#{parsed['division_name'].to_s.gsub("'","''")}' " +
|
104
|
+
"WHERE id='#{self.id}'"
|
105
|
+
DB.execute(q)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# actualiza el rol y objeto asignado a cada worker asignado a esta division
|
110
|
+
def self.updateActivesFromCentral()
|
111
|
+
BlackStack::Worker.getActives().each { |worker|
|
112
|
+
worker.updateFromCentral()
|
113
|
+
}
|
114
|
+
end
|
115
|
+
=end
|
116
|
+
|
117
|
+
#
|
118
|
+
def factory(name, params)
|
119
|
+
w = BlackStack::Worker.where(:name=>name).first
|
120
|
+
if (w==nil)
|
121
|
+
w = BlackStack::Worker.new
|
122
|
+
end
|
123
|
+
w.id = parsed['id']
|
124
|
+
w.name = name
|
125
|
+
w.assigned_process = parsed['assigned_process']
|
126
|
+
w.id_object = parsed['id_object']
|
127
|
+
w.id_division = parsed['id_division']
|
128
|
+
w.division_name = parsed['division_name']
|
129
|
+
w.ws_url = parsed['ws_url']
|
130
|
+
w.ws_port = parsed['ws_port']
|
131
|
+
w.save
|
132
|
+
end
|
133
|
+
|
134
|
+
# Retorna true si este worker esta corriendo en nuestros propios servidores,
|
135
|
+
# Retorna false si este worker esta correiendo en otro host, asumiendo que es el host del cliente.
|
136
|
+
# Comparando la pulic_ip_address del worer con la lista en BlackStack::Pampa::set_farm_external_ip_addresses.
|
137
|
+
def hosted?
|
138
|
+
BlackStack::Pampa::set_farm_external_ip_addresses.inlude?(self.public_ip_address)
|
139
|
+
end # hosted?
|
140
|
+
|
141
|
+
# Si es un worker hosteado en nuestos servidores (ver metodo hosted?),
|
142
|
+
# => retorna la cantidad de dias que fa
|
143
|
+
def expirationDesc
|
144
|
+
s = "(unknown)"
|
145
|
+
if self.hosted?
|
146
|
+
if !self.expiration_time.nil?
|
147
|
+
s = DB["SELECT DATEDIFF(mi, GETDATE(), w.expiration_time) AS n FROM worker w WHERE w.id='#{self.id}'"].first[:n].to_i.to_time_spent
|
148
|
+
end
|
149
|
+
else # no hosted
|
150
|
+
s = "(self-hosted)"
|
151
|
+
end
|
152
|
+
s
|
153
|
+
end
|
154
|
+
|
155
|
+
# Retorna la cantidad de minutos desde que este worker envio una senial de vida.
|
156
|
+
# Este metodo se usa para saber si un worker esta activo o no.
|
157
|
+
def last_ping_minutes()
|
158
|
+
q = "SELECT DATEDIFF(mi, p.last_ping_time, getdate()) AS minutes FROM worker p WHERE p.id='#{self.id}'"
|
159
|
+
return DB[q].first[:minutes].to_i
|
160
|
+
end
|
161
|
+
|
162
|
+
# returns true if this worker had got a ping within the last 5 minutes
|
163
|
+
def active?
|
164
|
+
self.last_ping_minutes < BlackStack::BaseWorker::KEEP_ACTIVE_MINUTES
|
165
|
+
end
|
166
|
+
|
167
|
+
# escribe en el archivo de log de este worker
|
168
|
+
def log(s, level=1, is_error=false)
|
169
|
+
logw(s, self.process, self.id, level, is_error)
|
170
|
+
end
|
171
|
+
|
172
|
+
# envia una senial de vida a la division
|
173
|
+
# TODO: guardar fecha-hora del ultimo ping en un atributo privado, y evitar el acceso escesivo a la base de datos
|
174
|
+
def ping()
|
175
|
+
DB.execute("UPDATE worker SET last_ping_time=GETDATE() WHERE id='#{self.id}'")
|
176
|
+
end
|
177
|
+
|
178
|
+
# DEPRECATED
|
179
|
+
def self.getActivesCount(processName)
|
180
|
+
raise "Method needs some code inside."
|
181
|
+
end
|
182
|
+
|
183
|
+
# obtiene array de workers actives, filtrados por proceso y por tipo de worker.
|
184
|
+
def self.getActives(assigned_process_name=nil, worker_name_filter=nil)
|
185
|
+
a = Array.new
|
186
|
+
q = ""
|
187
|
+
if (assigned_process_name!=nil)
|
188
|
+
q =
|
189
|
+
"SELECT p.id AS [id] " +
|
190
|
+
"FROM worker p WITH (NOLOCK INDEX(IX_peer__process__last_ping_time)) " +
|
191
|
+
"WHERE last_ping_time>DATEADD(mi,-5,GETDATE()) " +
|
192
|
+
"AND ISNULL(active,0)=1 " + # active indica si este worker fue asignado a esta division en la central
|
193
|
+
"AND assigned_process='#{assigned_process_name}' "
|
194
|
+
|
195
|
+
if worker_name_filter != nil
|
196
|
+
q = q +
|
197
|
+
"AND p.name LIKE '%#{worker_name_filter.to_s}%' "
|
198
|
+
end
|
199
|
+
|
200
|
+
q = q +
|
201
|
+
"ORDER BY p.name "
|
202
|
+
DB[q].all do |row|
|
203
|
+
a << BlackStack::Worker.where(:id=>row[:id]).first
|
204
|
+
end
|
205
|
+
else
|
206
|
+
q =
|
207
|
+
"SELECT p.id AS [id] " +
|
208
|
+
"FROM worker p WITH (NOLOCK INDEX(IX_peer__process__last_ping_time)) " +
|
209
|
+
"WHERE last_ping_time>DATEADD(mi,-5,GETDATE()) " +
|
210
|
+
"AND ISNULL(active,0)=1 "
|
211
|
+
|
212
|
+
if worker_name_filter != nil
|
213
|
+
q = q +
|
214
|
+
"AND p.name LIKE '%#{worker_name_filter.to_s}%' "
|
215
|
+
end
|
216
|
+
|
217
|
+
q = q +
|
218
|
+
"ORDER BY p.name "
|
219
|
+
DB[q].all do |row|
|
220
|
+
a << BlackStack::Worker.where(:id=>row[:id]).first
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
return a
|
225
|
+
end
|
226
|
+
|
227
|
+
# obtiene cantidad de registros en cola para incrawl.lnsearchvariation
|
228
|
+
def getPendingLnSearchVariationBlockInCrawlCount()
|
229
|
+
return DB.from(:lnsearchvariationblock).where(:incrawl_reservation_id=>self.id, :incrawl_start_time=>nil).count
|
230
|
+
end
|
231
|
+
|
232
|
+
end # class Worker
|
233
|
+
|
234
|
+
end # module BlackStack
|