Carnet d'un développeur

les pérégrinations d'un developpeur sur le Web

Comme on ne trouve pas souvent d’informations sur ce logiciel dédié à la gestion de campagne de mailing, je me suis dit que j’allais partager quelques trucs et astuces au gré du vent (quand je trouve qu’il y a une pertinence dans le partage de l’information).

L’info du jour concerne la création de schémas :

neolane001

Pour une raison ou pour une autre, vous créez un nouveau schéma et au moment de sauvegarder, vous avez une erreur.

Pourtant, vous avez beau regarder, votre schéma est syntaxiquement correct, voir même c’était un schéma parfaitement valide et vous n’avez fait que rajouter un espace dedans.

Ne cherchez plus dans le schéma lui même … Il faut savoir que quand vous cliquez sur « save », neolane ne se contente pas de valider que votre schéma. Il revalide tous les schémas. Il est donc fort probable que l’erreur soit liée à un autre schéma. Cherchez donc dans votre mémoire si vous n’avez pas touché innocemment à d’autres schémas :).

janvier 31st, 2015

Posted In: Neolane / Adobe campaign

Leave a Comment

Voilà un petit billet rapide sur une histoire rigolote concernant eZ le cluster et APC et un problème d’expiration de cache.

Pour resituer le contexte :
Site international, eZPublish 4.6 en PHP 5.3 avec module APC. Niveau infra, 4 frontaux apache, 1 worker, 1 varnish, 1 NFS, 2 DB (une pour le cluster).

Maintenant voilà le problème :
Il arrive que pour une raison ou eu autre, parfois il y a besoin d’expirer le content view cache. Pour se faire, il suffit de lancer la commande adéquate, ou de cliquer dans l’interface d’admin sur la bonne option.
Cette commande va tout simplement écrire dans le fichier expiry.php une clef « content-view-cache » contenant un timestamp. Quand eZ va venir lire le cache il regarde cette valeur et considère comme expiré tout ce qui se situe avant.
Dans le cas du mode cluster, le fichier expiry.php est partagé via NFS et dupliqué sur chaque frontal (la DB faisant référence).
Dans mon cas, le « bug » amusant qui se produisait c’est que en cas d’invalidation du cache, le fichier expiry.php était modifié, puis 2 heures plus tard … magie, le fichier expiry.php n’avait plus la clef concernant le content-view-cache.

Mais que s’est il passé ?
Après avoir regardé le code de plus près, j’en suis arrivé à la conclusion que rien dans le code ne pouvait produire cet effet (disparition de la clef).
J’ai donc supposé que c’était un problème infra. Comme j’ai de l’expérience, j’ai tout de suite soupçonné APC et un problème de conf et effectivement je ne me suis pas trompé.
Tous les frontaux avaient une conf APC simple comme ça :

; APC
extension="apc.so"
apc.enabled=1
apc.shm_segments=1
apc.optimization=0
apc.shm_size=64M
apc.ttl=7200
apc.user_ttl=7200
apc.filters = "-cache.*\.php"

Et le worker :

; APC
extension="apc.so"
apc.enabled=1
apc.shm_segments=1
apc.optimization=0
apc.shm_size=128M
apc.ttl=7200
apc.user_ttl=7200

Il manque :
apc.filters = « -cache.*\.php »

Et là, c’est le drame :)
Effectivement si on regarde comment est géré le expiryHandler de eZ, on s’aperçoit que pour charger le fichier on fait un include. Par conséquent, on utilise APC. Comme ce fichier n’est pas exclu par la conf, on le garde 2 h en mémoire. Par contre quand on écrit, on écrase bien le fichier avec une version périmée (celle de la mémoire).
Comme quoi, il faut toujours se méfier du setup infra et ne pas oublier que les accélérateurs de code doivent être bien configuré pour être efficace (exclure les caches la plupart du temps).

janvier 30th, 2015

Posted In: Developpement Web, eZPublish

Leave a Comment

Alors aujourd’hui pour continuer un peu la série migration, voilà une nouvelle problématique : le mode cluster et index_cluster.php pour la distribution des images.

Pour l’historique, en eZpublish 4.6, j’utilise le mode cluster fichiers. C’est à dire une base de données pour stocker les « metadatas » (en fait c’est pour gérer les dates et les expirations, pas des metadatas comme pour les images) et un système de fichier nfs pour partager les fichiers entre plusieurs frontaux.
Dans l’ancien système, c’est plutôt simple : index_cluster.php interroge la base de données pour récupérer des infos comme la date de dernière modif et crache l’image avec un header qui va bien.
L’idée c’est que lire des infos comme la date de dernière modif sur un système de fichier comme nfs ça n’a pas toujours été très fiable. Du coup on découple le fichier physique et les infos liées à ce même fichier en les stockant dans une base de données.

Avec eZpublish 5.4, il y a une évolution par rapport à la 5.3. Dans le fichier de conf apache recommandé (voir \doc\apache2\vhost.Template à la racine de votre install d’eZ), on a :

