class BlackStack::MyProcess

Constants

DEFAULT_MINIMUM_ENLAPSED_SECONDS

Attributes

assigned_division_changed[RW]
assigned_process[RW]
assigned_process_changed[RW]
division_name[RW]
email[RW]
id[RW]
id_client[RW]
id_division[RW]
logger[RW]
minimum_enlapsed_seconds[RW]
password[RW]
verify_configuration[RW]
worker_name[RW]
ws_port[RW]
ws_url[RW]

Public Class Methods

fullWorkerName(name) click to toggle source
# File lib/myprocess.rb, line 81
def self.fullWorkerName(name)
  "#{Socket.gethostname}.#{MyProcess.macaddress}.#{name}"
end
kill(the_pid) click to toggle source

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

# File lib/myprocess.rb, line 58
def self.kill(the_pid)
  system("TASKKILL /F /PID #{the_pid}")
end
macaddress() click to toggle source

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

# File lib/myprocess.rb, line 77
def self.macaddress()
  BlackStack::SimpleHostMonitoring.macaddress
end
new( 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 ) click to toggle source

constructor

# 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

Public Instance Methods

canRun?() click to toggle source

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

# File lib/myprocess.rb, line 234
def canRun?()
  self.assigned_process_changed == false && 
  self.assigned_division_changed == false
end
division() click to toggle source

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

# File lib/myprocess.rb, line 223
def division()
  raise "This is an abstract method."
end
doSleep(the_start_time) click to toggle source

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.

# 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
fullWorkerName() click to toggle source
# File lib/myprocess.rb, line 85
def fullWorkerName()
  MyProcess.fullWorkerName(self.worker_name)
end
get() click to toggle source

obtiene sus parametros de la central

# 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
hello() click to toggle source

saluda a la central

# 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
list() click to toggle source

Retorna un array de hashes.

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

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

> y ppid es el id del proceso padre.

# 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
notify() click to toggle source

se notifica al dispatcher de la division

# 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
pid() click to toggle source

retrieves the id of the current process

# File lib/myprocess.rb, line 31
def pid()
  Process.pid.to_s
end
ping() click to toggle source

ping the central database

# 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) click to toggle source

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

# File lib/myprocess.rb, line 251
def process(argv)
  raise "This is an abstract method."
end
run() click to toggle source

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.

# File lib/myprocess.rb, line 259
def run()
  #raise "This is an abstract method"
end
set(new_assigned_process, new_id_client) click to toggle source

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

# 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
updateWorker() click to toggle source

update worker configuration in the division

# File lib/myprocess.rb, line 168
def updateWorker()
  raise "Abstract Method."
end
whyCantRun() click to toggle source
# 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
worker() click to toggle source

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

# File lib/myprocess.rb, line 229
def worker()
  raise "This is an abstract method."
end