Jump to content

phénomène étrange après pcntl_fork / pcntl_waitpid


Recommended Posts

Bonjour,

 

Je suis en train de développer un module de paiement, et les besoins très spécifiques de la boutique et le process de la banque m'obligent à ce que mon URL de notification (url dans mon module, appelée par la banque en fin de paiement, de serveur à serveur) fasse 2 traitements :

- retourner OK et libérer le PHP tout de suite pour que la banque reçoive l'acquittement

- PUIS immédiatement APRES, rappeler la banque pour valider définitivement le paiement.

 

Quand je dis Immédiatement, c'est tout de suite, pas plus tard via une cron (même toutes les minutes).. Car le client attend derrière son écran avec un sablier, de savoir si sa commande est bien validée.

 

La seule solution que j'ai trouvé est d'utiliser pcntl_fork()

Le fils retourne OK puis exit (ça fonctionne, tout est OK en banque.)

Le père attend la réponse du fils avec pcntl_waitpid() puis continue son traitement en appelant l'url bancaire (une partie du traitement fonctionne, mais avec des effets de bord)

 

Mon problème :

Juste après pcntl_fork(), un Logger::addLog() envoie bien 2 logs (père et fils).

Mais dès que pcntl_waitpid() est passé (dès que le fils a fait son exit), les Logger::addLog(() du père ne semblent plus fonctionner.. Ce qui augure que d'autres fonctions Prestashop risquent de ne pas fonctionner non plus (une partie du code fonctionne tout de même)...

 

Bref, je me demande si le exit du fils ne fermerait pas certaines ressources Prestashop, devenues inaccessible au père qui lui continue de tourner..

 

Help !

 

Link to comment
Share on other sites

Merci de t'intéresser à mon post.

 

En fait les options du TPE bancaire sont forcés pour que le paiement du client corresponde à une demande d'autorisation.

Bref, le client n'est pas débité, on  s'assure juste que la carte est correcte.

Ce paramétrage n'est pas modifiable (stratégie de la boutique).

Par contre, je souhaite transformer le panier en commande prestashop uniquement si nous arrivons à DEBITER le client.

 

Donc :

- tunnel classique

- envoi du client vers la page de paiement bancaire

- la banque retourne (en mode serveur à serveur) le résultat de cette autorisation à une URL de notification.

- la banque attend en retour de cet appel une confirmation du programme (un acquittement)

.. ce qui veut dire un echo "ok" + fin de la connexion HTTP. cet acquittement doit être fait tout de suite, avant d'autres traitements.

 

- en plus, moi, je veux rappeler la banque en mode serveur à serveur, pour valider cette autorisation et débiter le client.

donc la seule solution que je vois, c'est que mon url de notification, elle fasse les 2 jobs, à savoir :

 - un echo "ok" + exit

 ET (PUIS)

 -  un curl pour valider le paiement

 

.. c'est tiré par les cheveux, mais j'ai pas trouvé d'autres solutions..

Le fork répondait à mon besoin, seulement lorsque le fils (ou le père) fait un exit, l'autre process perd une partie de prestashop ("Logger" qui ne fonctionne plus, envoi de mail hs, chargement du panier qui ne marche plus)

 

 

J'ai testé 5 mécaniques différentes avec des forks ou des "close-connection" ou encore des flush(), en vain.

Pour le moment, j'ai trouvé une solution alternative en passant par un exec(xxxx >/dev/null &)..

Pas très élégant, mais ça à le mérite de marcher en attendant mieux..

Link to comment
Share on other sites

En fait, faire ce que tu veux est loin d'être facile en PHP, et donc rarement mis en place lorsqu'il s'agit d’interagir avec une banque. (d'où mon scepticisme).

Tu dis que le client patiente avec un sablier, mais sur quel requête ?

 

 

Bref, tu as une requête (le callback de la banque) et tu aimerais initier un traitement après avoir répondu à cette requête.

Et tu n'a pas besoin de faire une synchronisation.

 

Plusieurs solutions s'offrent à toi :

- faire un fork

- lancer un programme externe

- utiliser une file de message

 

Utiliser une file de message serait le plus "élégant", mais probablement trop lourd à mettre en place pour ton besoin.

Lancer un programme externe, serait probablement le plus approprié, attentions à ne pas introduire de failles de sécurité.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...