# If using cluster, uncomment the following two lines:
## For 5.4 and higher:
#RewriteRule ^/var/([^/]+/)?storage/images(-versioned)?/.* /index.php [L]
#RewriteRule ^/var/([^/]+/)?cache/(texttoimage|public)/.* /index_cluster.php [L]
## Versions prior to 5.4:
#RewriteRule ^/var/([^/]+/)?storage/images(-versioned)?/.* /index_cluster.php [L]
#RewriteRule ^/var/([^/]+/)?cache/(texttoimage|public)/.* /index_cluster.php [L]

Donc bien sur, dans mon cas j’ai décommenté les premières lignes. La différence c’est qu’en 5.4, on utilise le stack symfony. Et comme l’idée dans le futur c’est quand même bien de dire au revoir à ez legacy, je me suis empressé de tester ça.

Et là … je dois dire que j’en ai chié … Moi je croyais que c’était magique que ça allait marcher sans rien faire de plus :).
Donc d’abord, on commence par une magnifique exception symfony :

Error: Call to a member function getTimestamp() on a non-object in /var/www/vendor/ezsystems/ezpublish-kernel/eZ/Bundle/EzPublishIOBundle/BinaryStreamResponse.php line 107
500 Internal Server Error - FatalErrorException

Bon forcément, d’un coté (legacy) on a un chemin nfs, de l’autre on lui a rien dit … Forcément, ça doit coincer au niveau de l’emplacement du fichier :). A ce moment commence la recherche du paramétrage à modifier pour changer le chemin des fichiers.

Après quelques recherches, on finit par tomber sur la doc eZ : https://github.com/ezsystems/ezpublish-kernel/blob/master/doc/specifications/io/legacy_dfs_cluster.md

Malheureusement, en recopiant les infos de cette doc, ça ne marche pas (je signale qu’on trouve aussi des versions différentes de la doc qui ne marchent pas mieux).

Première erreur :

ServiceNotFoundException: The service "ezpublish.core.io.metadata_handler.legacy_dfs_cluster.dfs" has a dependency on a non-existent service "ezdfs_connection".

Cette erreur est causée par le fait que legacy_dfs_cluster.dfs veut un service et on lui fournit un scalar. Après m’être posé des questions existensielles sur si ma connexion dbal était bien paramétrée ou pas, j’ai fini par arriver à la doc de symfony, qui dit :

Each connection is also accessible via the doctrine.dbal.[name]_connection service where [name] is the name of the connection.

Donc, pour résumer, il faut donc remplacer :

ez_io:
    binarydata_handlers:
        nfs:
            local:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: ezdfs

par

ez_io:
    binarydata_handlers:
        nfs:
            local:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: doctrine.dbal.ezdfs_connection

Premier problème résolu.

Après (ou avant) on a une erreur simple …

ez_io:
    binarydata_handlers:
        nfs:
            local:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: ezdfs

oneup_flysystem:
    adapters:
        nfs:
            local:
                # The last part, $var_dir$/$storage_dir$, is required for legacy compatibility
                directory: "/path/to/nfs/$var_dir$/$storage_dir$"

ça ne marche pas car il faut écrire :

oneup_flysystem:
    adapters:
        nfs_adapter:
            local:
                # The last part, $var_dir$/$storage_dir$, is required for legacy compatibility
                directory: "/path/to/nfs/$var_dir$/$storage_dir$"

C’est un peu l’inverse du problème précédent.

Maintenant, on tape bien dans la base définie pour le cluster, y a plus d’erreur d’adapter indéfini, mais par contre on revient à l’erreur originelle.
Après avoir testé :

ezpublish:
    system:
        default:
            io:
                metadata_handler: dfs
                binarydata_handler: dtc

Et n’avoir pas reçu la moindre erreur (je n’ai bien sur pas défini « dtc »), j’en ai déduit que le binarydata_handler, ben il s’en contrefichait pas mal. Je n’ai pas creusé plus, je suppose que tout n’est peut être pas encore complètement implémenté sur l’aspect « définir des espace de stockage via drivers par siteaccess », surtout que dans l’immédiat, c’est bien beau mais l’admin est loin de supporter tous les systèmes de fichiers proposés.

Quoiqu’il en soit, j’ai trouvé un moyen de faire fonctionner la chose, il suffit tout simplement de redéfinir ez_io.binarydata_handlers.default :

ez_io:
    binarydata_handlers:
        default:
            flysystem:
                adapter: nfs_adapter
    metadata_handlers:
        dfs:
            legacy_dfs_cluster:
                connection: doctrine.dbal.ezdfs_connection

Et là, c’est miraculeux, j’ai mes images de mon partage nfs qui s’affichent !!!
J’espère que ces quelques infos permettront à quelqu’un de ne pas perdre des heures comme moi à lire des tonnes de docs contradictoires.

 

janvier 24th, 2015

Posted In: Developpement Web

Leave a Comment

Page suivante »