Kresus: version 0.8.0

Posted on Fri 05 August 2016 in blog • Tagged with kresus, cozycloud

Je viens de publier une nouvelle version de Kresus, le gestionnaire de finances personnelles open-source sur lequel je travaille. Pour rappel, cette application, basée sur Weboob, est disponible dans CozyCloud et vous permet de vous connecter à votre compte bancaire, récupérer vos opérations et les classifier pour savoir où votre argent passe.

Action requise pour les auto-hébergés : installation de Weboob

Avant de passer à la liste détaillée des changements, il y a une procédure de migration qui nécessitera une action de votre part, si vous êtes auto-hébergés (c'est-à-dire si vous n'utilisez pas d'instance bêta sur l'infrastructure de CozyCloud). Si vous êtes utilisateur de l'infrastructure de CozyCloud, le changement devrait avoir été effectué par l'équipe des administrateurs systèmes de Cozy, et vous pouvez passer à la partie suivante.

Si vous êtes auto-hébergés, il vous faudra installer Weboob par vos propres moyens et vous assurer que l'utilisateur qui lance le processus de Kresus ait accès à Weboob. J'ai personnellement effectué une installation globale. Je recommande d'installer la version 1.1 ou supérieure de Weboob, pour être certain que les modules des sites ne soient pas dépassés.

Si vous utilisez l'application cozy_management, il existe maintenant une commande permettant d'effectuer l'installation globale de Weboob telle qu'elle est nécessaire pour que Kresus fonctionne sur votre machine :

cozy_management install_weboob

Un grand merci à nicofrand pour cette fonctionnalité !

Auparavant, Weboob, le système qui se connecte à votre banque pour récupérer la liste des comptes et opérations, était installé par Kresus et cela nécessitait des dépendences externes. Il a été décidé que Weboob devait désormais être installé au préalable par l'administrateur système : Kresus n'essaiera plus de l'installer. Cela simplifie beaucoup de choses, notamment en facilitant la gestion des dépendences nécessaires lors de l'installation.

La version courte

Pour cette version, beaucoup de changements peu visibles pour l'utilisateur : c'est beaucoup de nettoyage et de changements structurels dans le code (séparation du code client en composants logiques et lint complet), qui devraient faciliter la maintenance et l'amélioration du code par le futur. Aussi, beaucoup de problèmes relatifs à la détection des doublons et à la synchronisation automatique des comptes ont été réglés.

Un changement visible et notable : la liste des opérations est désormais beaucoup plus fluide lors du scroll, même si vous avez des tonnes d'opérations.

En cas de problèmes de balances

Si vous rencontrez des problèmes de synchronisation entre Kresus et votre banque, par exemple si Kresus affiche des soldes de comptes qui ne correspondent pas aux montants indiqués sur le site de votre banque, il est conseillé de vérifier les doublons dans la section correspondante et d'essayer de les fusionner à la main.

Si malgré la détection de doublons, vous avez encore des problèmes de montant, laissez un message sur le fil associé du forum de Cozy ! J'aimerais expérimenter des méthodes plus agressives de détection automatique de doublons, et cela nécessite de savoir quelles sont les situations qui posent fréquemment problème.

Les contributions en détail

