[spip-dev] API queue_add_job

Cédric ayant codé un super plugin “job_queue” pour programmer des tâches à lancer en différé, j’ai ajouté un inc/queue minimal pour le core. Ce fichier ne contient que l’API de base, ce qui permet de ne pas avoir à tester la présence du plugin pour utiliser la fonction

function queue_add_job($function, $description, $arguments = array(), $file = ‘’, …)

(Cette fonction a des arguments un peu inhabituels dans SPIP car elle reprend la nomenclature de la fonction équivalente dans Drupal.)

A noter un problème : on ne peut pas brancher envoyer_mail() dessus comme ça sinon on perd le message d’erreur en cas de mail important (genre, un envoi de demande de confirmation lors d’une signature de pétition). Il faudrait donc voir si on éclate envoyer_mail() en deux fonctions, l’une en direct lorsqu’on a vraiment besoin de controler le retour de la fonction, l’autre en différé ?

Quoi qu’il en soit sur forum.spip.org, où ce plugin est installé, les notifications se font en différé, ce qui fait que l’envoi d’un message est de nouveau immédiat.

– Fil

limpide non ?

:wink:

Committo,Ergo:Sum

les notifications se font en différé, ce qui fait que l'envoi d'un message
est de nouveau immédiat.

limpide non ?

Il y a une logique à suivre, c'est vrai :slight_smile:

-- Fil

http://geekandpoke.typepad.com/.a/6a00d8341d3df553ef0120a58e9ad6970b-pi

En fait l’api publique de job_queue est definie dans
http://zone.spip.org/trac/spip-zone/browser/plugins/job_queue/queue_options.php
C’est donc plutot ces 3 fonctions que j’aurais implémenté directement dans inc/utils par un
job_queue_add(…){
if (include_spip(‹ inc/queue ›))
return queue_add_job(…)
else {
}
}
idem pour les 2 autres qui n’ont rien a faire sinon.

Mais on peut aussi dire qu’on supprime cette api publique et qu’on doit inclure inc/queue pour utiliser queue_add_job.

En tout cas, là c’est batard car les plugins comme microblog ou notifications appellent job_queue_add.

Cédric

Si c'est parce qu'une bonne partie du code a lui-même été repris c'est compréhensible. Mais sinon ?

@ Cédric:

En tout cas, là c'est batard car les plugins comme microblog ou
notifications appellent job_queue_add.

Je n'avais pas vu ça, il faut changer comme tu dis.

@ RastaPopoulos <rastapopoulos@spip.org>:

(Cette fonction a des arguments un peu inhabituels dans SPIP car elle
reprend la nomenclature de la fonction équivalente dans Drupal.)

Si c'est parce qu'une bonne partie du code a lui-même été repris c'est
compréhensible. Mais sinon ?

C'est dans une optique de portabilité/généricité des API.

-- Fil

@ Cédric:

En tout cas, là c'est batard car les plugins comme microblog ou
notifications appellent job_queue_add.

Je n'avais pas vu ça, il faut changer comme tu dis.

@ RastaPopoulos <rastapopoulos@spip.org>:

(Cette fonction a des arguments un peu inhabituels dans SPIP car elle
reprend la nomenclature de la fonction équivalente dans Drupal.)

Si c'est parce qu'une bonne partie du code a lui-même été repris c'est
compréhensible.

Non, le code n'a pas été repris.

Mais sinon ?

C'est dans une optique de portabilité/généricité des API.

Sauf que drupal 7 a integre une queue avec une autre API.
Je l'ai vu qu'apres :stuck_out_tongue: ...

Cédric

On va encore se mordre la queue…

Donc http://drupal.org/project/job_queue qui a été repris
Contre http://api.drupal.org/api/drupal/modules--system--system.queue.inc/7/source inséré dans D7…

