Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
J'ai un problème de FileOpen en lecture seule qui ne passe pas chez un client et l'anomalie ne se présente pas en base test chez nous.
L'ano semble lié au fait que le fichier est ouvert en LockReadWrite! pour être remplis. Fermé juste avant une ré-ouverture pour un contrôle d'enchaînement des lignes.
Il y a donc à priori une latence entre le fileclose et la fermeture effective du fichier, le programme arrivant au fileopen "trop tôt".
Est ce que vous avez déjà noté ce genre de problème?
Connaissez vous un équivalent de fonction flush qui forcerais l'exécution de fermeture du fichier pour ré-ouvrir ses droit de lecture?
Merci d'avance.
Hors ligne
Bonjour,
Et en mettant un petit temps d'attente (genre sleep(1)) ou alors une boucle dans le genre : do until fileopen = 1 ?
Hors ligne
C'est ce que j'ai proposé mais mon chef et pas trop pour et préférerai un usage de fonction flush (ou plutot équivalent car flush n'existe pas en PB)
Sachant que je ne pouvais pas reproduire le cas et que j'ai demandé à la personne chargé du client de vérifié ça directement sur l'environnement client.
Ce qui a encore moins plus à mon chef
Dernière modification par Van (19-03-2013 13:46:14)
Hors ligne
peut-être aussi une question d'OS (?)
Hors ligne
Bonjour,
Pour ce genre de problème, éventuellement :
DO WHILE Yield() LOOP
Hors ligne
erasorz a écrit:
peut-être aussi une question d'OS (?)
C'est ce que j'ai avancé aussi mais mo chef me soutient que s'il y a une lantence c'est au niveau du code que je dois gérer.
Pour le coup le principe de dire j'ouvre le fichier, je le ferme pour le rouvrir directement derrière me plait déjà pas trop mais c'est du code exisant depuis une petit quizaine d'année, je vais donc pas ré-écrire (hélas).
J'aurais largement préféré une datawindow/saveas avec le contrôle des lignes par unr boucle for en fin si nécessaire.
Dernière modification par Van (19-03-2013 14:08:17)
Hors ligne
erasorz a écrit:
Bonjour,
Et en mettant un petit temps d'attente (genre sleep(1)) ou alors une boucle dans le genre : do until fileopen = 1 ?
Comment dire...
Et si jamais le chemin est incorrect ou que pour une raison externe la resource n'est pas dispo, on plante le programme indéfiniment ?
Au peer 2 peer avec un code comme ça, je mettrais au moins un yield() ou un sleep() système pour rendre la main à la machine.
Van a écrit:
le programme arrivant au fileopen "trop tôt"
L'expérience m'a déjà prouvé que lorqu'on en vient à se dire "mon programme / ordi va trop vite, il faudrait peut-être le ralentir", le problème est généralement ailleurs.
Il n'y aurait pas une info non décrite qui expliquerait le cas ? Genre le fichier est sur un share réseau, une clé usb, ou un truc du genre et il faut un certain temps pour que l'écriture soit effective et la réouverture ne bloque pas tant que le fichier n'est pas dispo ? (et encore, si il y a un problème de flush, le fichier est déjà dispo dans le cache disque)
Dernière modification par seki (19-03-2013 14:10:07)
Hors ligne
Pour le coup j'ai rajouter une boucle de x essais (x paramétrable) de FileOpen.
Chaque essai à droit à un yield et une seconde d'attente si le fichier n'a pas été ouvert. En pratique un seul essai supplémentaire devrais être nécessaire.
Si on atteind le nombre max d'essais un message en journal d'erreur du programme préviend l'utilisateur du problème.
Le paramétrage du chemin d'accès au fichier est un disque physique du serveur sur lequel tourne le programme.
Hors ligne
seki a écrit:
erasorz a écrit:
Bonjour,
Et en mettant un petit temps d'attente (genre sleep(1)) ou alors une boucle dans le genre : do until fileopen = 1 ?Comment dire...
Et si jamais le chemin est incorrect ou que pour une raison externe la resource n'est pas dispo, on plante le programme indéfiniment ?
Au peer 2 peer avec un code comme ça, je mettrais au moins un yield() ou un sleep() système pour rendre la main à la machine.
c'était une piste brute de coffrage...
j'allais pas coder un truc pareil sans garde-fou, hein
<HS>, ça vaut bien un :
for (var i = 1; true; i++) { if (i < 10) { ... } else break; }
</HS>
Hors ligne
erasorz a écrit:
c'était une piste brute de coffrage...
j'allais pas coder un truc pareil sans garde-fou, hein
J'éspère bien C'était juste histoire de dire... Pour une fois qu'il y a un peu d'animation depuis quelques jours.
Hors ligne
Bon finalement mon chef me laisse mettre en place la boucle x tentative d'essai sur laquelle on est plusieurs à pencher.
//boucle de tentatives d'ouverture du fichier for li_nb_ouv_tst = 1 to li_ouv_tst //li_ouv_tst paramétrable mais limité à 30 par code pour évité le gugus qui mettrais 30000 ii_noFichierRM = FileOpen(is_fg, StreamMode!, Read!, shared!) if isnull(ii_noFichierRM) then //ne devrais pas arrivé mais on prend pas de risque uf_journal("Erreur grave, le chemin et nom de fichier est null") exit end if if ii_noFichierRM > 0 then exit //fichier ouvert on sort de la boucle f_attente(1) //fonction faisant un yield dans une boucle do loop pendant le nombre de seconde envoyé en paramétre if li_nb_ouv_tst > 1 then uf_aff("tentative d'ouverture du fichier : "+string(li_nb_ouv_tst) +"/"+string(li_ouv_tst)) //affichage d'un message spécifiant à l'utilisateur que le programme tente l'ouverture next
Dernière modification par Van (20-03-2013 13:20:12)
Hors ligne
Puisque vous creusez la piste de la boucle, mettez au moins un yield() dans la boucle, histoire de ne pas geler l'appli pendant l'attente et aussi une petite tempo (avec le sleep() système qui est plus fin que le sleep PB) pour ne pas faire les 30 tours de boucle trop vite
global type syssleep from function_object end type type prototypes subroutine winSleep(ulong dwMilliseconds) Library "KERNEL32.DLL" Alias for "Sleep" end prototypes forward prototypes global subroutine syssleep (unsignedlong aul_milliseconds) end prototypes global subroutine syssleep (unsignedlong aul_milliseconds); // System Sleep (in milliseconds) winsleep(aul_milliseconds) end subroutine
Hors ligne
C'est dans la fonction f_attente()
do yield() loop until datetime(today(),now()) >ldt_temp //ldt_temp = le temps à l'entrée de la fonction plus les x secondes envoyé en paramétré de la fonction
Hors ligne