Un grand merci aux 7 contributeurs de cette nouvelle version, pour un total de 108 commits !

  • @AwYiss, qui avait déjà grandement amélioré l'interface utilisateur, a frappé de nouveau, en intégrant les préférences au niveau design, rendant cette partie plus consistente avec le reste de l'application et très élégante.
  • @nicofrand a corrigé des soucis de style (CSS) lors de l'ajout manuel d'opération.
  • Bezleputh (de la communauté Weboob) a corrigé un bogue qui empêchait l'import d'opérations, si celles-ci présentaient des informations manquantes.
  • @brouberol a ajouté un Dockerfile (ou RecetteÀMarcel pour les puristes de l'OS souverain) afin de pouvoir tester Kresus rapidement en production. J'espère pouvoir écrire un peu plus sur le sujet bientôt.
  • @PandiPanda69 a effectué une revue du code avec la sécurité à l'esprit :
    • Correction de bogue : lors de l'import d'une instance, si le fichier JSON contient des erreurs de syntaxe, ne pas essayer de l'importer.
    • Ajout de la possibilité de chiffrer l'export de son instance Kresus et d'importer une instance chiffrée de Kresus. Avec cette nouvelle méthode d'import, le mot de passe peut être inclus dans le fichier exporté, en toute sécurité ! (cette fonctionnalité n'est pas encore activée car elle nécessite une réflexion et des tests approfondis ainsi qu'une implémentation côté interface)
  • @ZeHiro:
    • Amélioration de la visualisation de la liste des opérations sur interface mobile (en lecture seule pour le moment).
    • Amélioration sensible des traductions : les notifications et textes des emails sont désormais traduits en français ou en anglais, selon la langue choisie dans votre Cozy !
    • Utilisation de la vraie monnaie du compte, avec le symbole monétaire associé, dans toute l'interface utilisateur.
    • Amélioration de la détection manuelle des doublons (deux opérations sont considérées comme des doublons seulement si leurs types sont identiques).
    • Suppression de faux positifs dans la détection automatique des doublons (deux opérations avec la même date, le même montant et le même libellé).
    • Si votre mot de passe expire, Kresus vous enverra désormais un mail une et une seule fois pour vous le signaler, et n'importera plus d'opérations automatiquement jusqu'à la mise à jour du mot de passe (le même comportement est prévu si le mot de passe devient erroné, s'il n'est pas mis à jour dans Kresus).
    • Ajout de la possibilité de supprimer une opération manuellement. N'utilisez cette fonctionnalité qu'en dernier recours et seulement si la détection de doublons n'a pas marché !
    • Fix spécifique à un problème spécifique de plateforme sous raspberry pi.
  • De manière notable, ZeHiro et moi-même avons contribué ensemble à des fonctionnalités majeures :
    • Grâce à une implémentation de l'infinite scrolling dans la liste des opérations, celle-ci est bien plus fluide à s'afficher, même si vous avez beaucoup d'opérations !
    • Découpage du code en modules logiques et refactoring pour que le code client passe le lint (validation statique du style du code). Ce n'est pas visible pour l'utilisateur, mais ça aide grandement les développeurs en leur évitant de se poser plein de questions futiles sur le style du code.
  • votre serviteur:
    • utilisation de Weboob au niveau global (voir paragraphe sur la procédure de migration).
    • meilleure représentation des erreurs. Normalement, les erreurs devraient être plus claires à comprendre, côté client comme ou dans les logs côté serveur, grâce à une meilleure cohérence et à des logs plus détaillés et facultatifs. Un mode de debugging pour Weboob a été également rajouté, ce qui est très utile en cas de problèmes de synchronisation avec votre banque, pour remonter des logs aux développeurs de Weboob !
    • la récupération automatique des opérations ne s'arrête plus en cas d'échec. Si les opérations n'étaient plus récupérées automatiquement toutes les nuits chez vous, c'était peut-être à cause de ce bug.
    • les graphiques des opérations en valeurs négatives pointent désormais vers le haut et non plus vers le bas.

Le mot de la fin

La prochaine version est déjà presque prête et comprend une réécriture presque complète du client avec une autre technologie (redux). Après cette réécriture, on devrait plus facilement pouvoir ajouter de nouveau des grosses fonctionnalités !

Comme d'habitude, si vous avez des remarques ou suggestions, n'hésitez-pas à me le faire savoir, par twitter, sur diaspora ou sur le forum de cozy !


Making asm.js/WebAssembly compilation more parallel in Firefox

Posted on Fri 22 April 2016 in blog • Tagged with opensource, mozilla

In December 2015, I've worked on reducing startup time of asm.js programs in Firefox by making compilation more parallel. As our JavaScript engine, Spidermonkey, uses the same compilation pipeline for both asm.js and WebAssembly, this also benefitted WebAssembly compilation. Now is a good time to talk about what it meant, how it got achieved and what are the next ideas to make it even faster.

What does it mean to make a program "more parallel"?

Parallelization consists of splitting a sequential program into smaller independent tasks, then having them run on different CPU. If your program is using N cores, it can be up to N times faster.

Well, in theory. Let's say you're in a car, driving on a 100 Km long road. You've already driven the first 50 Km in one hour. Let's say your car can have unlimited speed from now on. What is the maximal average speed you can reach, once you get to the end of the road?

People intuitively answer "If it can go as fast as I want, so nearby lightspeed sounds plausible". But this is not true! In fact, if you could teleport from your current position to the end of the road, you'd have traveled 100 Km in one hour, so your maximal theoritical speed is 100 Km per hour. This result is a consequence of Amdahl's law. When we get back to our initial problem, this means you can expect a N times speedup if you're running your program with N cores if, and only if your program can be entirely run in parallel. This is usually not the case, and that is why most wording refers to speedups up to N times faster, when it comes to parallelization.

Now, say your program is already running some portions in parallel. To make it faster, one can identify some parts of the program that are sequential, and make them independent so that you can run them in parallel. With respect to our car metaphor, this means augmenting the portion of the road on which you can run at unlimited speed.

This is exactly what we have done with parallel compilation of asm.js programs under Firefox.

A quick look at the asm.js compilation pipeline

I recommend to read this blog post. It clearly explains the differences between JIT (Just In Time) and AOT (Ahead Of Time) compilation, and elaborates on the different parts of the engines involved in the compilation pipeline.

As a TL;DR, keep in mind that asm.js is a strictly validated, highly optimizable, typed subset of JavaScript. Once validated, it guarantees high performance and stability (no garbage collector involved!). That is ensured by mapping every single JavaScript instruction of this subset to a few CPU instructions, if not only a single instruction. This means an asm.js program needs to get compiled to machine code, that is, translated from JavaScript to the language your CPU directly manipulates (like what GCC would do for a C++ program). If you haven't heard, the results are impressive and you can run video games directly in your browser, without needing to install anything. No plugins. Nothing more than your usual, everyday browser.

Because asm.js programs can be gigantic in size (in number of functions as well as in number of lines of code), the first compilation of the entire program is going to take some time. Afterwards, Firefox uses a caching mechanism that prevents the need for recompilation and almost instaneously loads the code, so subsequent loadings matter less*. The end user will mostly wait for the first compilation, thus this one needs to be fast.

Before the work explained below, the pipeline for compiling a single function (out of an asm.js module) would look like this:

  • parse the function, and as we parse, emit intermediate representation (IR) nodes for the compiler infrastructure. SpiderMonkey has several IRs, including the MIR (middle-level IR, mostly loaded with semantic) and the LIR (low-level IR closer to the CPU memory representation: registers, stack, etc.). The one generated here is the MIR. All of this happens on the main thread.
  • once the entire IR graph is generated for the function, optimize the MIR graph (i.e. apply a few optimization passes). Then, generate the LIR graph before carrying out register allocation (probably the most costly task of the pipeline). This can be done on supplementary helper threads, as the MIR optimization and LIR generation for a given function doesn't depend on other ones.
  • since functions can call between themselves within an asm.js module, they need references to each other. In assembly, a reference is merely an offset to somewhere else in memory. In this initial implementation, code generation is carried out on the main thread, at the cost of speed but for the sake of simplicity.

So far, only the MIR optimization passes, register allocation and LIR generation were done in parallel. Wouldn't it be nice to be able to do more?

* There are conditions for benefitting from the caching mechanism. In particular, the script should be loaded asynchronously and it should be of a consequent size.

Doing more in parallel

Our goal is to make more work in parallel: so can we take out MIR generation from the main thread? And we can take out code generation as well?

The answer happens to be yes to both questions.

For the former, instead of emitting a MIR graph as we parse the function's body, we emit a small, compact, pre-order representation of the function's body. In short, a new IR. As work was starting on WebAssembly (wasm) at this time, and since asm.js semantics and wasm semantics mostly match, the IR could just be the wasm encoding, consisting of the wasm opcodes plus a few specific asm.js ones*. Then, wasm is translated to MIR in another thread.

Now, instead of parsing and generating MIR in a single pass, we would now parse and generate wasm IR in one pass, and generate the MIR out of the wasm IR in another pass. The wasm IR is very compact and much cheaper to generate than a full MIR graph, because generating a MIR graph needs some algorithmic work, including the creation of Phi nodes (join values after any form of branching). As a result, it is expected that compilation time won't suffer. This was a large refactoring: taking every single asm.js instructions, and encoding them in a compact way and later decode these into the equivalent MIR nodes.

For the second part, could we generate code on other threads? One structure in the code base, the MacroAssembler, is used to generate all the code and it contains all necessary metadata about offsets. By adding more metadata there to abstract internal calls **, we can describe the new scheme in terms of a classic functional map/reduce:

  • the wasm IR is sent to a thread, which will return a MacroAssembler. That is a map operation, transforming an array of wasm IR into an array of MacroAssemblers.
  • When a thread is done compiling, we merge its MacroAssembler into one big MacroAssembler. Most of the merge consists in taking all the offset metadata in the thread MacroAssembler, fixing up all the offsets, and concatenate the two generated code buffers. This is equivalent to a reduce operation, merging each MacroAssembler within the module's one.

At the end of the compilation of the entire module, there is still some light work to be done: offsets of internal calls need to be translated to their actual locations. All this work has been done in this bugzilla bug.

* In fact, at the time when this was being done, we used a different superset of wasm. Since then, work has been done so that our asm.js frontend is really just another wasm emitter.

** referencing functions by their appearance order index in the module, rather than an offset to the actual start of the function. This order is indeed stable, from a function to the other.

Results

Benchmarking has been done on a Linux x64 machine with 8 cores clocked at 4.2 Ghz.

First, compilation times of a few asm.js massive games:

The X scale is the compilation time in seconds, so lower is better. Each value point is the best one of three runs. For the new scheme, the corresponding relative speedup (in percentage) has been added:

Compilation times of various
benchmarks

For all games, compilation is much faster with the new parallelization scheme.

Now, let's go a bit deeper. The Linux CLI tool perf has a stat command that gives you an average of the number of utilized CPUs during the program execution. This is a great measure of threading efficiency: the more a CPU is utilized, the more it is not idle, waiting for other results to come, and thus useful. For a constant task execution time, the more utilized CPUs, the more likely the program will execute quickly.

The X scale is the number of utilized CPUs, according to the perf stat command, so higher is better. Again, each value point is the best one of three runs.

CPU utilized on DeadTrigger2

With the older scheme, the number of utilized CPUs quickly rises up from 1 to 4 cores, then more slowly from 5 cores and beyond. Intuitively, this means that with 8 cores, we almost reached the theoritical limit of the portion of the program that can be made parallel (not considering the overhead introduced by parallelization or altering the scheme).

But with the newer scheme, we get much more CPU usage even after 6 cores! Then it slows down a bit, although it is still more significant than the slow rise of the older scheme. So it is likely that with even more threads, we could have even better speedups than the one mentioned beforehand. In fact, we have moved the theoritical limit mentioned above a bit further: we have expanded the portion of the program that can be made parallel. Or to keep on using the initial car/road metaphor, we've shortened the constant speed portion of the road to the benefit of the unlimited speed portion of the road, resulting in a shorter trip overall.

Future steps

Despite these improvements, compilation time can still be a pain, especially on mobile. This is mostly due to the fact that we're running a whole multi-million line codebase through the backend of a compiler to generate optimized code. Following this work, the next bottleneck during the compilation process is parsing, which matters for asm.js in particular, which source is plain text. Decoding WebAssembly is an order of magnitude faster though, and it can be made even faster. Moreover, we have even more load-time optimizations coming down the pipeline!

In the meanwhile, we keep on improving the WebAssembly backend. Keep track of our progress on bug 1188259!


Previous writings about Mozilla work

Posted on Wed 09 March 2016 in blog • Tagged with opensource, mozilla

I am currently a compiler engineer at Mozilla corporation, the company making the Firefox browser among else. Our JavaScript virtual machine, Spidermonkey, is split in several tiers, including an highly optimizing Just-In-Time (JIT) compiler able to compile JavaScript to assembly at runtime. My previous work has involved efficiently compiling Float32 arithmetic to hardware instructions and implement a new SIMD API for the Web.

About Float32 optimizations

The full blog post is there. It has been written in November 2013.

The main idea is that if you have float32 inputs to an operation; and you cast them to doubles; and you apply an arithmetic operation to these inputs; and you cast the result back to a float32, then you'd have the same result as if you did the entire computation with float32 values and operations.

So we've introduced an operation in JavaScript that converts a Number to its closest float32 IEEE754 representation: Math.fround. Said differently, the above equivalence says that:

function f(x, y) {
    return x + y;
}

function g(x, y) {
    var xf = Math.fround(x);
    var yf = Math.fround(y);
    return Math.fround(xf + yf);
}

// For all x, y that can be represented exactly as float32:
assert(f(x, y) === g(x, y));

Yes, ===. The same === you've been told not to use for floating-point Numbers. But here, we have bitwise equality, so we can use strict equality*.

Processors have special instructions for carrying out float32 arithmetic, which have higher throughput than the equivalent double ones. With this result in mind, we could add a pass that would spot opportunities where the computations are equivalent (thanks to Math.fround hints) and emit float32 instructions instead of double instructions. This sped up a some numerical applications and games engines by a few points.

* a careful reader would object that this is wrong for x = y = NaN, which I've put away for the sake of simplicity.

About SIMD.js

The full blog post is there. It has been written in March 2015.

Nowadays, processors have instructions sets that allow them to execute several simple arithmetic operations at once. For instance, let's say you have two arrays of integers and you want to add each element to the corresponding one in the other array. If both arrays have size N, this means you'll have to carry out N scalar additions. But processors can actually group these into bundles of several additions, with SIMD; for the case of 32-bits wide integers, on most modern processors, you need at most Math.ceil(N / 4) instructions. The blog post details what SIMD.js is and what bottlenecks we hit during implementation.

Conclusion

This was a small reminder about previously written blog posts. If you're into JavaScript, compilers or low-level optimization, I can only recommend you to go read the Mozilla's JavaScript blog.


A Tale Of Linux On The Desktop

Posted on Wed 27 January 2016 in blog • Tagged with opensource

So I've received a new desktop machine at home, on which only Windows 10 was installed. I've decided to install Linux, for my day-to-day hacking. Unfortunately, when I've plugged the Ubuntu (nobody's perfect) USB drive to my computer, I had the surprise to see a black screen showing up just after booting, and nothing else. Here are some notes taken during the installation of Linux on this machine.

