Sam & Max » cache http://sametmax.com Du code, du cul Sat, 07 Nov 2015 10:56:13 +0000 en-US hourly 1 http://wordpress.org/?v=4.1 Comment figer son app hors ligne pour plus d’un mois 9 http://sametmax.com/comment-figer-son-app-hors-ligne-pour-plus-dun-mois/ http://sametmax.com/comment-figer-son-app-hors-ligne-pour-plus-dun-mois/#comments Fri, 25 Apr 2014 09:35:29 +0000 http://sametmax.com/?p=10076 Je sers All That Counts avec nginx, et le fichier de config est super simple :

server {
        listen       80;
        server_name allthatcounts.net;

        error_log  /var/log/nginx/error_allthatcounts.log;
        access_log  /var/log/nginx/access_allthatcounts.log;

        location / {
            root /home/allthatcounts/www/;
            gzip  on;
            gzip_http_version 1.0;
            gzip_vary on;
            gzip_comp_level 6;
            gzip_proxied any;
            gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
            gzip_buffers 16 8k;
            gzip_disable ~@~\MSIE [1-6].(?!.*SV1)~@~];
            expires modified +90d;
        }
}

En gros c’est juste du log et servir les fichiers statiques compressés avec gzip. Il n’y a rien de plus à faire parce qu’il n’y a pas de backend. Simple. Efficace.

La couille c’est que c’est un copier / coller d’un autre projet que j’ai fais sans trop réfléchir, et quand j’ai mis en prod de nouvelles modifications sur le serveurs, mon Firefox me les affichait pas. Pourtant j’avais bien modifié le manifeste, donc il aurait du tout recharcher…

Sauf que, con de ma race, j’ai copié la ligne :

expires modified +90d;

Qui dit techniquement, met en cache tous les fichiers statiques pour 90 jours. Donc aussi le manifeste. Du coup, toutes les personnes qui ont visité le site ne verront aucune mise à jour pour un bon mois et demi.

Bravo Sam.

]]>
http://sametmax.com/comment-figer-son-app-hors-ligne-pour-plus-dun-mois/feed/ 9
Le manifeste du cache du mode hors ligne pour HTML5 10 http://sametmax.com/mode-le-manifeste-du-cache-du-mode-hors-ligne-pour-html5/ http://sametmax.com/mode-le-manifeste-du-cache-du-mode-hors-ligne-pour-html5/#comments Sun, 20 Apr 2014 12:17:08 +0000 http://sametmax.com/?p=10038 La bataille app native VS site responsive va faire rage pendant pas mal de temps, et pour le moment les apps gagnent : performances plus élevées, meilleures intégration visuelle dans l’OS, accès à une API plus riche… Les utilisateurs les préfèrent, et du coup les pros sont obligés de se les coltiner. C’est chiant, mais c’est la réalité du terrain pour les dev sur mobile.

Mais pour les sites Web ou les apps simples, il est super intéressant d’exploiter les capacités HTLM5 au max pour une obtenir une expérience plus “app” et moins “site web”.

Parmi ces possibilités : le mode hors ligne. D’un côté, il y a le stockage des données dans le navigateur, mais on vous en a déjà parlé.

De l’autre, il y a le cache des ressources. Cela consiste à déclarer quels fichiers (html, css, js, images, fonts, n’importe quoi…) garder en mémoire afin de les charger directement depuis le disque dur au lieu de le faire en ligne.

Pour cela, il faut déclarer un manifeste dans son HTML :

<html manifest="cache.manifest">

Ensuite, on créer le fichier cache.manifest dans son projet, qui est un fichier de texte simple.

Il faut le faire servir avec le mime-type

text/cache-manifest

sinon ça ne marche pas. Si vous le nommez

*.manifest

et que vous le servez avec un serveur de dev, ça marchera tout seul. Pour la prod, il faut le spécifier à votre serveur. Par exemple avec nginx, il faut éditer le fichier /etc/nginx/mime.types et y ajouter :

text/cache-manifest                   manifest;

