#!/usr/bin/perl
# $Id: oar_sched_fifo_queue_killer,v 1.11 2004/08/24 15:56:56 neyron Exp $

use strict;
use DBI();
use oar_iolib;
use Data::Dumper;
use oar_Judas qw(oar_debug oar_warn oar_error);

my $base = &iolib::connect();

my $done =0;
my $doneToLaunch=0;
my $doKill = 0;
my $queue = shift;

if (!defined($queue)){
    oar_error("You must specify a queue number for this scheduler !!");
    exit(1);
}

oar_debug "Begining of scheduler FIFO for queue $queue\n";
while(! $done)
{
    $done = 1;
    # recuperer le premier (date de soumission) job W
    # A CORRIGER : on pourrait tout reccuperer en une seule fonction...
    my $idJob = &iolib::get_oldest_waiting_idjob_by_queue($base,$queue);
    if ($idJob == -1)
    {
    last;
    }

    oar_debug "Job found : $idJob\n";
    my $ref =  &iolib::get_job($base, $idJob);

    # recuperer le nombre de noeud total
    my @noeuds_vivants = &iolib::get_alive_node_job($base, $idJob);
    my $nbnoeuds_demandes = $ref->{'nbNodes'};

    # verifier qu'il y a suffisament de noeud vivant
    if ($#noeuds_vivants+1 < $nbnoeuds_demandes)
    {
    # mettre le job en erreur
    oar_debug("Not enough Alive nodes\n");
    &iolib::set_job_state($base, $idJob, 'Error');

    $done=0;
    next;
    }

    # construire la liste des noeuds a utiliser :

    my $jobweight = $ref->{'weight'};


    # recuperer le maxpoid
    my $maxpoid = &iolib::get_maxweight_node($base);


    my @liste_noeuds = ();
    # si le job est en mode partage
    if (($jobweight <= $maxpoid) && ($jobweight > 0)){

        my %reshash= &iolib::get_free_nodes_job_killer($base,$idJob, $nbnoeuds_demandes,$jobweight);

        if ($reshash{'nbnodes'} > 0){
            @liste_noeuds = @{$reshash{'procs'}};
        }else{
            @liste_noeuds = ();
        }
        $doKill = $reshash{'retval'};
    }else{
        oar_error("job $idJob weight ($jobweight) greater than maxWeight ($maxpoid) or lower than 0\n");
        exit(2);
    }

    # si il y a suffisament de noeuds
    if( $#liste_noeuds+1 >= $nbnoeuds_demandes)
    {
    $doneToLaunch = 1;
    my $i=0;
    for($i=0; $i < $nbnoeuds_demandes; $i++)
    {
        # ajouter le couple id:noeuds
        &iolib::add_node_job_pair($base,$idJob,$liste_noeuds[$i]);
        #incrementer les poids
        my $nodeweight = &iolib::get_weight_node($base,$liste_noeuds[$i]);
        &iolib::set_weight_node($base,$liste_noeuds[$i], $nodeweight+$jobweight);
    }
    # passer le job a l'etat L
    &iolib::set_job_state($base, $idJob, 'toLaunch');

    #recommencer
    $done = 0;
    }
}

&iolib::disconnect($base);

oar_debug "End of scheduler FIFO killer\n";

if ($doKill == 1)
{
    exit 2;
}

if ($doneToLaunch == 1)
{
    exit 1;
}
if ($doneToLaunch == 0)
{
    exit 0;
}
