PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV (précédentes versions) → Erreur en retour d'un HttpDonneRésultat
Erreur en retour d'un HttpDonneRésultat
Débuté par Thierry, 17 déc. 2023 09:02 - 10 réponses
Membre enregistré
7 messages
Posté le 17 décembre 2023 - 09:02
Bonjour,
Le problème suivant semble indépendant de la version de Windev.
La fonction HTTPDonneResultat me retourne une erreur "java.lang.OutOfMemoryError: Java heap space--null".
Après quelques recherches sur les forums, je comprends que ce message survient lorsque la machine virtuelle Java est en manque de mémoire et que la solution consisterait à augmenter la taille du tas... (comment ?).
L'erreur semble se produire en effet quand le fichier à récupérer est volumineux. Pourtant selon les jours, la requête importe parfois des fichiers d'une taille supérieure à 100 Mo. La même requête (mêmes paramètres) peut retourner ce message un jour et fonctionner le lendemain.
Bref, je manque de connaissances et de compétences dans le domaine pour résoudre le problème.

c_resu est un chaîne
j_resu est un JSON
HTTP.IgnoreErreur = httpIgnoreCertificatInvalide+httpIgnoreCertificatExpiré+httpIgnoreNomCertificatInvalide
SI httpRequête(c_websce,"","","","application/json","","")
c_resu = HTTPDonneRésultat()
j_resu=ChaîneVersJSON(c_resu)
SI ErreurDétectée ALORS
Erreur(ErreurInfo(errComplet))
SINON
// …
FIN
SINON
//…
FIN


Je suis preneur de toutes suggestions.
Merci pour votre aide.

--
Thierry
Membre enregistré
3 353 messages
Popularité : +93 (137 votes)
Posté le 17 décembre 2023 - 12:07
Salut
Déjà Le résultat de la requête est un buffer pas une chaîne.
As tu essayé la fonction HTTPDestination et enregistrer le json ?
J'aurais rajouter un HTTPTimeOut
De plus, comment fait tu pour savoir que les 100Mo sont bien téléchargés ?
Au moins avec HTTPDestination tu peux vérifier l'existence du fichier.
Il aurait été bien d'indiquer ta version de windev car les fonctions http ont beaucoup évolué.
Pourquoi n'utilise tu pas une variable httpRequête?
Membre enregistré
7 messages
Posté le 17 décembre 2023 - 14:40
Merci beaucoup pour ta réponse qui me donne des pistes à explorer... notamment le HTTPTimeOut
J'ai développé mon application en Windev 27.
Concernant le type de variable, je me suis inspiré de l'aide Windev. Le retour de HttpDonneRésultat est récupéré dans une variable chaîne.

// Récupération des éléments de la page Web "www.pcsoft.fr"
ResLancement = HTTPRequête("http://www.pcsoft.fr")
SI ResLancement = Vrai ALORS
ResCode est une chaîne = HTTPDonneRésultat()
Info("Code HTML : " + ResCode)
ResEntête est une chaîne = HTTPDonneRésultat(httpEntête)
Info("Entête : " + ResEntête)
ResCookie est une chaîne = HTTPDonneRésultat(httpCookie)
Info("Cookie : " + ResCookie)
FIN


Je connais la taille du fichier en le sauvegardant par fsauvetexte :

c_resu est une chaîne
j_resu est un JSON

c_path_json = ComplèteRep(c_path_tmp)+"IMPORT-"+DateHeureSys()+".JSON"

HTTP.IgnoreErreur = httpIgnoreCertificatInvalide+httpIgnoreCertificatExpiré+httpIgnoreNomCertificatInvalide
SI httpRequête(c_websce,"","","","application/json","","")
c_resu = HTTPDonneRésultat()
j_resu=ChaîneVersJSON(c_resu)
SI ErreurDétectée ALORS
Erreur(ErreurInfo(errComplet))
SINON
SI PAS fSauveTexte(c_path_json,j_resu) ALORS
Erreur("Échec lors de l'enregistrement du json")
FIN
FIN
SINON
c_erreur_appel="Échec du lancement d'HTTPRequête"+RC+ErreurInfo(errComplet)
FIN