Pour apache, c’est un truc du genre dans le .htaccess:

AddType text/cache-manifest .manifest

Ensuite, le manifeste ressemble à ça :

CACHE MANIFEST
# 2014-04-20 13:25:00

# Toutes les ressources à sauvegarder en local. Le navigateur
# va toujours chercher ces ressources sur le disque.
# Si on est déconnecté, la page index.html, ses styles et javascript
# s'afficheront donc quand même.
CACHE:
index.html
/favicon.ico
stylesheet.css
images/logo.png
scripts/main.js
fonts/font.woff

# Ressources à toujours charger depuis le réseau. On met ici
# une étoile pour dire "tout le reste". Si on ne fait pas ça,
# on va se retrouver sans css et js :)
NETWORK:
*

# Ressources alternatives si les précédentes sont inacessibles.
# Par exemple, pour afficher un point rouge si on est hors ligne
# et un point vert si on est en ligne :
# images/offline.png sera servi si images/online.png est inaccessible
FALLBACK:
images/online.png images/offline.png

Notez le commentaire # 2014-04-20 13:25:00 tout en haut. C’est
une convention qu’on utilise pour donner la dernière date de modification des
fichiers cachés. En effet, les fichiers de la section CACHE ne seront
pas rechargés tant que le manifeste n’a pas été modifié.

Cela veut dire que si vous modifiez index.html, l’utilisateur
ne verra pas la modification. Mais si vous changez la date du fichier manifeste,
le fichier est modifié, et le navigateur rechargera donc toutes les ressources
qu’il a mis en cache. Ainsi, vous permettez aux utilisateurs de voir les
ressources cachées qui ont été modifiées.

]]>
http://sametmax.com/mode-le-manifeste-du-cache-du-mode-hors-ligne-pour-html5/feed/ 10
Marre des mots de passe pour push sur git ? 13 http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/ http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/#comments Tue, 19 Nov 2013 08:36:34 +0000 http://sametmax.com/?p=8013 Vous êtes dans une situation où vous ne pouvez pas utiliser uniquement une clé pour vous authentifier, et il faut taper votre putain de mot de passe à chaque push.

Ça sent le vécu n’est-ce pas ?

Mais bien entendu git vient avec une option bien cachée au fond de son fion pour adresser ce problème :

git config credential.helper 'cache --timeout=3600'

Et votre authentification sera gardée en mémoire pour une heure. Vous pouvez faire :

git config --global credential.helper 'cache --timeout=3600'

Pour l’étendre à tous les repos de votre machine.

]]>
http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/feed/ 13
Question d’un lecteur sur le cache et Django 1 http://sametmax.com/question-dun-lecteur-sur-le-cache-et-django/ http://sametmax.com/question-dun-lecteur-sur-le-cache-et-django/#comments Sun, 04 Aug 2013 06:12:36 +0000 http://sametmax.com/?p=7003 Encore un message du formulaire de contact auquel je n’arrive pas à répondre (delivery failure).

> Subject: Idée d’article/Question
>
> Message Body:
> Salut !
>
> Merci pour vos articles décalés et ceux qui sont plus au centre.
>
> J’ai une petite question sur Django :
> Est-ce possible de mettre toutes les résultats de requetes de l’ORM de
Django dans memcached, et de les récupérer / mettre à jour / supprimer ?
> Pour moi ça bloque au niveau de la mise à jour / suppression.
>
> Du coup je me suis dit que vous pourriez faire un article sur les
différentes méthodes de mise en cache dans Django et ce que on peut
faire avec.

Hello,

Oui, c’est possible.

La mise à jour et la suppression du cache a toujours été une des choses
les plus difficiles en programmation, donc c’est naturel de bloquer dessus.

Pour commencer, utilise django-cache-machine ou johnny-cache, qui sont des
surcouche à l’ORM Django avec cache automatique. Ensuite, tu apprendras
à faire le reste à la main petit à petit.