Twitter fame

Graphics not working

Graphics don't work, but we can still install Ubuntu in non-graphic mode with an alternate install image, namely the network installer. Let's try that.

The machine has a Nvidia graphics card, so the open-source Nouveau graphics driver is used by default. Suspecting proprietary drivers might solve the problem, I decide to download them. Then, to my greatest surprise, I find out network isn't working, be it the wireless network or Ye Olde Ethernet network.

Ethernet not working

The computer vendor's website says the network card is an Atheros Killer 2400. Looking that up on the web with my favorite search engine, this StackOverflow page showed up. The solution to make ethernet work at the end of the installation is the following:

modprobe alx
echo 1969 e0a1 > /sys/bus/pci/drivers/alx/new_id

This enables the module alx and registers the device to the module. Now ethernet is working. Fiuu. Let's keep moving.

Install All The Drivers!

The ubuntu's nvidia troubleshooting page gives you a nice tool that show you what drivers are adapted to your hardware: ubuntu-drivers. Here's an output example given by this command:

$ sudo ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
vendor   : NVIDIA Corporation
modalias : pci:v000010DEd00000FE9sv0000106Bsd00000130bc03sc00i00
driver   : xserver-xorg-video-nouveau - distro free builtin
driver   : nvidia-340-updates - distro non-free
driver   : nvidia-340 - distro non-free
driver   : nvidia-352 - distro non-free recommended
driver   : nvidia-352-updates - distro non-free