Je vais tester en modifiant le timeout.
Membre enregistré
3 353 messages
Popularité : +93 (137 votes)
Posté le 17 décembre 2023 - 16:32
Justement, puisque tu enregistre dans un fichier.
La fonction HTTPDestination enregistre directement le résultat de la requête
Cela devrait utiliser moins de mémoire.
Membre enregistré
7 messages
Posté le 17 décembre 2023 - 17:57
Voilà, ce que j'ai expérimenté :
Passage du HTTPTimeOut à 60 secondes
Utilisation de la commande HTTPDestination("D:\TEST20231217.json")
Je récupère bien le fichier json mais vide du moins presque... il contient le message d'erreur :





Je vais revoir mon code en passant par une variable de type HTTPRequete... Je te tiendrai informé.

Merci encore pour ton aide.
Membre enregistré
3 353 messages
Popularité : +93 (137 votes)
Posté le 17 décembre 2023 - 18:22
Salut,
Je pense plutôt que c'est la requête le problème.
N'y a-t-il pas un moyen de réduire la taille du résultat de celle ci ?
Sinon tu peux ajouter une jauge dans ton premier code
https://doc.pcsoft.fr/?3043009
100Mo cela reste énorme pour un json.
Tu devrais voir l'exemple
LST n°108 : WD Téléchargement Partiel qui permet le téléchargement voir la reprise de téléchargement de fichiers via http
Message modifié, 17 décembre 2023 - 18:38
Membre enregistré
3 353 messages
Popularité : +93 (137 votes)
Posté le 17 décembre 2023 - 18:51
Resalut,
Pour t'aider voici une page sur le sujet
https://blogs.pcsoft.fr/fr/optimiser-utilisation-memoire-lors-transfert-donnees-vers-api-rest/281474976710965/read.awp
Sinon avec une variable de type httpRequête.
Il y a les propriétés
- ..Destination qui permet de spécifier le chemin de destination du fichier : cela évite de stocker en mémoire dans un buffer le contenu du fichier.
- ..AvancementTéléchargement qui vous permettra de suivre la progression du téléchargement dans une jauge ou dans les traces avec une fonction de callback
Membre enregistré
7 messages
Posté le 17 décembre 2023 - 20:10
Merci pour ces informations. Je vais expérimenter tout cela.
Je te tiendrai informé
Membre enregistré
3 895 messages
Popularité : +227 (347 votes)
Posté le 18 décembre 2023 - 09:40
Bonjour,
As-tu une bonne raison pour enregistrer le résultat ? Tu dois l'envoyer ailleurs ?
Ton API n'a-t-elle pas une option de pagination ?

--
Il y a peut être plus simple, mais, ça tourne
Message modifié, 18 décembre 2023 - 09:41
Membre enregistré
7 messages
Posté le 18 décembre 2023 - 11:10
Bonjour,
Oui, je traite le fichier json récupéré pour en extraire certains éléments et les enregistrer dans ma base HFSQL.
Qu'entends-tu par Option de pagination ?
Je ne suis pas vraiment en maîtrise de toutes les fonctions associées aux requêtes http...

Merci
Membre enregistré
3 895 messages
Popularité : +227 (347 votes)
Posté le 18 décembre 2023 - 11:31
Thierry a écrit :
Oui, je traite le fichier json récupéré pour en extraire certains éléments et les enregistrer dans ma base HFSQL

Il y a la désérialisation pour ça, sinon on revient aux BDD séquentielles
Qu'entends-tu par Option de pagination ?

Certaine API permettent de récupérer les données non pas en totalité mais par tranche de n enregistrements (une page,) un peu comme OFFSET dans la clause LIMIT. Cela évite une saturation mémoire.

Par ailleurs, ton problème ne vient pas de la requête proprement dite, mais de la mémoire allouée à ta machine Java.
Je te conseille de lire le billet suivant : https://stackoverflow.com/questions/14763079/what-are-the-xms-and-xmx-parameters-when-starting-jvm, ainsi que la doc Oracle correspondante : https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html

--
Il y a peut être plus simple, mais, ça tourne
Quand tout a échoué utilisez l'option RTFM
Message modifié, 18 décembre 2023 - 11:36