Class: BlackStack::MyProcess

Inherits:
Object
  • Object
show all
Defined in:
lib/myprocess.rb

Direct Known Subclasses

MyChildProcess, MyParentProcess

Constant Summary collapse

DEFAULT_MINIMUM_ENLAPSED_SECONDS =
60

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(the_worker_name, the_division_name, the_minimum_enlapsed_seconds = MyProcess::DEFAULT_MINIMUM_ENLAPSED_SECONDS, the_verify_configuration = true, the_email = nil, the_password = nil) ⇒ MyProcess

constructor



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/myprocess.rb', line 11

def initialize(
    the_worker_name, 
    the_division_name, 
    the_minimum_enlapsed_seconds=MyProcess::DEFAULT_MINIMUM_ENLAPSED_SECONDS, 
    the_verify_configuration=true,
    the_email=nil, 
    the_password=nil
)
  self.assigned_process_changed = false
  self.assigned_division_changed = false
  self.assigned_process = File.expand_path($0)
  self.worker_name = "#{the_worker_name}" 
  self.division_name = the_division_name
  self.minimum_enlapsed_seconds = the_minimum_enlapsed_seconds
  self.verify_configuration = the_verify_configuration
  self.email = the_email
  self.password = the_password
end

Instance Attribute Details

#assigned_division_changedObject

Returns the value of attribute assigned_division_changed.



6
7
8
# File 'lib/myprocess.rb', line 6

def assigned_division_changed
  @assigned_division_changed
end

#assigned_processObject

Returns the value of attribute assigned_process.



7
8
9
# File 'lib/myprocess.rb', line 7

def assigned_process
  @assigned_process
end

#assigned_process_changedObject

Returns the value of attribute assigned_process_changed.



6
7
8
# File 'lib/myprocess.rb', line 6

def assigned_process_changed
  @assigned_process_changed
end

#division_nameObject

Returns the value of attribute division_name.



7
8
9
# File 'lib/myprocess.rb', line 7

def division_name
  @division_name
end

#emailObject

Returns the value of attribute email.



8
9
10
# File 'lib/myprocess.rb', line 8

def email
  @email
end

#idObject

Returns the value of attribute id.



7
8
9
# File 'lib/myprocess.rb', line 7

def id
  @id
end

#id_clientObject

Returns the value of attribute id_client.



7
8
9
# File 'lib/myprocess.rb', line 7

def id_client
  @id_client
end

#id_divisionObject

Returns the value of attribute id_division.



7
8
9
# File 'lib/myprocess.rb', line 7

def id_division
  @id_division
end

#loggerObject

Returns the value of attribute logger.



7
8
9
# File 'lib/myprocess.rb', line 7

def logger
  @logger
end

#minimum_enlapsed_secondsObject

Returns the value of attribute minimum_enlapsed_seconds.



7
8
9
# File 'lib/myprocess.rb', line 7

def minimum_enlapsed_seconds
  @minimum_enlapsed_seconds
end

#passwordObject

Returns the value of attribute password.



8
9
10
# File 'lib/myprocess.rb', line 8

def password
  @password
end

#verify_configurationObject

Returns the value of attribute verify_configuration.



6
7
8
# File 'lib/myprocess.rb', line 6

def verify_configuration
  @verify_configuration
end

#worker_nameObject

Returns the value of attribute worker_name.



7
8
9
# File 'lib/myprocess.rb', line 7

def worker_name
  @worker_name
end

#ws_portObject

Returns the value of attribute ws_port.



7
8
9
# File 'lib/myprocess.rb', line 7

def ws_port
  @ws_port
end

#ws_urlObject

Returns the value of attribute ws_url.



7
8
9
# File 'lib/myprocess.rb', line 7

def ws_url
  @ws_url
end

Class Method Details

.fullWorkerName(name) ⇒ Object



81
82
83
# File 'lib/myprocess.rb', line 81

def self.fullWorkerName(name)
  "#{Socket.gethostname}.#{MyProcess.macaddress}.#{name}"
end

.kill(the_pid) ⇒ Object

ejecuta TASKKILL /F /PID #the_pid y retorna el output del comando



58
59
60
# File 'lib/myprocess.rb', line 58

def self.kill(the_pid)
  system("TASKKILL /F /PID #{the_pid}")
end

.macaddressObject

This function works in windows only TODO: Esta funcion no retorna la mac address completa TODO: Validar que no se retorne una macaddress virtual, con todos valores en 0



77
78
79
# File 'lib/myprocess.rb', line 77

def self.macaddress()
  BlackStack::SimpleHostMonitoring.macaddress
end

Instance Method Details