So this tells me what the recommanded driver for my nvidia card is. For bonus credit, it also shows me a recommended driver for the builtin WiFi card. Once I've installed it, it has been working like a charm!

Moar graphics settings

After the nvidia driver has been installed, a tweak was needed to ensure the driver outputs video on the DVI port instead of the VGA port. Beforehand, the xorg.conf file was generated thanks to the nvidia-xsettings command.

Final boss: UEFI

Now that all minimal drivers are correctly installed and configured, let's try to reboot. Although I've installed the grub bootloader on the main disk, I can't find a way to access it, even by trying all the lines in the boot menu.

The reason is that I've boot up the USB drive in legacy mode, which is not UEFI mode. As a matter of fact, Ubuntu has been installed in legacy mode but the machine is booting with UEFI, so Linux can't be seen from the bootloader.

Fortunately, this is Linux, and everything that has been done can be undone. If you can find a way to boot with UEFI and log in under Linux (maybe chrooting), then you can follow this procedure.

I couldn't boot in UEFI mode, but I could run the Boot-Repair-Disk on USB as UEFI, so I've followed the procedure there and converted my installation into UEFI mode.

Linux After All

And here we are, with Linux working out of the box^W^W^W^W. So yes, 2016 will be another year of Linux on the desktop for me; but it still feels unlikely for a newcomer to install Ubuntu and see it Just Work on any given machine, so maybe 2017 will be the year of Linux on the desktop, but not 2016.

Many thanks to @etnbrd, @martiusweb and @padenot for the detailed explanations about some Linux specifics and for advices.


Kresus: version 0.7.0

Posted on Mon 18 January 2016 in blog • Tagged with kresus, cozycloud

Je viens de publier une nouvelle version de Kresus, le gestionnaire de finances personnelles open-source sur lequel je travaille. Pour rappel, cette application, basée sur Weboob, est disponible dans CozyCloud et vous permet de vous connecter à votre compte bancaire, récupérer vos opérations et les classifier pour savoir où votre argent passe.

La version courte

  • Coup de pinceau magistral sur l'interface, merci @AwYiss !
  • Support de nouvelles banques, merci @ZeHiro !
  • Possibilité de sélectionner un compte par défaut, merci @nicofrand !
  • Réparation du lien entre factures et opérations bancaires, merci @ZeHiro !
  • Couleurs associées aux catégories, merci @nicofrand !
  • Réparation du module HelloBank.
  • Mise à jour automatique quotidienne de Weboob.
  • L'installation sera désormais plus rapide (l'application est précompilée par les développeurs, et non plus compilée au moment de l'installation).

Les contributions en détail

Un grand merci à tous les contributeurs qui ont été hyperactifs ce mois-ci !

  • @AwYiss a personnalisé et donné un coup de jeune à toute l'interface ! Notamment, l'interface est maintenant utilisable sur mobile. Merci @AwYiss!
  • @nicofrand a été prolifique :
    • Il y a désormais un bouton "fermer" et un bouton "vider et fermer" dans la fenêtre de recherche des opérations, qui explicitent mieux les intentions.
    • Il est maintenant possible d'éditer les champs personnalisés de connexion aux banques (par ex. la phrase secrète de connexion, etc.).
    • Un compte peut désormais être sélectionné comme compte par défaut, dans les préférences (étoile à côté des comptes). C'est ce compte-là qui s'affichera en premier quand vous vous connecterez à Kresus.
    • Kresus a une belle favicon, pour les versions mobiles !
    • Weboob peut être mis à jour sans qu'aucun compte ne soit présent, grâce à l'onglet "avancé" affiché lors de l'installation.
    • Il est désormais possible d'assigner une couleur à une catégorie. Cette couleur sera utilisée dans les graphiques en barre et en camembert pour représenter ladite catégorie.
  • @ZeHiro a également été très efficace :
    • Il est désormais possible de retirer un libellé personalisé d'une opération.
    • Il est possible de quitter le champ de libellé personalisé en pressant Echap.
    • Les factures liées par Konnector n'étaient pas récupérées correctement, c'est maintenant réparé !
    • Support de quelques nouvelles banques et intégration de toutes les variantes des banques, avec les icônes associées !
    • Des opérations peuvent être rajoutées à la main dans un compte. Bien que cela soit très utile, c'est pour le moment mal géré par la reconnaissance automatique des opérations, et donc à n'utiliser que si vous savez vraiment bien ce que vous faites.
    • Qualité du code : début de lint côté client.
  • votre serviteur :
    • mise à jour du module bancaire HelloBank
    • fusion automatique des comptes doublons très probables
    • mise à jour automatique des modules weboob, une fois par jour
    • possibilité de changer le login d'accès à une banque
    • amélioration de la qualité du code avec un lint côté serveur
    • meilleur affichage des erreurs côté client
    • mise à jour du système de build, des fichiers lisez-moi, etc.
    • simplification des traductions et ajout d'un script pour vérifier la cohérence entre les traductions.