Pour les pages complètes, des solutions qui n’ont rien à avoir avec
Django, telles que Varnish, sont aussi des approches qui permettent de
gagner pas mal en perfs.

Bref, je note ce truc dans la liste des articles à faire.

Sam

]]>
http://sametmax.com/question-dun-lecteur-sur-le-cache-et-django/feed/ 1
Savoir si une page est en cache avec Varnish 2 http://sametmax.com/savoir-si-une-page-est-en-cache-avec-varnish/ http://sametmax.com/savoir-si-une-page-est-en-cache-avec-varnish/#comments Wed, 01 May 2013 07:44:34 +0000 http://sametmax.com/?p=5945 Pour savoir si cette feignasse de Varnish a bien fait son boulot voici une petite astuce pour afficher dans les HEADERS de son navigateur la provenance de la page, le cache ou le backend.
Varnish propose dans son wiki cette méthode.


dans le fichier de conf de Varnish:

vi /etc/varnish/default.vcl

et rajoutez ces quelques lignes:

sub vcl_deliver {
        if (obj.hits > 0) {
                set resp.http.X-Cache = "HIT";
        } else {
                set resp.http.X-Cache = "MISS";
        }
}

On redemarre le service pour prendre en compte les changements:

service varnishd restart

Dans le navigateur:

Comme on le voit ici, la page a été servie par le backend, si ce n’était pas prévu il va falloir revoir vos règles.

ATTENTION: Pensez à bien rafraichir votre navigateur pour être sur que ce ne soit pas la page mise en cache par ce dernier qui soit affichée, personnellement j’utilise la version navigation privé de chrome.

]]>
http://sametmax.com/savoir-si-une-page-est-en-cache-avec-varnish/feed/ 2
Changement du cache du blog 14 http://sametmax.com/changement-du-cache-du-blog/ http://sametmax.com/changement-du-cache-du-blog/#comments Mon, 08 Apr 2013 13:06:22 +0000 http://sametmax.com/?p=5641 ce plugin Wordpress (ou alors quelqu'un me l'a recommandé, je sais plus) et j'ai trouvé la motivation pour l'installé ce matin.]]> Vu qu’on est des feignasses et qu’on a pas envie de tweaker le blog jusqu’à ce que performances s’en suivent, on a fait les bourrins en mettant un gros varnish en front.

On a reçu de nombreuses remarques comme quoi on ne voyait pas si les commentaires étaient postés et autres détails qui rendaient la consultation du blog fort confuse.

On n’est pas devenu moins fainéant entre temps, mais il se trouve que je suis tombé par hasard sur ce plugin WordPress (ou alors quelqu’un me l’a recommandé, je sais plus) et j’ai trouvé la motivation pour l’installer ce matin.

Normalement il devrait invalider le cache à chaque fois qu’on met à jour un article ou que quelqu’un poste un commentaire.

À voir si ça plombe pas les perfs mais normalement ça devrait aller, on a eu à peine 4,758 comments depuis le lancement du blog, ça fait moins d’un comment à l’heure, on devrait survivre.

Si vous constatez que c’est mieux, faites le nous savoir, on aura au moins l’impression d’avoir fait notre BA.

]]>
http://sametmax.com/changement-du-cache-du-blog/feed/ 14
Firefox n’affiche plus les styles CSS ni les images 6 http://sametmax.com/firefox-naffiche-plus-les-styles-css-ni-les-images/ http://sametmax.com/firefox-naffiche-plus-les-styles-css-ni-les-images/#comments Fri, 04 Jan 2013 12:15:30 +0000 http://sametmax.com/?p=3956 Après avoir vidé le cache, il peut arriver que notre panda roux n’affiche plus les styles CSS ou les images: il n’y a plus aucune mise en page, juste du texte noir sur une page blanche. Damned !

