unit uOrquestadorV2Main;

interface

uses
{$IFDEF WINDOWS}
  Windows, Messages, Variants, Forms, Dialogs, Controls, StdCtrls, ComCtrls,
  utilidades,  
{$ELSE}
  uWinMsgs, ERRORS,
  baseunix,
  unix,
  uEmuladorWinIPC,
  uKeyDir,
  uAuxiliares,
{$ENDIF}
  SysUtils, Classes,
  uconstantesSimSEE, uDespachador, uMsgsDespachador,
  uInicioYFinal, uRobotOrquestadorV2, uconstantes_nettopos, uMsgsOrquestadorV2,
  uDatosNodo, uTareas, xMatDefs,
  ubuffrw,
{$IFDEF NETTOPOS_DLL}
  uimportnettopos,
{$ELSE}
  unettopos,
  unettopostypes,
  uglobsharedmem
{$ENDIF};

type
  TRobotMensajeoMasivo = class(TThread)
    private
      despachador: TDespachador;
    public
      Constructor Create(despachador: TDespachador);
      procedure Execute; override;
  end;

{$IFDEF LINUX}
  TOrquestadorV2 = class(TComponent)
{$ELSE}

  { TOrquestadorV2 }

  TOrquestadorV2 = class(TForm)
      LNArch: TLabel;
      LTiempoTotal: TLabel;
      ENArch: TEdit;
      BBuscar: TButton;
      BEnviarArchivos: TButton;
      BLanzarOptimizacion: TButton;
      BGetListaTopos: TButton;
      ETiempoTotal: TEdit;
      PBOpt: TProgressBar;
      cbNodoLocalCom: TCheckBox;
      ODNArch: TOpenDialog;
      l0: TLabel;
      l25: TLabel;
      l50: TLabel;
      l75: TLabel;
      l100: TLabel;
      Button1: TButton;
      procedure BBuscarClick(Sender: TObject);
      procedure BEnviarArchivosClick(Sender: TObject);
      procedure BGetListaToposClick(Sender: TObject);
      procedure FormCreate(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure BLanzarOptimizacionClick(Sender: TObject);
      procedure FormResize(Sender: TObject);
      procedure Button1Click(Sender: TObject);
{$ENDIF}
    private
      despachador: TDespachador;
      robotOrquestador: TRobotOrquestador;
{$IFDEF WINDOWS}
      procedure posicionarEtiquetasPorcentaje;
{$ENDIF}
      procedure lanzarOptimizacion(arch: String);
      procedure msgp_RecibirRespuesta(var Msg: TMessage); message uMsgsDespachador.MSGP_RECIBIR_RESPUESTA;
    public
{$IFDEF LINUX}
      recolectar: boolean;
      constructor Create(AOwner: TComponent); reintroduce;
      procedure Free; virtual;
{$ENDIF}
  end;

var
  OrquestadorV2: TOrquestadorV2;

implementation

uses uCosaConNombre;

{$IFNDEF LINUX}
{$R *.dfm}
{$ELSE}
var
  SActionRec: SigActionRec;

{ Procedimientos agregados para el manejo de seńales
del sistema.}  
procedure Handler(Sig : Integer); cdecl;
begin
  writeln('--estoy en el Handler---', GetThreadId);
  case Sig of
    SIGALRM:
    begin
      writeln('SIGALRM');
//      umensajesretardados.tic_Barrer;
      exit;
    end;
    SIGINT, SIGTERM :
    begin
      writeln('--- recibi SIGINT o SIGTERM --- pongo recolectar=false ' );
      OrquestadorV2.recolectar:= false;
      exit;
    end;
    //  SIGIO: writeln('SIGIO');
  end; { case }
end;

procedure InstallHandlers;
begin
  writeln('Instalo Handlers, ThreadId= ', GetThreadId);
  with SActionRec do
  begin
	  sa_handler:= SigActionHandler(@Handler);
  	fpsigemptyset(sa_mask);
	  sa_flags:= 0;
  end; { with }
	fpsigaction(SIGINT, @SActionRec, nil);
	fpsigaction(SIGTERM, @SActionRec, nil);
	fpsigaction(SIGALRM, @SActionRec, nil);
//   sigaction(SIGIO, @SActionRec, nil );
//  umensajesretardados.IniciarBarridos;
end;
{$ENDIF}

Constructor TRobotMensajeoMasivo.Create(despachador: TDespachador);
begin
  inherited Create(true);
  self.despachador:= despachador;
  self.FreeOnTerminate:= true;
  self.Resume;
end;

procedure TRobotMensajeoMasivo.execute;
const
  NIters= 10000;
var
  iter, iTareas: Integer;
  tareas: TList;
  datosNodo: TDatosNodo;
  conjuntoDeEjecucion: TConjuntoDeEjecucion;
  s: String;
  paramsEntrada: TBuffWriter;
  toTareas: Integer;
begin
  tareas:= TList.Create;
  conjuntoDeEjecucion:= TConjuntoDeEjecucion.Create(despachador.idsNodos);
  despachador.setDatosNodos(conjuntoDeEjecucion);
  despachador.setTemporizador(TTemporizadorUniOperacionPromedioMovil.Create(conjuntoDeEjecucion, despachador, 6));

  s:= 'Hola....';
  for iter := 1 to 40 do
      s:= s+ IntToStr(iter)+'123456789';

  try
    toTareas:= 300;
    for iter:= 0 to NIters - 1 do
    begin
      for iTareas:= 0 to despachador.conjuntoDeEjecucion.Count -1 do
      begin
        paramsEntrada:= TBuffWriter.Create(xSizeOf(s));
        paramsEntrada.xString(s);

        datosNodo:= despachador.conjuntoDeEjecucion[iTareas];
        tareas.Add(TFichaTarea.Create(uconstantes_nettopos.AppName_Topo, uconstantes_nettopos.MSGP_TOPO_MEMO_ADD,
                                      paramsEntrada, 0, toTareas, true, datosNodo.idNodo, true));
      end;
      if despachador.forkAndJoin(tareas, toTareas * despachador.conjuntoDeEjecucion.Count * 3) = 1 then
        writeln(iter, 'OK')
      else
      begin
        writeln(iter, 'Error');
{$IFDEF WINDOWS}
        //llamarAtencion(OrquestadorV2);
{$ENDIF}
      end;
      for iTareas:= 0 to despachador.conjuntoDeEjecucion.Count -1 do
        TFichaTarea(tareas[iTareas]).Free;
      tareas.Count:= 0;
    end;
  finally
    tareas.Free;
  end;
end;

{$IFDEF LINUX}
constructor TOrquestadorV2.Create(AOwner: TComponent);
{$ELSE}
procedure TOrquestadorV2.FormCreate(Sender: TObject);
{$ENDIF}
begin
{$IFDEF LINUX}
  inherited Create( AOwner );
  installHandlers;
  recolectar:= false;
{$ENDIF}
  inicializar;
	sysutils.DecimalSeparator := '.';
	DecimalSeparator:= '.';
	DateSeparator:= '/';
	ShortDateFormat:='d/m/y';
  uInicioYFinal.AlInicio;
{$IFDEF WINDOWS}
  registrarAplicacion(uMsgsOrquestadorV2.AppName, handle);
{$ELSE}
  registrarAplicacion(uMsgsOrquestadorV2.AppName, fpGetPid);
{$ENDIF}
  despachador:= NIL;
  robotOrquestador:= NIL;
  if idAplicYo = 0 then
  begin
    ShowMessage('ERROR: ' + uconstantes_nettopos.getNetTopos_StrError(getUltimoError));
{$IFDEF WINDOWS}
    PostQuitMessage(0);
{$ENDIF}
  end
{$IFNDEF WINDOWS}//Si estoy en linux debo recibir como parametro el archivo de sala
  else if ParamCount < 1 then
  begin
    ShowMessage('Debe indicar un archivo de corrida válido como parámetro de la aplicacion.');
  end
{$ENDIF}
  else
  begin
    despachador:= TDespachador.Create;
{$IFDEF WINDOWS}
    if ParamCount >= 1 then
      ENArch.Text:= ParamStr(1);
    self.Top:= 15;
    self.Left:= Screen.Width - Self.Width - 15;
{$ELSE}
    recolectar:= true;
    lanzarOptimizacion(ParamStr(1));
{$ENDIF}
  end;
end;

{$IFDEF LINUX}
procedure TOrquestadorV2.Free;
{$ELSE}
procedure TOrquestadorV2.FormDestroy(Sender: TObject);
{$ENDIF}
begin
  if idAplicYo > 0 then
  begin
    if robotOrquestador <> NIL then
    begin
      robotOrquestador.sala.globs.abortarSim:= true;
      robotOrquestador.WaitFor;
      robotOrquestador.Free;
    end;
    desregistrarAplicacion(idAplicYo);
    if despachador <> NIL then
      despachador.Free;
  end;
  finalizar;
  uInicioYFinal.AlFinal;
{$IFDEF LINUX}
  inherited Free;
{$ENDIF}
end;

{$IFDEF WINDOWS}
procedure TOrquestadorV2.FormResize(Sender: TObject);
begin
  posicionarEtiquetasPorcentaje;
end;

procedure TOrquestadorV2.BGetListaToposClick(Sender: TObject);
begin
  deshabilitarControles(self);
  despachador.getListaTopos;
  habilitarControles(self);
end;

procedure TOrquestadorV2.BLanzarOptimizacionClick(Sender: TObject);
begin
  lanzarOptimizacion(ENArch.Text);
end;

procedure TOrquestadorV2.Button1Click(Sender: TObject);
begin
  despachador:= TDespachador.Create;
  TRobotMensajeoMasivo.Create(self.despachador);
end;

procedure TOrquestadorV2.BBuscarClick(Sender: TObject);
begin
  if ODNArch.Execute then
  begin
    ODNArch.FileName:= quitarRaiz(ODNArch.FileName);
    ENArch.Text:= ODNArch.FileName;
  end;
end;

procedure TOrquestadorV2.BEnviarArchivosClick(Sender: TObject);
begin

end;

procedure TOrquestadorV2.posicionarEtiquetasPorcentaje;
begin
  l0.left:= PBOpt.left;
  l25.left:= trunc(PBOpt.left + PBOpt.Width * 0.25 - l25.width div 2);
  l50.left:= trunc(PBOpt.left + PBOpt.Width * 0.50 - l50.width div 2);
  l75.left:= trunc(PBOpt.left + PBOpt.Width * 0.75 - l75.width div 2);
  l100.left:= PBOpt.left + PBOpt.Width - l100.width;
end;
{$ENDIF}

procedure TOrquestadorV2.lanzarOptimizacion(arch: String);
begin
  if FileExists(arch) then
  begin
{$IFDEF WINDOWS}
    utilidades.deshabilitarControles(self);
    //Le asigno alta prioridad al hilo de escucha para que no se pierdan mensajes
    //por estar realizando calculos
    SetPriorityClass(GetCurrentProcess, HIGH_PRIORITY_CLASS);    
{$ENDIF}
    robotOrquestador:= TRobotOrquestador.Create(arch, despachador);
  end
  else
    ShowMessage('Debe Seleccionar un Archivo de Corrida Válido. arch = ' + arch);
end;

procedure TOrquestadorV2.msgp_RecibirRespuesta(var Msg: TMessage);
begin
//  writeln('Recibi respuesta', IntToStr(msg.WParam));
  despachador.recibirRespuesta(msg);
end;

end.