Si vous voulez voir encore plus de détails, les commits sont présentés par là.

Le mot de la fin

Comme d'habitude, si vous avez des remarques ou suggestions, n'hésitez-pas à me le faire savoir, par twitter ou sur le forum de cozy !


Hello Mozilla, world!

Posted on Thu 31 December 2015 in blog • Tagged with mozilla

Hello Mozilla!

Hello world! And in advance, happy new year!

I am going to try to blog more about my work at Mozilla, and this will happen in this new mozilla category. You can expect technical posts about SpiderMonkey (the JS virtual machine implementation in Mozilla Firefox), OdinMonkey / asm.js, WebAssembly (wasm), and all things Mozilla in this category.

Feel free to reach me out via twitter, and see you soon!


CozyCloud : migrer son instance 2, le retour

Posted on Thu 19 November 2015 in blog • Tagged with cozycloud

Si vous vous rappelez bien, j'ai déjà écrit un article pour expliquer comment migrer son instance https://cozy.io d'un endroit vers un autre. Ces derniers jours, je me suis rendu compte que mon serveur personnel était sous-utilisé et qu'il me serait possible d'en prendre un plus léger et moins cher, d'où la nécessité d'une nouvelle migration d'un serveur à un autre.

Edit (10 février 2016) : j'ai ajouté la copie des répertoires permanents à cette procédure, sans avoir pu tester. Vos retours sur cette partie sont les bienvenus !

Les étapes sont les suivantes :

  • Récupérer la base de l'ancien Cozy.
  • Recopier le répertoire de données permanentes des apps.
  • La mettre en place dans le nouveau Cozy.
  • Réinstaller les applications.

Récupérer la base de l'ancien Cozy

Il s'agit d'un fichier qui contient toutes les données relatives à votre Cozy, que ce soit des données internes (par exemple, quelles applications installées) ou propres aux applications (par exemple, vos comptes en banques).

Si votre Cozy est hébergé par CozyCloud (sur cozycloud.cc donc), il est possible de demander l'export de la base de données CouchDB à l'équipe Cozy. Problème réglé.

Si vous êtes auto-hébergé, il va falloir mettre les mains dans le cambouis :

D'abord, réduire la taille de la base de données, c'est-à-dire effectuer un compactage de la base de données. C'est parti, depuis l'ancien serveur :

    # On éteint Cozy pour éviter l'apparition de nouvelles données
    sudo service supervisor stop
    # On fait une sauvegarde de la base, en cas de pépin
    cd /var/lib/couchdb/
    sudo cp cozy.couch cozy.couch.backup
    # On compacte la base
    sudo cozy-monitor compact

Ensuite, récupérer la base elle-même. Celle-ci est contenue dans le répertoire /var/lib/couchdb/ et porte le nom de cozy.couch, sauf si vous l'avez modifié vous-même.

L'ancien Cozy était installé par le package Debian

Si vous avez installé votre serveur avec le package Debian ou Ubuntu, il est possible d'utiliser l'outil scp pour effectuer cette tâche, en vous connectant depuis le nouveau serveur vers l'ancien. Si vous utilisez cette méthode, prenez soin de nommer la version sur le nouveau serveur cozy.couch.new, c'est important pour la suite.

L'ancien Cozy était installé avec Docker

Si comme moi vous avez préféré jouer avec le feu et utiliser Docker pour installer votre cozy, il va falloir ruser un peu. Personnellement, j'ai choisi la méthode malpropre, à savoir exposer la base de données sur le serveur web pendant un court instant et utiliser wget sur le nouveau cozy. Il est sûrement possible d'extraire le fichier depuis le Docker vers l'hôte, mais j'avoue ne pas avoir cherché ; si quelqu'un connaît une méthode, je suis preneur ! Pour ma méthode « malpropre », il faut modifier le fichier de configuration de nginx pour donner accès au fichier :

    # Copier la base vers /var/www
    sudo cp /var/lib/couchdb/cozy.couch /var/www/cozy.couch.new
    # Donner les droits en lecture à nginx
    sudo chown www-data:www-data -R /var/www
    # Editer le fichier de config de nginx avec le meilleur éditeur du monde
    sudo vim /etc/nginx/sites-available/cozy.conf

J'ai remplacé le bloc location/ { proxy_set_header ... par le suivant :

    location / {
        root /var/www;
        try_files $uri $uri/ /index.html;
    }

Toujours depuis l'ancien serveur, bien penser à relancer nginx :

    sudo service nginx restart

Ensuite, depuis le nouveau serveur, sur lequel je suppose que vous avez déjà installé le paquet cozy et qu'il tourne correctement :

    cd /var/lib/couchdb
    # Stopper supervisor va arrêter tout cozy
    sudo service supervisor stop
    sudo service couchdb stop
    sudo wget https://monanciencozy.tld/cozy.couch.new

Recopier les données permanentes des applications

Cela a été rajouté depuis l'écriture initiale de ce blog post, il est donc probable que cela ne fonctionne pas, dans quel cas contactez-moi svp !

