pampa_workers 0.0.39

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ module BlackStack
2
+
3
+ class RemoteDivision
4
+ attr_accessor :name
5
+ include BlackStack::BaseDivision
6
+ end # RemoteDivision
7
+
8
+ end # module BlackStack
@@ -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
@@ -0,0 +1,8 @@
1
+ module BlackStack
2
+ class Role < Sequel::Model(:role)
3
+ BlackStack::Role.dataset = BlackStack::Role.dataset.disable_insert_output
4
+
5
+ ROLE_PRISMA_USER = "prisma.user"
6
+
7
+ end
8
+ end # module BlackStack
@@ -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
@@ -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
@@ -0,0 +1,5 @@
1
+ module BlackStack
2
+ class UserDivision < Sequel::Model(:user_division)
3
+ BlackStack::UserDivision.dataset = BlackStack::UserDivision.dataset.disable_insert_output
4
+ end
5
+ end # module BlackStack
@@ -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
@@ -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