La solution est de forcer le refresh de la page et du cache avec Ctrl + Shift + R.

]]>
http://sametmax.com/firefox-naffiche-plus-les-styles-css-ni-les-images/feed/ 6
Effacer le cache DNS sous Mac Os http://sametmax.com/effacer-le-cache-dns-sous-mac-os/ http://sametmax.com/effacer-le-cache-dns-sous-mac-os/#comments Thu, 22 Nov 2012 21:17:30 +0000 http://sametmax.com/?p=3257 Si vous avez encore l’ancienne IP lorsque vous faites un ping sur un site c’est que votre cache DNS l’a mémorisée. Il faut parfois le réinitialiser (si vous changez votre site de serveur ou que vous ne pouvez plus accéder à un site en particulier).

Ouvrez un Terminal:
Dans Applications > Utilitaires > Terminal

et tapez:

lookupd -flushcache

Si ça ne marche pas essayez (pour les Mac plus récents):

dscacheutil -flushcache

Rappel:
la commande ping est toujours utile, c’est un outil qui sert à tester la conneciton entre 2 IPs.

ping yahoo.com
PING yahoo.com (72.30.38.140): 56 data bytes
64 bytes from 72.30.38.140: icmp_seq=0 ttl=42 time=275.592 ms
64 bytes from 72.30.38.140: icmp_seq=1 ttl=42 time=212.991 ms
64 bytes from 72.30.38.140: icmp_seq=2 ttl=42 time=255.605 ms
]]>
http://sametmax.com/effacer-le-cache-dns-sous-mac-os/feed/ 0
Django cache illimité sur filesystem – Overrider FileBasedCache 2 http://sametmax.com/django-cache-illimite-sur-filesystem-overrider-filebasedcache/ http://sametmax.com/django-cache-illimite-sur-filesystem-overrider-filebasedcache/#comments Sat, 13 Oct 2012 14:00:01 +0000 http://sametmax.com/?p=2569 Django propose plusieurs façons de mettre de son site en cache.
Un de nos site gourmant en pages commencait à saturer le cache en mémoire alors il a fallut le basculer sur le filesystem, oui mais Django et son backend filesystem par défaut autorise 300 entrées dans le cache, ensuite il va effacer les anciennes pour les remplacer par les nouvelles, etc…

On peut régler le nombre d’entrées avec l’option MAX_ENTRIES dans les settings mais que fait django derrière ?
Il va scanner votre répertoire de cache et compter tous les fichiers ! Niveau performance on a vu mieux !

Voici un petit patch qui consiste à bypasser le comptage des fichiers dans le cas où l’ont veut un cache “infini”, ce qui soulève un autre problème, ça va cacher jusqu’à qu’il n’y ait plus de pages à cacher ou que le disque sature :)

dans un fichier cache.py que vous mettez où vous voulez (moi dans libs par ex):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
    Override FileBasedCache to extend entries cache count.
    avoid scanning all cache dir to count entries.
 