Depuis des versions récentes de la plateforme, Cozy autorise les applications à avoir un répertoire de données permanentes, qui sont conservées même si l'application a été désinstallée. C'est très pratique pour porter facilement des applications qui utilisent des fichiers comme mémoire vers Cozy !

Pour porter ce répertoire, voici la procédure à effectuer :

  • copier le répertoire sur la machine précédente et le mettre dans un zip, par exemple:

    # depuis la machine qui héberge l'ancien cozy
    cd /usr/local/var/cozy
    zip /tmp/usr-local-var-cozy.zip -r ./*
    
  • transférer le zip vers le nouveau serveur (avec votre méthode préférée : FTP, Web, scp, etc.). Par exemple, avec scp:

    # depuis la nouvelle machine
    scp user@ancienne-machine:/tmp/usr-local-var-cozy.zip /tmp
    
  • remplacer le répertoire sur la nouvelle machine:

    # depuis la nouvelle machine
    mkdir -p /usr/local/var/cozy
    cd /usr/local/var/cozy && zip backup.zip -r ./*
    unzip /tmp/usr-local-var-cozy.zip
    

Mettre en place la base dans le nouveau cozy

Je suppose que vous avez déjà récupéré la base d'une manière ou d'une autre, et que celle-ci est déjà présente dans /var/lib/couchdb, sous le nom cozy.couch.new. Depuis le nouveau serveur, effectuez les commandes suivantes :

        cd /var/lib/couchdb
        # On arrête Cozy (via supervisor) et couchdb
        sudo service supervisor stop
        sudo service couchdb stop
        # Backup de l'ancienne base
        sudo mv cozy.couch cozy.couch.old
        sudo mv cozy.couch.new cozy.couch
        sudo chown -R couchdb:couchdb ./cozy.couch
        # On relance le tout
        sudo service couchdb start
        sudo service supervisor start

Et voilà ! Après cela, il va falloir attendre quelques minutes que le contrôleur Cozy relance les applications.

Réinstaller les applications manquantes

L'import de la base comprend les données internes à Cozy, notamment les informations sur les applications installées. Comme on vient d'importer une base qui vient d'un autre cozy où des applications sont installées, le nouveau cozy va penser que certaines applications sont présentes sur le disque, alors qu'elles ne le sont pas. Il est nécessaire d'effectuer une petite réparation ici, au niveau de la pile logicielle cozy et des applications installées. Heureusement, l'équipe a pensé à ça et nous a fourni une commande qui permet de réinstaller les applications utilisateurs. C'est parti, depuis le nouveau serveur :

    # Mettre à jour cozy-monitor (utile pour les image préinstallées)
    sudo npm install -g cozy-monitor
    # Mettre à jour l'ensemble de la pile Cozy pour commencer
    sudo cozy-monitor update-all-cozy-stack
    # Réinstaller les applications manquantes
    sudo cozy-monitor reinstall-missing-app

J'ai eu plusieurs erreurs à ce moment-là, souvent liées à des applications qui n'étaient plus trouvées sur github, ou des erreurs réseaux. En général, relancer la commande fonctionne, sinon j'ai purement et simplement désinstallé l'application en question. Par exemple, si l'application plantée était Kresus, j'ai simplement effectué

    sudo cozy-monitor uninstall kresus

Ce n'est pas un problème, car la désinstallation d'une application n'implique pas la désinstallation des données. Ensuite, il est possible de réinstaller les applications depuis l'interface du site web.

Pour terminer, il faut mettre à jour les permissions des dossiers contenant les données persistantes :

   cd /usr/local/var/cozy
   # On change les permissions pour chaque dossier. Note, penser à changer
   # le nom de l'application à chaque fois
   sudo chown -R cozy-nomApp nomApp

Conclusion

Notons que la migration d'un serveur à l'autre est désormais beaucoup plus facile qu'auparavant ! Pas besoin de rafistoler les données directement dans la base, et il existe une commande pour réinstaller les applications automatiquement. Bien joué, l'équipe Cozy !

J'espère que cette procédure aura marché pour vous, j'ai écrit ces notes rapidement et de mémoire. Si j'ai oublié quoi que ce soit, n'hésitez pas à me contacter sur twitter, diaspora ou sur irc (mon nick est bnjbvr). Si ça a marché et que vous avez apprécié, n'hésitez pas à me le dire également. ;-)


Kresus: version 0.6.0

Posted on Mon 16 November 2015 in blog • Tagged with kresus, cozycloud

Je viens de publier une nouvelle version de Kresus, le gestionnaire de finances personnelles open-source sur lequel je travaille. Pour rappel, cette application est disponible dans CozyCloud et vous permet de vous connecter à votre compte bancaire, récupérer vos opérations et les classifier pour savoir où votre argent passe.

Les gros changements de cette version

  • Support des banques ING et HSBC (merci nicofrand !).
  • Libellés personnalisés : dans la liste des opérations, il est possible de renommer une opération en cliquant sur son libellé, en ajoutant des informations personnalisées dessus. Ce libellé personnalisé est également pris en compte dans la recherche par mots-clés (merci ZeHiro !).
  • Notifications par email : Il est maintenant possible d'envoyer des notifications si le solde d'un compte dépasse ou est en dessous d'un seuil donné; ou si une nouvelle opération dépasse un certain seuil. Il est également possible d'envoyer des rapports quotidiens, hebdomadaires ou mensuels, qui contiennent les nouvelles opérations importées durant la période. Plus à venir dans les prochaines versions.

Tous les changements de cette version

Merci à tous les contributeurs de cette version, que ce soit en patches ou en rapports d'erreurs !

  • ZeHiro:
    • Meilleure détection des doublons (moins de faux positifs).
    • Le tri des opérations / catégories etc. est maintenant conscient de la locale utilisée (les accents sont pris en compte, etc.).
    • Support des libellés personnalisés (voir ci-dessus).
  • nicofrand:
    • Support des champs personnalisés pour l'identification sur certaines banques en ligne. Certaines banques demandent la réponse à une question personnalisée ou la date de naissance, pour pouvoir s'identifier, en plus du login et du mot de passe. Cette contribution apporte les bases nécessaires pour supporter ces champs supplémentaires. En pratique, cela veut dire qu'ING et HSBC sont maintenant supportés par Kresus !
    • Le bouton "vider" dans la fenêtre de recherche est maintenant en orange, pour alerter l'utilisateur.
    • Ajout d'un bouton "vider et fermer" dans cette même fenêtre, afin de bien distinguer les deux actions : "vider" efface les champs du formulaire, "vider et fermer" ferme le formulaire de recherche.
  • babolivier:
    • Vérification de la présence de virtualenv lors de l'installation de Weboob, avec fallback sur virtualenv2 s'il est présent.
  • dattaz:
    • Ajout de npm comme dépendance à l'installation Debian standalone
  • padenot:
    • Amélioration d'une traduction de chaîne en anglais
  • rlustin:
    • Suppression des espaces en fin de ligne

Et les autres ajouts et modifications dans Kresus :

  • Implémentation des rapports par emails et des alertes par email (voir ci-dessus).
  • Possibilité de rechercher les libellés personnalisés, lors d'une recherche par mots-clés.
  • Les imports d'instance évitent maintenant de réimporter les données internes à Kresus et les catégories si elles sont déjà présentes, ce qui évite des bugs par la suite.
  • Kresus est capable de détecter si Weboob est installé de manière globale et l'utiliser de préférence, plutôt que télécharger et l'installer localement, si c'est possible.
  • Le démarrage de l'application est plus séquentiel, ce qui évite des ralentissements au lancement (notamment pour la version standalone) et implique une meilleure cohérence des données.
  • Réécriture complète du serveur, pour passer de CoffeeScript à ECMAScript 6. Le code est maintenant moderne, propre, plus facile à comprendre et n'utilise plus que JavaScript, de partout ! Cela va grandement faciliter les mises à jour du serveur.
  • Comme d'habitude, beaucoup de bugs mineurs ont été écrasés et de plus petits nettoyages dans le code ont eu lieu.

Les prochains chantiers

Les prochains chantiers sont les choses sur lesquelles j'aimerais me pencher pour la (les ?) prochaines versions. Bien sûr, toute contribution sur ces sujets est plus qu'encouragée et ce sera avec plaisir que je vous aiderai à parcourir et comprendre le code. Cela inclut, mais ne se limite pas à :

  • Une réécriture partielle du code client, pour qu'il soit moins dense (certains fichiers font plus de 1,000 lignes !) et plus compartementalisé.
  • Une meilleure gestion des erreurs affichées à l'utilisateur, pour qu'elles soient plus faciles à comprendre et à gérer, donc plus utiles.
  • Une manière de marquer des paires d'opérations comme n'étant PAS des doublons, de dé-fusionner des doublons, ainsi qu'une détection automatique intelligente de la plupart des doublons.
  • Une catégorisation automatique des opérations (enfin !).

Le mot de la fin

Comme d'habitude, si vous avez des remarques ou suggestions, n'hésitez pas à me le faire savoir, par twitter ou sur le forum de cozy !


Kresus: version 0.5.4

Posted on Sun 20 September 2015 in blog • Tagged with kresus, cozycloud

Je viens de publier une nouvelle version de Kresus, le gestionnaire de finances personnelles open-source sur lequel je travaille. Pour rappel, cette application est disponible dans CozyCloud et vous permet de vous connecter à votre compte bancaire, récupérer vos opérations et les classifier pour savoir où votre argent passe.

Nouveautés

Encore une autre mise à jour mineure avant de gros changements structurels !

  • Merci @ZeHiro: les types des opérations (carte bleue, chèque, virement, etc.), importés automatiquement depuis la version précédente, sont maintenant affichés dans l'interface et peuvent être modifiés à la main !
  • L'interface utilisateur pour changer le type et la catégorie d'une opération a été améliorée : ce sont maintenant de vrais boutons qui permettent cela, et grâce à ZeHiro, ces boutons sont mieux esthétiquement intégrés au reste de l'interface !
  • Merci @Goofy pour des corrections de la traduction française !
  • Merci @Cylwin qui a ajouté des liens vers d'autres applications Cozy (en particulier vers le connecteur EDF !).
  • Merci @rgarrigue qui a amélioré le processus d'installation pour la version standalone (sans Cozy).
  • Il est maintenant possible de rechercher par type d'opération également. L'export contient dorénavant les types des opérations et l'import sait les gérer.
  • Le fichier d'instructions README a encore été étoffé ! La documentation est un travail de longue haleine...
  • Et comme d'habitude, beaucoup de petits bugs ont été résolus : les exports sont maintenant plus solides; les opérations sont maintenant triées correctement dans tous les navigateurs; plus de doublons peuvent être trouvés; les recherches par dates sont correctes, etc.

Le mot de la fin

Comme d'habitude, si vous avez des remarques ou suggestions, n'hésitez-pas à me le faire savoir, par twitter ou sur le forum de cozy !


Getting Things Done: The Good Parts

Posted on Tue 08 September 2015 in blog • Tagged with lifehacking

Getting Things Done: The Good
Parts

I've finished the Getting Things Done book a few weeks ago and wanted to write up a bit about it, as a summary of all the great big ideas I've found in that book.

Stop the juggling

It often happens that we get a lot of thoughts about plenty of things we'd like to do later along the day. Call X. Buy Y. Think about Z. The most common reaction to this flow of ideas is to say "alright, I'll do it later, but I really must not forget about it". That's the best way to actually forget about this thing, to be stressed and to feel like we should spend all our time doing it, right now.

I really liked a metaphor I've read from the free version of the Passion Planner, which was about juggling balls. If you have one or two in your hands, it's rather easy. With three balls, it gets a bit challenging, but you can handle that within a few hours. Four, five, six balls, you really need to practice before achieving it flowlessly. Seven and more? It sounds undoable to most of us, while we actually still try to do it. How mad is that?

The same thing happens with all the thoughts you have in your head. Remembering about one or two works fine, but beyond, it's both stressing and challenging. The solution is quite easy, though: whenever you get distracted by a thought, note it down on a piece of paper, any post-it or todo-list software and get back to it later. It works fine to have an inbox list that receives all these ideas, without more pondering or organisation.

You can get to classify these things later, at some specific times and quite regularily (e.g. at the end of the hour, day, or week, depending on your production rate :-)).

Be reminded

Some tasks have to be done at specific dates, or can't be done right now, or aren't urgent right now, or have to be done by other people. Forget about them, until you can't forget about them anymore. For that purpose, using any agenda software works like a charm: add a due date or a reminder to a task you have to do later, to be sure to not forget about it.

For tasks that are beyond your control (because they need actions from somebody else), estimate how much time you're willing to wait before you should try to get things moving forward and contact back the person who's in charge. When you're not sure about how much, ask the task's owner when you should get back to them. It gives a feeling of professionalism and it gives you a date for the reminder to set in your agenda software.

Tasks that belong to this kind should be moved from the Inbox to a Waiting For category of your todo-list (or binders, or anything you want), and be forgotten until the reminder triggers.

Don't throw away the crazy ones

If you have a stub idea for a new project, or an item you'd like to buy but obviously not right now, or some movie or TV show you just heard about and would like to watch in the future, file it into your inbox. When it's time to organize things a bit, put these items into a Maybe/Someday list or sub-list. I've got for instance a list of things I'd like to buy some day, movies I'd like to see, courses I'd like to follow, blog posts I'd like to read, and so on: all these lists belong to a Maybe/Someday folder.

Putting such things on lists also helps pondering their importance: is that item really worth it? Is it something that I could not do, not buy, not watch? In particular, things you want to buy right now might not appear as mandatory, after sitting in a list for a few months: this really helps avoiding impulse buyings.

Having a list full of crazy ideas is fine: the more you have, the more you'll get, and the more chances there'll be that one of them isn't that random.

Reduce projects to the next physical action

Where does procrastination come from? Often from our feeling of being overwhelmed by the size of the project in front of us: we don't know where to start or how to start. Whenever this happens to me, it often is due to a blurry description of the thing to do. For instance, "plan vacation" is definitely a fuzzy summary and doesn't help to understand what's the next step to accomplish.

The basic thrust is to reduce the project to the next physical action. What do I need to do to plan this vacation? I need to set dates and ask my partner if they will be available at this time. Which dates do I choose? I need to compare nights rates at several hostels, and so on. At some point, the thinking stops and you precisely know what your next step will be (in this example, that could be "find hostels rates comparator websites" or "go to website X and compare rates"). That's the kind of item that should be in your todo list (and writing down the n other steps you thought about will earn you some time).

To achieve Inbox Zero, treat emails like tasks

Inbox Zero is a famous productivity concept, stating that you'll have a clearer state of mind if you get to empty your inbox: no emails means no juggling! But that's harder than it sounds: we often inherit thousands of emails that are in our inboxes without any form of sorting. The initial triaging can take some time, but it's really worth it.

One solution that worked for me is to treat emails like tasks, by categorizing them into sub-lists:

  • Most personal emails land into my inbox. I've used automatic filters for common newsletters and mundane notifications, so that they don't pollute the inbox.
  • Important emails that I need to answer right now? I answer them on the go, and classify them right now.
  • I've got a subfolder of my inbox that's called read me later. That's for emails which don't need instantaneous action and that I can read later in the day / week, without any need to answer them. One neat trick I've read about is the unsubscribe filter: set up a filter stating that if the email's body contains the word "unsubscribe", then it should be filed into the "read me later" directory. Most non personal emails don't land in the inbox thanks to this.
  • There's a answer me subfolder, for emails that need an answer but with no urge. Most personal long form emails land in this folder, incubate for a while and at some point I answer them, and that's totally fine.
  • There's a waiting for subfolder, with emails I've written that are expecting an answer. I check it once every week but having a reminder in the agenda software works better anyway, so I'm unsure about its value.
  • All the other emails get archived. Email providers now have efficient and fast search tools, so any time I need to look for something that belongs to the past, I just type in a few keywords and it works fine.

Furthermore, I also recommend looking at emails at specific times of the day (maybe twice or three times a day, no more). Between these specific times, I block access to the emails client in the web browser: for Firefox, there's the great and free LeechBlock addon that achieves this.

Choose the next action by requirements

There are tasks that require a lot of energy to accomplish (like writing down a report, coding, etc.) while others just need you to be a bit less active (watching a conference video, reading new code, and so on). There are tasks that can be done only at work, and others that can be done only at home. Some are urgent to do before next Thursday, some could be done maybe one day in a far, far away future. Some can be done in less than two minutes, some others will take hours.

See what's going on here? Tasks often have instrinsic caracteristics: required energy, estimated time needed to complete, priority, location / context. When time comes to the actual doing, it's important to consider these requirements and to choose accordingly.

For instance, if you're starting a quite long task at the end of the day, the chance is low that you'll finish it today. But if you feel a need for closure, you're clearly going to overwork and stay late at work. However, if you consider the time required to finish this task before starting it, you may not start it this day. Instead, you can just do something shorter. That also means prioritizing your work at the start of the day and thus not spending your time on non important stuff as it comes.

Conclusion

There are many other ideas in the book that would need more explanation, but if you've already read about productivity and emails management, it should sound familiar and give yourself some insight.

The getting things done website contains a nice summary of the five ideas explained in the book. If you have some time, it's nice to read it carefully, with a pair of modern eyes: some of the tools recommended in this book looked very old-school to me (binders? really?). I am using the Wunderlist todo application, as it is, for me, both complete (tasks, sub-tasks, lists of tasks, folders of lists, reminders, due dates) and minimal (nothing else that make it overly complicated).

Thanks for reading. If you have any comment or remark, feel free to drop me a line on twitter! If you've appreciated the blog post, don't hesitate to let me know and skim the rest of the blog posts ;-)

Picture by Unsplash, published under CC0 Public Domain