Question
Gestion d'une file d'attente
- Phil'z Edward
- Auteur du sujet
- Hors Ligne
- Membre senior
-
Réduire
Plus d'informations
- Messages : 45
- Remerciements reçus 0
il y a 13 ans 8 mois #12634
par Phil'z Edward
Réponse de Phil'z Edward sur le sujet Re:Gestion d'une file d'attente
Voici une ébauche de ce que j'ai réussi à faire en ajoutant le timeout, le nombre max de tache dans la file d'attente
La fonction dequeue sur laquelle je suis encore entrain de travailler pour quelle puisse gérer le fait que si une tache n'a pas été résolu elle le remette dans la file d'attente
[code:1]
<#
.SYNOPSIS
Création d'une file d'attente avec gestion de tâches: Réplication & Consolidation.
.PARAMETRE
System.Collection.Queue pour gérer la file d'attente
Start-job pour gérer les différentes tâches de la file d'attente en arrière plan
.AUTHOR
...
#>
#
$MaxQueueMag = 100
$MaxAllowedJobRuntimeInMinutes = 1
$QueueCount = 0
$QueueHead = 0
$QueueTail = 0
$Queue = New-Object int[] ($MaxQueueMaag)
#Ajout des magasins à la file d'attente si liste < 100 / Envoie un message si liste = 100
function Enqueue([int] $Value)
{
if($QueueCount -eq $MaxQueueMag)
{
throw \"La liste Est Pleine!!!\"
}
else
{
$script:QueueCount++
$script:Queue[$QueueHead] = $Value
}
$script:QueueHead = NextIndex $QueueHead
\"Enqueue:$Value QueueCount=$QueueCount QueueHead=$QueueHead QueueTail=$QueueTail Queue = $Queue\"
}
#Enlève des magasins à la file d'attente si la tâche a été traîtée sinon remettre dans la file d'attente
function Dequeue
{
if($QueueCount -eq 0)
{
throw \"La file d'attente est vide!!!\"
}
else
{
$script:QueueCount--
$ReturnValue=$Queue[$QueueTail]
$script:QueueTail = NextIndex $QueueTail
}
\"Dequeue:$ReturnValue QueueCount=$QueueCount QueueHead=$QueueHead QueueTail=$QueueTail Queue = $Queue\"
}
Function NextIndex([int] $currentIndex)
{
if($currentIndex -eq $MaxQueueMag-1)
{
$currentIndex = 0
}
else
{
$currentIndex++
}
return $currentIndex
}
Function Split-MagJobName {
#Parse le nom d'un Job et renvoi un objet
param ($MagJobName)
$Nom,$Date=$MagJobName -split \"\\\"
New-Object PSObject -Property @{Magasin=($Nom -Replace \"^MAG\",\"\"«»);
StartTime=([DateTime]::FromBinary($Date));
State=$Null;
Name=$MagJobName #Nom du job utilisé par Stop-Job
}
}
Function New-Magasin {
param(
[String]$NomMag,
[String]$NumMag
)
New-Object PsObject -property @{
Nom=$NomMag;
Numero=$NumMag;
DebutReplication=$Null;
FinReplication=$null;
Success=$null
}
}
$Path=\"\\serveurdefichier\\" #Chemin d'accès vers le script ou le point exe
@'
param($Magasin)
Write-host \"Traite le magasin situé à $($Magasin.Nom)\" -Fore White
Sleep -Seconds (Get-Random -Maximum 3 -Minimum 1)
$result=(Get-Random -Maximum 2 -Minimum 0) -as [Boolean]
if ($result )
{Write-host \"Réussite du traitement du magasin situé à $($Magasin.Nom)\" -Fore Green}
else
{Write-host \"Echec du traitement du magasin situé à $($Magasin.Nom)\" -Fore Red}
$Magasin.FinReplication=[DateTime]::Now
$Magasin.Success=$Result
return $Magasin
'@ > $Path
$Magasins=@(
(New-Magasin 'Limoges' 132),
(New-Magasin 'Marseille' 131),
(New-Magasin 'Lyon' 155),
(New-Magasin 'Lille' 123),
(New-Magasin 'Bordeaux' 152),
(New-Magasin 'Montpellier' 151),
(New-Magasin 'Brest' 141),
(New-Magasin 'St-Etienne' 133),
(New-Magasin 'Clermont' 166)
)
# How many jobs we should run simultaneously
$MaxConcurrentJobs = 5;
$Queue = [System.Collections.Queue]::«»Synchronized( (New-Object System.Collections.Queue) )
foreach($Mag in $Magasins)
{ $Queue.Enqueue($Mag) }
# Function that pops input off the queue and starts a job with it
function Start-JobFromQueue
{
#Create Job TimeOut Timer implémenté à 1h
$Timer = New-Object System.Timers.Timer
$Timer.Interval = MaxAllowedJobRuntimeInMinutes * 60
$Timer.AutoReset = $False
$Timer.Enabled = $True
$Timer.Start()
#Create Event Suscriber for Job TimeOut Timer Elapsed Event
Register-ObjectEvent -InputObject $Timer -EventName Elapsed -MessageData $Job -Action {
if(Get-Job | ?{$_.InstanceID -eq $Event.MessageData.InstanceID}){
Write-Warning (\"Job\" + $Event.MessageData.ID + \"Has Exceeded The Max Allowed Runtime And Will Be Terminated\"«»)
$Event.MessageData | Stop-Job
}
if( $Queue.Count -gt 0)
{
$MagasinCourant=$Queue.Dequeue()
$StartDate=[DateTime]::Now
$MagasinCourant.DebutReplication=$StartDate
$JobName=\"MAG$($MagasinCourant.Nom)\$($StartDate.ToBinary())\"
$CurrentJob = Start-Job -FilePath $Path -ArgumentList $MagasinCourant -Name $JobName
Register-ObjectEvent -InputObject $CurrentJob -EventName StateChanged -SourceIdentifier \"Event$JobName\" -Action {
Start-JobFromQueue
Unregister-Event $eventsubscriber.SourceIdentifier
Remove-Job $eventsubscriber.SourceIdentifier
} | Out-Null
}
}
# Start up to the max number of concurrent jobs
# Each job will take care of running the rest
for( $i = 0; $i -lt $MaxConcurrentJobs; $i++ )
{
Start-JobFromQueue
}
sleep -Seconds (1*60)
$MagasinsResultat=Get-Job|Where-Object {$_.Name -Match \"^MAG\"}|Receive-Job -keep
#Exporter le resultat dans un fichier .TXT
$global:folderSource = \"\\serveurdefichier\repertoire\\"
$template = ' $MagasinsResultat '
$export = $global:folderSource + \"Replication-\" + (Get-Date -Format yyyy-MM-dd) + \".txt\"
$global:file | Out-File $export -encoding UTF8
[/code:1]
Merci pour remarques et suggestions
cdt,<br><br>Message édité par: PE2012, à: 5/09/12 10:22
La fonction dequeue sur laquelle je suis encore entrain de travailler pour quelle puisse gérer le fait que si une tache n'a pas été résolu elle le remette dans la file d'attente
[code:1]
<#
.SYNOPSIS
Création d'une file d'attente avec gestion de tâches: Réplication & Consolidation.
.PARAMETRE
System.Collection.Queue pour gérer la file d'attente
Start-job pour gérer les différentes tâches de la file d'attente en arrière plan
.AUTHOR
...
#>
#
$MaxQueueMag = 100
$MaxAllowedJobRuntimeInMinutes = 1
$QueueCount = 0
$QueueHead = 0
$QueueTail = 0
$Queue = New-Object int[] ($MaxQueueMaag)
#Ajout des magasins à la file d'attente si liste < 100 / Envoie un message si liste = 100
function Enqueue([int] $Value)
{
if($QueueCount -eq $MaxQueueMag)
{
throw \"La liste Est Pleine!!!\"
}
else
{
$script:QueueCount++
$script:Queue[$QueueHead] = $Value
}
$script:QueueHead = NextIndex $QueueHead
\"Enqueue:$Value QueueCount=$QueueCount QueueHead=$QueueHead QueueTail=$QueueTail Queue = $Queue\"
}
#Enlève des magasins à la file d'attente si la tâche a été traîtée sinon remettre dans la file d'attente
function Dequeue
{
if($QueueCount -eq 0)
{
throw \"La file d'attente est vide!!!\"
}
else
{
$script:QueueCount--
$ReturnValue=$Queue[$QueueTail]
$script:QueueTail = NextIndex $QueueTail
}
\"Dequeue:$ReturnValue QueueCount=$QueueCount QueueHead=$QueueHead QueueTail=$QueueTail Queue = $Queue\"
}
Function NextIndex([int] $currentIndex)
{
if($currentIndex -eq $MaxQueueMag-1)
{
$currentIndex = 0
}
else
{
$currentIndex++
}
return $currentIndex
}
Function Split-MagJobName {
#Parse le nom d'un Job et renvoi un objet
param ($MagJobName)
$Nom,$Date=$MagJobName -split \"\\\"
New-Object PSObject -Property @{Magasin=($Nom -Replace \"^MAG\",\"\"«»);
StartTime=([DateTime]::FromBinary($Date));
State=$Null;
Name=$MagJobName #Nom du job utilisé par Stop-Job
}
}
Function New-Magasin {
param(
[String]$NomMag,
[String]$NumMag
)
New-Object PsObject -property @{
Nom=$NomMag;
Numero=$NumMag;
DebutReplication=$Null;
FinReplication=$null;
Success=$null
}
}
$Path=\"\\serveurdefichier\\" #Chemin d'accès vers le script ou le point exe
@'
param($Magasin)
Write-host \"Traite le magasin situé à $($Magasin.Nom)\" -Fore White
Sleep -Seconds (Get-Random -Maximum 3 -Minimum 1)
$result=(Get-Random -Maximum 2 -Minimum 0) -as [Boolean]
if ($result )
{Write-host \"Réussite du traitement du magasin situé à $($Magasin.Nom)\" -Fore Green}
else
{Write-host \"Echec du traitement du magasin situé à $($Magasin.Nom)\" -Fore Red}
$Magasin.FinReplication=[DateTime]::Now
$Magasin.Success=$Result
return $Magasin
'@ > $Path
$Magasins=@(
(New-Magasin 'Limoges' 132),
(New-Magasin 'Marseille' 131),
(New-Magasin 'Lyon' 155),
(New-Magasin 'Lille' 123),
(New-Magasin 'Bordeaux' 152),
(New-Magasin 'Montpellier' 151),
(New-Magasin 'Brest' 141),
(New-Magasin 'St-Etienne' 133),
(New-Magasin 'Clermont' 166)
)
# How many jobs we should run simultaneously
$MaxConcurrentJobs = 5;
$Queue = [System.Collections.Queue]::«»Synchronized( (New-Object System.Collections.Queue) )
foreach($Mag in $Magasins)
{ $Queue.Enqueue($Mag) }
# Function that pops input off the queue and starts a job with it
function Start-JobFromQueue
{
#Create Job TimeOut Timer implémenté à 1h
$Timer = New-Object System.Timers.Timer
$Timer.Interval = MaxAllowedJobRuntimeInMinutes * 60
$Timer.AutoReset = $False
$Timer.Enabled = $True
$Timer.Start()
#Create Event Suscriber for Job TimeOut Timer Elapsed Event
Register-ObjectEvent -InputObject $Timer -EventName Elapsed -MessageData $Job -Action {
if(Get-Job | ?{$_.InstanceID -eq $Event.MessageData.InstanceID}){
Write-Warning (\"Job\" + $Event.MessageData.ID + \"Has Exceeded The Max Allowed Runtime And Will Be Terminated\"«»)
$Event.MessageData | Stop-Job
}
if( $Queue.Count -gt 0)
{
$MagasinCourant=$Queue.Dequeue()
$StartDate=[DateTime]::Now
$MagasinCourant.DebutReplication=$StartDate
$JobName=\"MAG$($MagasinCourant.Nom)\$($StartDate.ToBinary())\"
$CurrentJob = Start-Job -FilePath $Path -ArgumentList $MagasinCourant -Name $JobName
Register-ObjectEvent -InputObject $CurrentJob -EventName StateChanged -SourceIdentifier \"Event$JobName\" -Action {
Start-JobFromQueue
Unregister-Event $eventsubscriber.SourceIdentifier
Remove-Job $eventsubscriber.SourceIdentifier
} | Out-Null
}
}
# Start up to the max number of concurrent jobs
# Each job will take care of running the rest
for( $i = 0; $i -lt $MaxConcurrentJobs; $i++ )
{
Start-JobFromQueue
}
sleep -Seconds (1*60)
$MagasinsResultat=Get-Job|Where-Object {$_.Name -Match \"^MAG\"}|Receive-Job -keep
#Exporter le resultat dans un fichier .TXT
$global:folderSource = \"\\serveurdefichier\repertoire\\"
$template = ' $MagasinsResultat '
$export = $global:folderSource + \"Replication-\" + (Get-Date -Format yyyy-MM-dd) + \".txt\"
$global:file | Out-File $export -encoding UTF8
[/code:1]
Merci pour remarques et suggestions
cdt,<br><br>Message édité par: PE2012, à: 5/09/12 10:22
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.032 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Gestion d'une file d'attente