#canRun?Boolean

retorna true si el proceso hijo (child) esta habilitado para trabajar.

Returns:

  • (Boolean)


234
235
236
237
# File 'lib/myprocess.rb', line 234

def canRun?()
  self.assigned_process_changed == false && 
  self.assigned_division_changed == false
end

#divisionObject

Get the data object of the divison assigned to this worker. Needs database connections. So it’s available for ChildProcess only.



223
224
225
# File 'lib/myprocess.rb', line 223

def division()
  raise "This is an abstract method."
end

#doSleep(the_start_time) ⇒ Object

obtiene la diferencia en segundos entre la hora actual y el parametro the_start_time. si la diferencia es mayor al atributo minimum_enlapsed_seconds, entonces duerme el tiempo restante.



64
65
66
67
68
69
70
71
72
# File 'lib/myprocess.rb', line 64

def doSleep(the_start_time)
  # si el proceso tardo menos del minimum_enlapsed_seconds, entonces duermo el tiempo restante
  end_time = Time.now
  elapsed_seconds = end_time - the_start_time # in seconds
  if (elapsed_seconds < self.minimum_enlapsed_seconds)
    sleep_seconds = self.minimum_enlapsed_seconds - elapsed_seconds 
    sleep(sleep_seconds)
  end
end

#fullWorkerNameObject



85
86
87
# File 'lib/myprocess.rb', line 85

def fullWorkerName()
  MyProcess.fullWorkerName(self.worker_name)
end

#getObject

obtiene sus parametros de la central



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/myprocess.rb', line 117

def get()
  # me notifico a la central. obtengo asignacion que tenga
  url = "#{BlackStack::Pampa::api_url}/api1.3/pampa/get.json"
  res = BlackStack::Netting::call_post(url, {
    'api_key' => BlackStack::Pampa::api_key, 
    'name' => self.fullWorkerName }.merge( BlackStack::RemoteHost.new.poll )
  )
  parsed = JSON.parse(res.body)
  if (parsed['status'] != BlackStack::Netting::SUCCESS)
    raise parsed['status'].to_s
  else 
    if self.verify_configuration
      # si ya tenia un proceso asignado, y ahora se le asigna un nuevo proceso 
      if self.assigned_process.to_s.size > 0
        a = File.expand_path(self.assigned_process)
        b = File.expand_path(parsed['assigned_process'])
        if a != b
          self.assigned_process_changed = true
        else
          self.assigned_process_changed = false
        end
      end

      # si ya tenia un proceso asignado, y ahora se le asigna un nuevo proceso 
      if self.id_division.to_s.size > 0
        if self.id_division.to_guid != parsed['id_division'].to_guid
          self.assigned_division_changed = true
        else
          self.assigned_division_changed = false
        end
      end
    end # verify_configuration
          
    # si ya tenia asignada una division, entonces le notifico mi nueva configuracion
    self.set(parsed['assigned_process'], parsed['id_client'])
  
    self.id                 = parsed['id']
    self.assigned_process   = parsed['assigned_process']
    self.id_client          = parsed['id_client']
    self.id_division        = parsed['id_division']
    self.division_name      = parsed['division_name']
    self.ws_url             = parsed['ws_url']
    self.ws_port            = parsed['ws_port']      
  
    # le notifico a la nueva division asignada mi nueva configuracion
    self.set(parsed['assigned_process'], parsed['id_client'])
  end
end

#helloObject

saluda a la central



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/myprocess.rb', line 90

def hello()
  # me notifico a la central. obtengo asignacion si ya la tenia
  url = "#{BlackStack::Pampa::api_url}/api1.3/pampa/hello.json"
  res = BlackStack::Netting::call_post(url, {
    'api_key' => BlackStack::Pampa::api_key, 
    'name' => self.fullWorkerName }.merge( BlackStack::RemoteHost.new.poll )
  )
  parsed = JSON.parse(res.body)
  if (parsed['status'] != BlackStack::Netting::SUCCESS)
    raise parsed['status'].to_s
  end
end

#listObject

Retorna un array de hashes.

> Cada elemento del hash tiene la forma: :pid, :ppid,

> donde imagename es el patch completo del proceso, pid es el id del proceso

> y ppid es el id del proceso padre.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/myprocess.rb', line 39

def list()
  a = []
  s = `wmic process get executablepath,processid,parentprocessid`
  s.split(/\n+/).each { |e|
    aux = e.strip.scan(/^(.+)\s+(\d+)\s+(\d+)$/)[0]
    if (aux!=nil)
      if (aux.size>=3)
        a << {
          :executablepath => aux[0].strip.to_s,
          :pid => aux[2].to_s, # TODO: deberia ser aux[1], pero por algo que no entiendo ahora el pid viene en aux[2]
          :ppid => aux[1].to_s, # TODO: deberia ser aux[2], pero por algo que no entiendo ahora el pid viene en aux[1]
        }
      end
    end
  }
  a