"""
import os
from django.core.cache.backends.filebased import FileBasedCache
 
class CustomFileBasedCache(FileBasedCache):
 
    def _get_num_entries(self):
       count = 0
       if self._max_entries == 9999: return 0
       for _,_,files in os.walk(self._dir):
           count += len(files)
       return count
    _num_entries = property(_get_num_entries)

dans les settings rajoutez à votre backend filesystem le backend customisé “libs.cache.CustomFileBasedCache” et l’option MAX_ENTRIES à -1:

CACHE_DEFAULT_SECONDS = 3600
CACHES = {
   'default': {
       'BACKEND': 'redis_cache.RedisCache',
       'LOCATION': 'localhost:6379',
       'TIMEOUT': CACHE_DEFAULT_SECONDS,
   },
   'filesystem': {
       'BACKEND': 'libs.cache.CustomFileBasedCache',
       'LOCATION': '/var/tmp/django',
       'TIMEOUT': CACHE_DEFAULT_SECONDS,
       'OPTIONS': {
            'MAX_ENTRIES': 9999 # Set 9999 for unlimited cache
       }
   }
}

On évite du coup le os.walk de la méthode _get_num_entries qui dans le cas d’un grand nombre de fichiers en cache pourrait faire du mal à votre serveur.

A utiliser avec précaution car ça cache, ça cache, ça cache… :)

]]>
http://sametmax.com/django-cache-illimite-sur-filesystem-overrider-filebasedcache/feed/ 2
Optimiser Mysql en mettant en cache les requetes SELECT avec query_cache_size + benchmark 6 http://sametmax.com/optimiser-mysql-en-utilisant-le-cache-query_cache_size/ http://sametmax.com/optimiser-mysql-en-utilisant-le-cache-query_cache_size/#comments Tue, 28 Aug 2012 23:25:24 +0000 http://sametmax.com/?p=1912 Voici une petite astuce pour mettre en cache les requetes mysql. Pour donner une idée du gain j’ai fait un petit script de benchmark, le gain à la lecture est plutôt convaincant. Je ne suis pas benchmarkeur de profession alors si il y en a dans la salle qui pensent que ce test n’est pas réaliste merci d’apporter votre contribution ;)

Editer le fichier my.cnf pour activer le cache des requetes:

query_cache_type = 1
query_cache_size = 256M

query_cache_type est le type de cache que l’on va adopter:
0 = pas de cache
1 = met en cache toutes les requetes sauf celles qui ont le flag “SELECT S_NO_CACHE”
2 = met en cache seulement les requetes qui comportent le flag “SELECT SQL_CACHE”

Ci dessous le script pour tester les perfs:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import MySQLdb as mdb
import sys
 
from timeit import Timer 
 
def benchmark(cur):
    """
        execute query
    """
    cur.execute("SELECT * FROM Writers")
    rows = cur.fetchall()
    #     for row in rows:
    #         print row
 
def create_fixtures():
    """
        Create dummy datas for test
    """
 
    with con:
        cur = con.cursor()
        cur.execute("DROP TABLE IF EXISTS Writers")
        cur.execute("CREATE TABLE IF NOT EXISTS Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))")
        cur.execute("INSERT INTO Writers(Name) VALUES('Jack London')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Honore de Balzac')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Lion Feuchtwanger')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Emile Zola')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Adolf Hitler')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Ronald McDonalds')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Mamie Nova')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Sam &amp; Max')")
 
def set_query_cache(query_cache_type=1):
    """
        Set query cache
        0 : Don't cache results in or retrieve results from the query cache.
        1 : Cache all query results except for those that begin with SELECT S_NO_CACHE.
        2 : Cache results only for queries that begin with SELECT SQL_CACHE
    """
 
    with con:
        cur = con.cursor()
        cur.execute("SET GLOBAL query_cache_size = 16777216")
        cur.execute("SET SESSION query_cache_type = %s" % str(query_cache_type)) 
 
def start_benchmark(nb_queries=1000, cached_queries=1):
    """
 
    """
    # use cached query benchmark
    print "Starting benchmark: %s reads - query cache type = %s" % (nb_queries, cached_queries)
 
    # set query cache
    set_query_cache(cached_queries)
 
    # run the test
    t = Timer("queries()", "from __main__ import queries")
    print t.timeit(number=nb_queries) 
 
if __name__ == '__main__':
 
    # connect to db
    con = mdb.connect('localhost', 'root', '12345', 'test');
 
    # create dummy datas
    create_fixtures()
 
    with con:
        cur = con.cursor()
        queries = lambda: benchmark(cur=cur)
 
    # launch benchmark
    start_benchmark(nb_queries=10000, cached_queries=1)
    start_benchmark(nb_queries=10000, cached_queries=0)
 
    con.close()

Ce qui me donne…

python mysql_tests.py
Starting benchmark: 10000 reads - query cache type = 1
1.47591710091
Starting benchmark: 10000 reads - query cache type = 0
1.96538686752

Conclusion:
Il semblerait qu’en effet le gain dû au cache est plutôt pas mal, en plus c’est juste 2 params à mettre dans son fichier de config.

Faites part de vos retours, ça peut toujours servir ;)

]]>
http://sametmax.com/optimiser-mysql-en-utilisant-le-cache-query_cache_size/feed/ 6