J'aime bien leur API sql au passage… c'est plus clair que la notre, mais plus long à écrire.

         $update = db_update('queue')
           ->fields(array(
             'consumer_id' => $this->consumerId,
             'expire' => time() + $lease_time,
           ))
           ->condition('item_id', $item->item_id)
           ->condition('consumer_id', 0);
         // If there are affected rows, this update succeeded.
         if ($update->execute()) {

Sauf que drupal 7

...

J'aime bien leur API sql au passage… c'est plus clair que la notre, mais plus long à écrire.

La nôtre n'est historiquement pas beaucoup plus qu'un gros Sed sur un source MySQL pas prévu pour cela, partant c'est clair qu'il faudra la revoir, c'est d'ailleurs pourquoi j'ai tout de suite mis un gestionnaire de version intégrée qui permettra en particulier d'exécuter dans un même script des bouts de code de versions différentes de l'API.

Maintenant, le recours aux objets pour définir les interfaces, bof. La verbosité n'a jamais été un gage de précision.

Committo,Ergo:Sum

Bah, justement, ce que j'apprécie, c'est le chainage possible ->fonction() qui n'est réalisable qu'avec des objets. Mais je sais pas si on parle de la même chose là.

Dans le cas précis des soucis que j'ai avec notre API, c'est que je suis incapable d'écrire un sql_select() sans aller regarder ses arguments dans /base/abstract_sql dès lors que j'ai un group ou order à mettre parce que j'arrive pas à retenir l'ordre des paramètres. Qui plus est, si on veut juste une limite, il faut renseigner les précédents group et order alors qu'on n'en a pas besoin…

C'est ça que je trouve intéressant dans leur écriture, c'est que tu définis simplement ce qui t'intéresse ->condition() (->where() eut ptet été plus clair), mais on peut imaginer ->groupby(), ->limit(), ->having(), etc.

Tu peux commencer à écrire une requête sans l'executer aussi
$req = db_select('table')->condition('titre','Tim');
if ($en_plus) {
  $req->condition('qqc','valeur');
}
$res = $req->execute();

Je pense que si on remplacait une liste d'argument par un argument tableau indexe, cela serait peut être plus facile :
sql_select(array('select'=>'*','from'=>'spip_articles','where'=>'id_article=3'))

Cédric

+1
L'idée me plait beaucoup ! (honte à moi mais j'oublie souvent l'ordre des arguments actuels...)

Oh ça, c'est du sucre syntaxique sans difficulté à mettre au-dessus de notre API.
On peut même écrire un script Shell de qq lignes qui te prend toutes les déclarations "function .." de abstract_sql et en fait un objet dont les variables rémanentes sont homonymes des paramètres des fonctions actuelles.
Je ne dis pas que cette écriture est dénuée d'avantages, mais ce n'est vraiment pas ce qui détermine la qualité de conception d'une API.

Committo,Ergo:Sum

S'lt

Bah, justement, ce que j'apprécie, c'est le chainage possible ->fonction()
qui n'est réalisable qu'avec des objets. Mais je sais pas si on parle de la
même chose là.

Je pense que si on remplacait une liste d'argument par un argument tableau
indexe, cela serait peut être plus facile :
sql_select(array('select'=>'*','from'=>'spip_articles','where'=>'id_article=3'))

L'idée du tableau indexé me plait bien. On avait déjà abordé ce genre
de solution sur d'autres point d'API.
L'écriture objet ne semble pas apporter grand chose me semble t il.

Km

Comme déjà répondu, un tableau indexé serait déjà mieux que la solution actuelle, et de toute façon le chainage de méthodes n'est pas possible en PHP4 (on continue à conserver la compatibilité, non ?).

-Nicolas

Moi je ne dis plus un mot sur la compat PHP4 depuis que je n'arrive plus à l'assurer avec Porte Plume… C'est soit PHP4 fonctionne et PHP5 «notice» des problèmes… soit comme en ce moment PHP5 tourne à merveille, mais PHP4 se vautre en beauté… et comme j'ai pas réussi à corriger… c'est comme ça depuis un bon moment…

Comme déjà répondu, un tableau indexé serait déjà mieux que la solution
actuelle, et de toute façon le chainage de méthodes n'est pas possible

donc la solution actuelle est meilleure, car le chaînage de méthoes n'est rien d'autre que la composition de fonctions,
opération vieille de quelques siècles que la méthodologie objet a affublé d'un vocabulaire pompeux sans même arriver toujours
à la restituer dans son intégralité.

en PHP4 (on continue à conserver la compatibilité, non ?).

Moi je ne dis plus un mot sur la compat PHP4 depuis que je n'arrive plus à l'assurer avec Porte Plume… C'est soit PHP4 fonctionne et PHP5 «notice» des problèmes… soit comme en ce moment PHP5 tourne à merveille, mais PHP4 se vautre en beauté… et comme j'ai pas réussi à corriger… c'est comme ça depuis un bon moment…

Le meilleur moyen d'assurer la compatiblité, c'est de se dispenser d'utiliser des gadgets aux performances minables et la phraéologie insupportable. Les modèles objets de PHP en sont un bon exemple.

Committo,Ergo:Sum

Ah non, je me permets d'émettre une réserve ! Je ne suis pas tout à fait d'accord… Je crois que tu omets de créer un code «accessible» comme SPIP voulait l'être… et ce qui peut faciliter la lecture d'un code est pour moi toujours bon à prendre… De ce point de vue, je trouve les chainage beaucoup plus intéressant et facilitant : tu as en premier l'objet qui est traité, puis les fonctions appliquées, c'est une lecture somme toute assez claire…

$('#contenu li.spip')
   .addClass('liste')
   .removeClass('spip')
   .find('h1')
         .html("Liste d'éléments");

Plus il me semble en tout cas que :

html("Liste d'éléments",
     find('h1',
         removeClass('spip',
             addClass('liste',
                 $('#contenu li.spip')
             )
         )
     )
);

On peut toujours dire que c'est pour une question de performance qu'il est préférable d'écrire en «composition de fonctions» mais dans ce cas pourquoi ne pas écrire en C ou en Assembleur directement, plus performant encore ?