end

#notifyObject

se notifica al dispatcher de la division



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/myprocess.rb', line 200

def notify()
  if (self.ws_url==nil || self.ws_port==nil)
    raise "Cannot notify. Worker not exists, or it has not parameters, or it is belong another client. Check your api_key, and check the name of the worker."
  end
          
  # me notifico a la division. obtengo trabajo
  url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url}:#{self.ws_port}/api1.3/pampa/notify.json"
  res = BlackStack::Netting::call_post(url, 
    {
    'api_key' => BlackStack::Pampa::api_key, 
    'name' => self.fullWorkerName, 
    'assigned_process' => self.assigned_process,
    'id_client' => self.id_client,
    'id_division' => self.id_division }.merge( BlackStack::RemoteHost.new.poll )
  )
  parsed = JSON.parse(res.body)
  if (parsed['status'] != "success")
    raise parsed['status'].to_s
  end
end

#pidObject

retrieves the id of the current process



31
32
33
# File 'lib/myprocess.rb', line 31

def pid()
  Process.pid.to_s
end

#pingObject

ping the central database



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/myprocess.rb', line 173

def ping()
  # me notifico a la central.
  url = "#{BlackStack::Pampa::api_url}/api1.3/pampa/ping.json"
  res = BlackStack::Netting::call_post(url, {
    'api_key' => BlackStack::Pampa::api_key, 
    'name' => self.fullWorkerName }.merge( BlackStack::RemoteHost.new.poll )
  )
  parsed = JSON.parse(res.body)
  if (parsed['status'] != BlackStack::Netting::SUCCESS)
    raise parsed['status'].to_s
  end
  
  # me notifico a la division.
  if (self.ws_url != nil && self.ws_port != nil)
    url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url.to_s}:#{self.ws_port.to_s}/api1.3/pampa/ping.json"
    res = BlackStack::Netting::call_post(url, {
      'api_key' => BlackStack::Pampa::api_key, 
      'name' => self.fullWorkerName }.merge( BlackStack::RemoteHost.new.poll )
    )
    parsed = JSON.parse(res.body)
    if (parsed['status'] != "success")
      raise parsed['status'].to_s
    end
  end # if
end

#process(argv) ⇒ Object

este metodo ejecuta el trabajo para el que fue creado el objeto.



251
252
253
# File 'lib/myprocess.rb', line 251

def process(argv)
  raise "This is an abstract method."
end

#runObject

ejecuta el proceso, en modo parent, bot o child segun la clase que se implemente. en modo parent, hace un loop infinito. en modo bot o child, hace un loop hasta que el metodo canRun? retorne false. en modo bot o child, invoca al metodo process() en cada ciclo.



259
260
261
# File 'lib/myprocess.rb', line 259

def run()
  #raise "This is an abstract method"
end

#set(new_assigned_process, new_id_client) ⇒ Object

notifico mis parametros (assigned_process, id_client) a la division asignada



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/myprocess.rb', line 104

def set(new_assigned_process, new_id_client)
  if (self.ws_url.to_s.size > 0 && self.ws_port.to_s.size > 0)
    url = "#{BlackStack::Pampa::api_protocol}://#{self.ws_url.to_s}:#{self.ws_port.to_s}/api1.3/pampa/notify.json"
    res = BlackStack::Netting::call_post(url, {
      'api_key' => BlackStack::Pampa::api_key, 
      'name' => self.fullWorkerName,
      'assigned_process' => new_assigned_process,
      'id_client' => new_id_client }.merge( BlackStack::RemoteHost.new.poll )
    )
  end    
end

#updateWorkerObject

update worker configuration in the division



168
169
170
# File 'lib/myprocess.rb', line 168

def updateWorker()
  raise "Abstract Method."
end

#whyCantRunObject



239
240
241
242
243
244
245
246
247
# File 'lib/myprocess.rb', line 239

def whyCantRun()
  if self.assigned_process_changed == true
    return "Assigned process has changed." 
  elsif self.assigned_division_changed == true
    return "Assigned division has changed." 
  else
    return "unknown"
  end
end

#workerObject

Get the data object of worker linked to this process. Needs database connections. So it’s available for ChildProcess only.



229
230
231
# File 'lib/myprocess.rb', line 229

def worker()
  raise "This is an abstract method."
end