Posts Tagged ‘Devoxx’
[DevoxxFR 2022] Père Castor 🐻, raconte-nous une histoire (d’OPS)
Lors de Devoxx France 2022, David Aparicio, Data Ops chez OVHcloud, a partagé une conférence de 44 minutes sur l’apprentissage à partir des échecs en opérations informatiques. David a analysé les post-mortems d’incidents majeurs survenus chez des géants comme GitHub, Amazon, Google, OVHcloud, Apple, Fastly, Microsoft, GitLab et Facebook. En explorant les causes racines, les remédiations et les bonnes pratiques, il a montré comment tirer des leçons des erreurs pour renforcer la résilience des systèmes. Suivez OVHcloud sur ovhcloud.com et twitter.com/OVHcloud.
Comprendre les post-mortems
David a commencé par expliquer ce qu’est un post-mortem : un document rédigé après un incident pour comprendre ce qui s’est passé, identifier les causes et prévenir les récurrences. Il inclut l’historique de l’incident, les flux d’information, l’organisation (qui a agi, avec quelle équipe), les canaux de communication avec les clients, l’utilisation des ressources et les processus suivis. David a souligné l’importance de la transparence, citant des initiatives comme les meetups de développeurs où les échecs sont partagés pour démystifier les incidents.
Il a illustré son propos avec une histoire fictive d’Elliot, un junior qui, par erreur, supprime une base de données de production en suivant une documentation mal structurée. Cet incident, inspiré de cas réels chez AWS (2017), GitLab et DigitalOcean, montre les dangers d’un accès non contrôlé à la production. David a recommandé des garde-fous comme des approbations manuelles pour les commandes critiques (par exemple, DROP TABLE), des rôles RBAC stricts, et des tests réguliers des backups pour garantir leur fiabilité.
Les incidents personnels : le legacy à l’épreuve
David a partagé une expérience personnelle chez OVHcloud, où il gère le data lake pour répliquer les données internes. Lors d’une astreinte, un week-end d’été, il a été alerté d’un problème sur une infrastructure legacy sans documentation claire. Un service saturait sa file de connexions (1024 clients maximum), provoquant des refus. Sans réponse des développeurs, David a opté pour une solution KISS (Keep It Simple, Stupid) : une sonde vérifiant la connectivité toutes les cinq minutes, redémarrant le service si nécessaire. Ce script, en place depuis un an et demi, a redémarré le service 70 fois, évitant de nouveaux incidents.
Un autre incident concernait une application Java legacy, tombant après 20 à 40 minutes malgré des redémarrages. Les logs montraient des déconnexions ZooKeeper et des crashs JVM. Plutôt que d’ajuster la mémoire (heap tuning), David a découvert un script de nettoyage propriétaire dans l’historique. Appliqué deux fois par semaine, ce script a résolu le problème durablement. Ces cas illustrent l’importance de comprendre le legacy, d’éviter les solutions complexes et de documenter les correctifs.
Les pannes majeures : CDN et réseaux
David a analysé l’incident Fastly de juin 2021, où une erreur 503 a touché des sites comme The Guardian, The New York Times, Amazon, Twitter et la Maison Blanche. La cause : une configuration client déployée sans test le 8 juin, activée par une demande du 12 mai, révélant un point de défaillance unique (SPoF) dans le CDN. Résolu en 45 minutes, cet incident souligne l’importance de tester les changements en pré-production (par exemple, via blue-green deployments ou shadow traffic) et de personnaliser les messages d’erreur pour améliorer l’expérience utilisateur.
Un autre cas marquant est la panne Facebook de septembre 2021, causée par une mise à jour du protocole BGP (Border Gateway Protocol). Les serveurs DNS, incapables d’accéder aux datacenters, se sont mis en mode protection, coupant l’accès à Facebook, Instagram, WhatsApp et même aux outils internes (Messenger, LDAP). Les employés ne pouvaient ni badger ni consulter la documentation, obligeant une intervention physique avec des disqueuses pour accéder aux racks. David a recommandé des TTL (Time To Live) plus longs pour les DNS, des canaux de communication séparés et des routes de secours via d’autres cloud providers.
Bonnes pratiques et culture de l’échec
David a conclu en insistant sur la nécessité de ne pas blâmer les individus, comme dans le cas d’Elliot, mais de renforcer les processus. Il a proposé des tests réguliers de backups, des exercices de chaos engineering (par exemple, simuler une erreur 500 un vendredi après-midi), et l’adoption de pratiques DevSecOps pour intégrer la sécurité dès les tests unitaires. Il a également suggéré de consulter les post-mortems publics (comme ceux de GitLab ou ElasticSearch) pour s’inspirer et d’utiliser des outils comme Terraform pour automatiser les déploiements sécurisés. Enfin, il a encouragé à rejoindre OVHcloud pour expérimenter et apprendre des incidents dans un environnement transparent.
Kafka Streams @ Carrefour : Traitement big data à la vitesse de l’éclair
Lors de Devoxx France 2022, François Sarradin et Jérémy Sebayhi, membres des équipes data de Carrefour, ont partagé un retour d’expérience de 45 minutes sur l’utilisation de Kafka Streams pour des pipelines big data en temps réel. François, technical lead chez Moshi, et Jérémy, ingénieur senior chez Carrefour, ont détaillé leur transition des systèmes batch Spark et Hadoop vers un traitement stream réactif sur Google Cloud Platform (GCP). Leur talk a couvert l’adoption de Kafka Streams pour le calcul des stocks et des prix, les défis rencontrés et les solutions créatives mises en œuvre. Découvrez Carrefour sur carrefour.com et Moshi sur moshi.fr.
Du batch au stream processing
François et Jérémy ont débuté en comparant le traitement batch et stream. La plateforme legacy de Carrefour, datant de 2014, reposait sur Spark et Hadoop pour des jobs batch, traitant les données comme des fichiers avec des entrées et sorties claires. Les erreurs étaient gérables en corrigeant les fichiers d’entrée et en relançant les pipelines. Le streaming, en revanche, implique des flux d’événements continus via des topics Kafka, où les erreurs nécessitent une gestion en temps réel sans perturber le pipeline. Un événement corrompu ne peut être simplement supprimé, car les données historiques peuvent couvrir des années, rendant le reprocessing impraticable.
Kafka Streams, un framework réactif basé sur Apache Kafka, a permis à Carrefour de passer au stream processing. Il exploite Kafka pour un transit de données scalable et RocksDB pour un stockage d’état colocalisé à faible latence. François a expliqué que les développeurs définissent des topologies—graphes acycliques dirigés (DAG) similaires à ceux de Spark—avec des opérations comme map, flatMap, reduce et join. Kafka Streams gère automatiquement la création des topics, les stores d’état et la résilience, simplifiant le développement. L’intégration avec les services GCP (GCS, GKE, BigTable) et les systèmes internes de Carrefour a permis des calculs de stocks et de prix en temps réel à l’échelle nationale.
Surmonter les défis d’adoption
Adopter Kafka Streams chez Carrefour n’a pas été sans obstacles. Jérémy a noté que beaucoup d’équipes manquaient d’expérience avec Kafka, mais la familiarité avec Spark a facilité la transition, les deux utilisant des paradigmes de transformation similaires. Les équipes ont développé indépendamment des pratiques pour le monitoring, la configuration et le déploiement, consolidées ensuite en best practices partagées. Cette approche pragmatique a créé une base commune pour les nouveaux projets, accélérant l’adoption.
Le changement nécessitait une adaptation culturelle au-delà des compétences techniques. La plateforme data de Carrefour, gérant des volumes massifs et des données à haute vélocité (stocks, prix, commandes), exigeait un changement de mindset du batch vers le réactif. Le stream processing implique des jointures continues avec des bases externes, contrairement aux datasets statiques des batchs. François et Jérémy ont souligné l’importance d’une documentation précoce et d’un accompagnement expert pour naviguer dans les complexités de Kafka Streams, surtout lors des déploiements en production.
Bonnes pratiques et architectures
François et Jérémy ont partagé les pratiques clés émergées sur deux ans. Pour les schémas des topics, ils utilisaient Schema Registry pour typer les données, préférant des clés obligatoires pour assurer la stabilité des partitions et évitant les champs optionnels pour prévenir les ruptures de contrat. Les valeurs des messages incluaient des champs optionnels pour la flexibilité, avec des champs obligatoires comme les IDs et timestamps pour le débogage et l’ordonnancement des événements.
Maintenir des topologies stateful posait des défis. Ajouter de nouvelles transformations (par exemple, une nouvelle source de données) nécessitait de retraiter les données historiques, risquant des émissions dupliquées. Ils ont proposé des solutions comme les déploiements blue-green, où la nouvelle version construit son état sans produire de sortie jusqu’à ce qu’elle soit prête, ou l’utilisation de topics compactés comme snapshots pour stocker uniquement le dernier état par clé. Ces approches minimisaient les perturbations mais exigeaient une planification rigoureuse, les déploiements blue-green doublant temporairement les besoins en ressources.
Métriques et monitoring
Le monitoring des applications Kafka Streams était crucial. François a mis en avant des métriques clés : lag (messages en attente par topic/consumer group), indiquant les points de contention ; end-to-end latency, mesurant le temps de traitement par nœud de topologie ; et rebalance events, déclenchés par des changements de consumer group, pouvant perturber les performances. Carrefour utilisait Prometheus pour collecter les métriques et Grafana pour des dashboards, assurant une détection proactive des problèmes. Jérémy a insisté sur l’importance des métriques custom via une couche web pour les health checks, les métriques JMX de Kafka Streams n’étant pas toujours suffisantes.
Ils ont aussi abordé les défis de déploiement, utilisant Kubernetes (GKE) avec des readiness probes pour surveiller les états des applications. Une surallocation de CPU pouvait retarder les réponses aux health checks, causant des évictions de consumer groups, d’où l’importance d’un tuning précis des ressources. François et Jérémy ont conclu en vantant l’écosystème robuste de Kafka Streams—connecteurs, bibliothèques de test, documentation—tout en notant que sa nature événementielle exige un mindset distinct du batch. Leur expérience chez Carrefour a démontré la puissance de Kafka Streams pour des données en temps réel à grande échelle, incitant le public à partager ses propres retours.
[DevoxFR 2022] Cracking Enigma: A Tale of Espionage and Mathematics
In his captivating 45-minute talk at Devoxx France 2022, Jean-Christophe Sirot, a cloud telephony expert from Sherweb, takes the audience on a historical journey through the cryptanalysis of the Enigma machine, used by German forces during World War II. Jean-Christophe weaves a narrative that blends espionage, mathematics, and technological innovation, highlighting the lesser-known contributions of Polish cryptanalysts like Marian Rejewski alongside Alan Turing’s famed efforts. His presentation, recorded in April 2022 in Paris, reveals how Enigma’s secrets were unraveled through a combination of human ingenuity and mathematical rigor, ushering cryptography into the modern era. This post summarizes the key themes, from early Polish breakthroughs to Turing’s machines, and reflects on their lasting impact.
The Polish Prelude: Cryptography in a Time of War
Jean-Christophe sets the stage in post-World War I Poland, a nation caught between Soviet Russia and a resurgent Germany. In 1919, during the Polish-Soviet War, Polish radio interception units, staffed by former German army officers, cracked Soviet codes, securing a decisive victory at the Battle of Warsaw. This success underscored the strategic importance of cryptography, prompting Poland to invest in codebreaking. By 1929, a curious incident at Warsaw’s central station revealed Germany’s use of Enigma machines. A German embassy official’s attempt to retrieve a misrouted “radio equipment” package—later identified as a commercial Enigma—alerted Polish intelligence.
Recognizing the complexity of Enigma, a machine with rotors, a reflector, and a plugboard generating billions of possible configurations, Poland innovated. Instead of relying on puzzle-solvers, as was common, they recruited mathematicians. At a new cryptography chair in western Poland, young talents like Marian Rejewski, Henryk Zygalski, and Jerzy Różycki began applying group theory and permutation mathematics to Enigma’s ciphers. Their work marked a shift from intuitive codebreaking to a systematic, mathematical approach, laying the groundwork for future successes.
Espionage and Secrets: The German Defector
The narrative shifts to 1931 Berlin, where Hans-Thilo Schmidt, a disgruntled former German officer, offered to sell Enigma’s secrets to the French. Schmidt, driven by financial troubles and resentment after being demobilized post-World War I, had access to Enigma key tables and technical manuals through his brother, an officer in Germany’s cipher bureau. Meeting French intelligence in Verviers, Belgium, Schmidt handed over critical documents. However, the French, lacking advanced cryptanalysis expertise, passed the materials to their Polish allies.
The Poles, already studying Enigma, seized the opportunity. Rejewski and his team exploited a flaw in the German protocol: operators sent a three-letter message key twice at the start of each transmission. Using permutation theory, they analyzed these repeated letters to deduce rotor settings. By cataloging cycle structures for all possible rotor configurations—a year-long effort—they cracked 70–80% of Enigma messages by the late 1930s. Jean-Christophe emphasizes the audacity of this mathematical feat, achieved with minimal computational resources, and the espionage that made it possible.
Turing and Bletchley Park: Scaling the Attack
As Germany invaded Poland in 1939, the Polish cryptanalysts shared their findings with the Allies, providing documentation and a reconstructed Enigma machine. This transfer was pivotal, as Germany had upgraded Enigma, increasing rotors from three to five and plugboard connections from six to ten, exponentially raising the number of possible keys. The Polish method, reliant on the repeated message key, became obsolete when Germany reduced repetitions to once.
Enter Alan Turing and the team at Bletchley Park, Britain’s codebreaking hub. Turing devised a new approach: the “known plaintext attack.” By assuming certain messages contained predictable phrases, like weather forecasts for the Bay of Biscay, cryptanalysts could test rotor settings. Turing’s genius lay in automating this process with the “Bombe,” an electromechanical device that tested rotor and plugboard configurations in parallel. Jean-Christophe explains how the Bombe used electrical circuits to detect inconsistencies in assumed settings, drastically reducing the time needed to crack a message. By running multiple Bombes, Bletchley Park decrypted messages within hours, providing critical intelligence that shortened the war by an estimated one to two years.
The Legacy of Enigma: Modern Cryptography’s Dawn
Jean-Christophe concludes by reflecting on Enigma’s broader impact. The machine, despite its complexity, was riddled with flaws, such as the inability to map a letter to itself and the exploitable key repetition protocol. These vulnerabilities, exposed by Polish and British cryptanalysts, highlighted the need for robust algorithms and secure protocols. Enigma’s cryptanalysis marked a turning point, transforming cryptography from a craft of puzzle enthusiasts to a rigorous discipline grounded in mathematics and, later, computer science.
He draws parallels to modern cryptographic failures, like the flawed WEP protocol for early Wi-Fi, which used secure algorithms but a weak protocol, and the PlayStation 3’s disk encryption, undone by poor key management. Jean-Christophe’s key takeaway for developers: avoid custom cryptography, use industry standards, and prioritize protocol design. The Enigma story, blending human drama and technical innovation, underscores the enduring importance of secure communication in today’s digital world.
Resources:
-
Enigma by Dermot Turing
-
Our Spy in Hitler’s Office by Paul Paillole
-
The Code Book by Simon Singh
-
The Codebreakers by David Kahn
[DevoxxFR 2022] Exploiter facilement des fonctions natives avec le Projet Panama depuis Java
Lors de Devoxx France 2022, Brice Dutheil a présenté une conférence de 28 minutes sur le Projet Panama, une initiative visant à simplifier l’appel de fonctions natives depuis Java sans les complexités de JNI ou de bibliothèques tierces. Brice, contributeur actif à l’écosystème Java, a introduit l’API Foreign Function & Memory (JEP-419), montrant comment elle relie le monde géré de Java au code natif en C, Swift ou Rust. À travers des démonstrations de codage en direct, Brice a illustré le potentiel de Panama pour des intégrations natives fluides. Suivez Brice sur Twitter à twitter.com/Brice_Dutheil pour plus d’insights Java.
Simplifier l’intégration de code natif
Brice a débuté en expliquant la mission du Projet Panama : connecter l’environnement géré de Java, avec son garbage collector, au monde natif de C, Swift ou Rust, plus proche de la machine. Traditionnellement, JNI imposait des étapes laborieuses : écrire des classes wrapper, charger des bibliothèques et générer des headers lors des builds. Ces processus étaient sujets aux erreurs et chronophages. Des alternatives comme JNA et JNR amélioraient l’expérience développeur en générant des bindings au runtime, mais elles étaient plus lentes et moins sécurisées.
Lancé en 2014, le Projet Panama répond à ces défis avec trois composantes : les API vectorielles (non couvertes ici), les appels de fonctions étrangères et la gestion de la mémoire. Brice s’est concentré sur l’API Foreign Function & Memory (JEP-419), disponible en incubation dans JDK 18. Contrairement à JNI, Panama élimine les complexités du build et offre des performances proches du natif sur toutes les plateformes. Il introduit un modèle de sécurité robuste, limitant les opérations dangereuses et envisageant de restreindre JNI dans les futures versions de Java (par exemple, Java 25 pourrait exiger un flag pour activer JNI). Brice a souligné l’utilisation des method handles et des instructions d’invocation dynamique, inspirées des avancées du bytecode JVM, pour générer efficacement des instructions assembleur pour les appels natifs.
Démonstrations pratiques avec Panama
Brice a démontré les capacités de Panama via du codage en direct, commençant par un exemple simple appelant la fonction getpid de la bibliothèque standard C. À l’aide du SystemLinker, il a effectué une recherche de symbole pour localiser getpid, créé un method handle avec un descripteur de fonction définissant la signature (retournant un long Java), et l’a invoqué pour récupérer l’ID du processus. Ce processus a contourné les lourdeurs de JNI, nécessitant seulement quelques lignes de code Java. Brice a insisté sur l’activation de l’accès natif avec le flag –enable-native-access dans JDK 18, renforçant le modèle de sécurité de Panama en limitant l’accès à des modules spécifiques.
Il a ensuite présenté un exemple plus complexe avec la fonction crypto_box de la bibliothèque cryptographique Libsodium, portable sur des plateformes comme Android. Brice a alloué des segments de mémoire avec un ResourceScope et un NativeAllocator, garantissant la sécurité mémoire en libérant automatiquement les ressources après usage, contrairement à JNI qui dépend du garbage collector. Le ResourceScope prévient les fuites mémoire, une amélioration significative par rapport aux buffers natifs traditionnels. Brice a également abordé l’appel de code Swift via des interfaces compatibles C, démontrant la polyvalence de Panama.
Outils et potentiel futur
Brice a introduit jextract, un outil de Panama qui génère des mappings Java à partir de headers C/C++, simplifiant l’intégration de bibliothèques comme Blake3, une fonction de hachage performante écrite en Rust. Dans une démo, il a montré comment jextract créait des bindings compatibles Panama pour les structures de données et fonctions de Blake3, permettant aux développeurs Java de tirer parti des performances natives sans bindings manuels. Malgré quelques accrocs, la démo a souligné le potentiel de Panama pour des intégrations natives transparentes.
Brice a conclu en soulignant les avantages de Panama : simplicité, rapidité, compatibilité multiplateforme et sécurité mémoire renforcée. Il a noté son évolution continue, avec JEP-419 en incubation dans JDK 18 et une deuxième preview prévue pour JDK 19. Pour les développeurs d’applications desktop ou de systèmes critiques, Panama offre une solution puissante pour exploiter des fonctions spécifiques aux OS ou des bibliothèques optimisées comme Libsodium. Brice a encouragé le public à expérimenter Panama et à poser des questions, renforçant son engagement via Twitter.
[Devoxx France 2021] Overcoming Impostor Syndrome: Practical Tips
At Devoxx France 2021, Aurélie Vache, a Google Cloud expert and CNCF ambassador, delivered an inspiring session titled Tips pour combattre le syndrome de l’imposteur (YouTube). This non-technical talk tackled impostor syndrome, a pervasive feeling of self-doubt and illegitimacy despite evident success. Aurélie shared personal anecdotes and seven actionable strategies to combat this mindset, resonating with developers and tech professionals. Aligned with Devoxx’s emphasis on personal growth, the session empowered attendees to transform fear into strength, fostering confidence and community.
Understanding Impostor Syndrome
Aurélie began by gauging the audience’s familiarity with impostor syndrome, noting its growing awareness since her first talk in 2019. She posed three relatable questions: Do you fear asking “dumb” questions? Do you feel comfortable mentoring juniors but not peers? Do you worry others will “unmask” you as a fraud? Many raised hands, confirming the syndrome’s prevalence.
Impostor syndrome, Aurélie explained, is a distorted perception of one’s abilities, where individuals attribute success to luck or others’ efforts rather than their own competence. First identified in women, it affects both genders, with 70% of executives and many developers experiencing it. It manifests as a critical inner voice, whispering, “You’re not good enough” or “You don’t belong”. Aurélie shared her own struggles, admitting she felt unqualified to give this talk, yet used humor to dismiss these “nonsense” thoughts, setting a positive tone.
Celebrate Achievements and Learn from Mistakes
The first strategy is to acknowledge your knowledge, skills, and victories. Humans excel at self-criticism but struggle to recognize strengths. Aurélie advised listing accomplishments, such as solving a tough bug, and documenting them via mind maps to engage both brain hemispheres. She emphasized that no victory is too small and that mistakes are learning opportunities, not failures. For example, recalling a debugging triumph can counter the inner voice’s negativity, reinforcing your competence.
This practice aligns with cognitive behavioral techniques, helping reframe negative thoughts. Aurélie’s transparency about her doubts made the advice relatable, encouraging attendees to start small, perhaps by noting one achievement daily, to build self-awareness and confidence.
Build a Supportive Network
The second tip is to surround yourself with supportive communities, peers, and mentors. Aurélie credited her involvement with Duchess, a women-in-tech group, for helping her overcome self-imposed limits and achieve goals she once thought unattainable. Communities provide a safe space to share fears, reducing isolation. She also recommended learning from mentors or role models, acknowledging that no one knows everything—a liberating truth.
During Q&A, an attendee highlighted how pair programming within communities fosters mutual growth, reinforcing this strategy. Aurélie’s emphasis on collective strength resonated, encouraging attendees to join meetups, user groups, or online forums like Stack Overflow to find their tribe.
Share Knowledge and Contribute
Aurélie’s third strategy is to share knowledge and contribute, even if you feel “less qualified”. Writing blog posts, speaking at meetups, or contributing to open-source projects can boost confidence. She advised starting small—perhaps sharing internally at work—then progressing to public platforms or conferences. Other avenues include teaching kids at coding workshops or tweeting new learnings, as Aurélie did with a Kubernetes tip that resonated widely, proving even “obvious” insights have value.
An audience member echoed this, noting that sharing, even if you’re not the “best,” fills gaps left by others, enhancing visibility and confidence. Aurélie’s call to action—create and share content—empowered attendees to overcome perfectionism and contribute meaningfully.
Embrace Feedback and Positivity
The final strategies focus on mindset shifts. Tip four: seek constructive feedback over external validation, starting with topics you’re comfortable with. Tip five: engage in pair programming to learn collaboratively without judgment, as clarified during Q&A when addressing misconceptions about it being evaluative. Tip six: focus on positive feedback, like supportive colleagues, rather than dwelling on negativity, such as a harsh 2019 Devoxx comment that took Aurélie a month to process. Tip seven: accept that you can’t master every skill (e.g., Rust, Go, serverless) and view weaknesses as growth opportunities.
Aurélie shared a personal rejection from a master’s program due to poor interview performance, yet she thrived in tech, urging attendees to persevere beyond credentials. An attendee’s anecdote about Dan Abramov’s public admission of knowledge gaps reinforced that even experts don’t know everything, normalizing impostor feelings.
Transforming Fear into Strength
Aurélie concluded by framing impostor syndrome as a source of humility, a valuable trait for developers. Admitting “I don’t know” fosters collaboration, as others share similar doubts but fear speaking up. The syndrome, she argued, isn’t a flaw but a catalyst for growth, pushing you to learn, share, and help others. Referencing its mention in The Big Bang Theory, she destigmatized the topic, encouraging open dialogue.
Q&A discussions highlighted real-world challenges, like toxic colleagues amplifying impostor feelings, and Aurélie advised seeking supportive environments to mitigate this. Another attendee suggested companies avoid overselling candidates as “experts,” which can exacerbate impostor syndrome on new projects. Aurélie’s mantra—“You are legitimate”—left attendees empowered to embrace their worth.
Links:
- Aurélie Vache’s LinkedIn: https://www.linkedin.com/in/aurelievache/
- Aurélie Vache’s Twitter: https://twitter.com/aurelievache
- CloudBees: https://www.cloudbees.com/
- CNCF: https://www.cncf.io/
Hashtags: #ImpostorSyndrome #PersonalGrowth #AurélieVache #CloudBees #CNCF
[DevoxxFR 2021] Maximizing Productivity with Programmable Ergonomic Keyboards: Insights from Alexandre Navarro
In an enlightening session at Devoxx France 2021, Alexandre Navarro, a seasoned Java backend developer, captivated the audience with a deep dive into the world of programmable ergonomic keyboards. His presentation, titled “Maximizing Your Productivity with a Programmable Ergonomic Keyboard,” unveils the historical evolution of keyboards, the principles of ergonomic design, and practical strategies for customizing keyboards to enhance coding efficiency. Alexandre’s expertise, honed over eleven years of typing in the Bépo layout and eight years on a TextBlade, offers developers a compelling case for rethinking their primary input device. This post explores the key themes of his talk, providing actionable insights for programmers seeking to optimize their workflow.
A Journey Through Keyboard History
Alexandre begins by tracing the lineage of keyboards, a journey that illuminates why our modern layouts exist. In the 1870s, early typewriters resembled pianos with alphabetical key arrangements, mere prototypes of today’s devices. By 1874, the Sholes and Glidden typewriter introduced a layout resembling QWERTY, a design often misunderstood as a deliberate attempt to slow typists to prevent jamming. Alexandre debunks this myth, explaining that QWERTY was shaped by practical needs, such as placing frequent English digraphs like “TH” and “ER” for efficient typing. The addition of a number row and user feedback further refined the layout, with quirks like the absence of dedicated “0” and “1” keys—substituted by “O” and “I”—reflecting telegraphy influences.
This historical context sets the stage for understanding why QWERTY persists despite its limitations. Alexandre notes that modern keyboards, like the iconic IBM model, retain QWERTY’s staggered rows and non-aligned letters, a legacy of mechanical constraints irrelevant to today’s technology. His narrative underscores a critical point: many developers use keyboards designed for a bygone era, prompting a reevaluation of tools that dominate their daily work.
Defining Ergonomic Keyboards
Transitioning to ergonomics, Alexandre outlines the hallmarks of a keyboard designed for comfort and speed. He categorizes ergonomic features into three domains: physical key arrangement, letter layout, and key customization. Physically, an ergonomic keyboard should be orthogonal (straight rows, unlike QWERTY’s stagger), symmetrical to match human hand anatomy, flat to reduce tendon strain, and accessible to minimize finger travel. These principles challenge conventional designs, where number pads skew symmetry and elevated keys stress wrists.
Alexandre highlights two exemplary models: the Keyboardio Model 01 and the ErgoDox. The Keyboardio, which he uses, boasts orthogonal, symmetrical keys and accessible layouts, while the ErgoDox offers customizable switches and curvature. These keyboards prioritize user comfort, aligning with the natural positioning of hands to reduce fatigue during long coding sessions. By contrasting these with traditional keyboards, Alexandre emphasizes that ergonomic design is not a luxury but a necessity for developers who spend hours typing.
Optimizing with Programmable Keyboards
The heart of Alexandre’s talk lies in programming keyboards to unlock productivity. Programmable keyboards, like the ErgoDox and Keyboardio, emerged around 2011, powered by microcontrollers that developers can flash with custom firmware, often using Arduino-based C code or graphical tools. This flexibility allows users to redefine key functions, creating layouts tailored to their workflows.
Alexandre introduces key programming concepts, such as layers (up to 32, akin to switching between QWERTY and number pad modes), macros (single keys triggering complex shortcuts like “Ctrl+F”), and tap/hold behaviors (e.g., a key typing “A” when tapped but acting as “Ctrl” when held). These features enable developers to streamline repetitive tasks, such as navigating code or executing IDE shortcuts, directly from their home row. Alexandre’s personal setup, using the Bépo layout optimized for French, exemplifies how customization can enhance efficiency, even for English-heavy programming tasks.
Why Embrace Ergonomic Keyboards?
Alexandre concludes by addressing the “why” behind adopting ergonomic keyboards. Beyond speed, these devices offer comfort, reducing the risk of repetitive strain injuries—a concern for developers typing extensively. He shares his experience with the Bépo layout, which, while not optimized for English, outperforms QWERTY and AZERTY due to shared frequent letters and better hand alternation. For those hesitant to switch, Alexandre suggests starting with a blank keyboard to learn touch typing, ensuring all fingers engage without glancing at keys.
His call to action resonates with developers: mastering your keyboard is as essential as mastering your IDE. By investing in an ergonomic, programmable keyboard, programmers can transform a mundane tool into a productivity powerhouse. Alexandre’s insights, grounded in years of experimentation, inspire a shift toward tools that align with modern coding demands.
Links:
- Watch the full presentation: https://www.youtube.com/watch?v=zCMra9RgCzw
- Follow Devoxx France on LinkedIn: https://www.linkedin.com/in/devoxxfrance/
- Follow Devoxx France on Twitter: https://twitter.com/DevoxxFR
- Visit Devoxx France: https://www.devoxx.fr/
[DevoxxFR 2019] Micronaut: The Ultra-Light JVM Framework of the Future
At Devoxx France 2019, Olivier Revial, a developer at Stackeo in Toulouse, presented Micronaut: The Ultra-Light JVM Framework of the Future. This session introduced Micronaut, a modern JVM framework designed for microservices and serverless applications, offering sub-second startup times and a 10MB memory footprint. Through slides and demos, Revial showcased Micronaut’s cloud-native approach and its potential to redefine JVM development.
Limitations of Existing Frameworks
Revial began by contrasting Micronaut with established frameworks like Spring Boot and Grails. While Spring Boot simplifies development with auto-configuration and standalone applications, it suffers from runtime dependency injection and reflection, leading to slow startup times (20–25 seconds) and high memory usage. As codebases grow, these issues worsen, complicating testing and deployment, especially in serverless environments where rapid startup is critical. Frameworks like Spring create a barrier between unit and integration tests, as long-running servers are often relegated to separate CI processes.
Micronaut addresses these pain points by eliminating reflection and using Ahead-of-Time (AOT) compilation, performing dependency injection and configuration at build time. This reduces startup times and memory usage, making it ideal for containerized and serverless deployments.
Micronaut’s Innovative Approach
Micronaut, created by Grails’ founder Graeme Rocher and Spring contributors, builds on the strengths of existing frameworks—dependency injectiaon, auto-configuration, service discovery, and HTTP client/server simplicity—while introducing innovations. It supports Java, Kotlin, and Groovy, using annotation processors and AST transformations for AOT compilation. This eliminates runtime overhead, enabling sub-second startups and minimal memory footprints.
Micronaut is cloud-native, with built-in support for MongoDB, Kafka, JDBC, and providers like Kubernetes and AWS. It embraces reactive programming via Reactor, supports GraalVM for native compilation, and simplifies testing by allowing integration tests to run alongside unit tests. Security features, including JWT and basic authentication, and metrics for Prometheus, enhance its enterprise readiness. Despite its youth (version 1.0 released in 2018), Micronaut’s ecosystem is rapidly growing.
Demonstration
Revial’s demo showcased Micronaut’s capabilities. He used the Micronaut CLI to create a “hello world” application in Kotlin, adding a controller with REST endpoints, one returning a reactive Flowable. The application started in 1–2 seconds locally (6 seconds in the demo due to environment differences) and handled HTTP requests efficiently. A second demo featured a Twitter crawler storing tweets in MongoDB using a reactive driver. It demonstrated dependency injection, validation, scheduled tasks, and security (basic authentication with role-based access). A GraalVM-compiled version started in 20 milliseconds, with a 70MB Docker image compared to 160MB for a JVM-based image, highlighting Micronaut’s efficiency for serverless use cases.
Links:
Hashtags: #Micronaut #Microservices #DevoxxFR2019 #OlivierRevial #JVMFramework #CloudNative
Navigating the Application Lifecycle in Kubernetes
At Devoxx France 2019, Charles Sabourdin and Jean-Christophe Sirot, seasoned professionals in cloud-native technologies, delivered an extensive exploration of managing application lifecycles within Kubernetes. Charles, an architect with over 15 years in Linux and Java, and Jean-Christophe, a Docker expert since 2002, combined their expertise to demystify Docker’s underpinnings, Kubernetes’ orchestration, and the practicalities of continuous integration and delivery (CI/CD). Through demos and real-world insights, they addressed security challenges across development and business-as-usual (BAU) phases, proposing organizational strategies to streamline containerized workflows. This post captures their comprehensive session, offering a roadmap for developers and operations teams navigating Kubernetes ecosystems.
Docker’s Foundations: Isolation and Layered Efficiency
Charles opened the session by revisiting Docker’s core principles, emphasizing its reliance on Linux kernel features like namespaces and control groups (cgroups). Unlike virtual machines (VMs), which bundle entire operating systems, Docker containers share the host kernel, isolating processes within lightweight environments. This design achieves hyper-density, allowing more containers to run on a single machine compared to VMs. Charles demonstrated launching a container, highlighting its process isolation using commands like ps
within a containerized bash session, contrasting it with the host’s process list. He introduced Docker’s layer system, where images are built as immutable, stacked deltas, optimizing storage through shared base layers. Tools like Dive, he noted, help inspect these layers, revealing command histories and suggesting size optimizations. This foundation sets the stage for Kubernetes, enabling efficient, portable application delivery across environments.
Kubernetes: Orchestrating Scalable Deployments
Jean-Christophe transitioned to Kubernetes, describing it as a resource orchestrator that manages containerized applications across node pools. Kubernetes abstracts infrastructure complexities, using declarative configurations to maintain desired application states. Key components include pods—the smallest deployable units housing containers—replica sets for scaling, and deployments for managing updates. Charles demonstrated creating a namespace and deploying a sample application using kubectl run
, which scaffolds deployments, replica sets, and pods. He showcased rolling updates, where Kubernetes progressively replaces pods to ensure zero downtime, configurable via parameters like maxSurge
and maxUnavailable
. The duo emphasized Kubernetes’ auto-scaling capabilities, which adjust pod counts based on load, and the importance of defining resource limits to prevent performance bottlenecks. Their demo underscored Kubernetes’ role in achieving resilient, scalable deployments, aligning with hyper-density goals.
CI/CD Pipelines: Propagating Versions Seamlessly
The session delved into CI/CD pipelines, illustrating how Docker tags facilitate version propagation across development, pre-production, and production environments. Charles outlined a standard process: developers build Docker images tagged with version numbers (e.g., 1.1
, 1.2
) or environment labels (e.g., prod
, staging
). These images, stored in registries like Docker Hub or private repositories, are pulled by Kubernetes clusters for deployment. Jean-Christophe highlighted debates around tagging strategies, noting that version-based tags ensure traceability, while environment tags simplify environment-specific deployments. Their demo integrated tools like Jenkins and JFrog Artifactory, automating builds, tests, and deployments. They stressed the need for robust pipeline configurations to avoid resource overuse, citing Jenkins’ default manual build triggers for tagged releases as a safeguard. This pipeline approach ensures consistent, automated delivery, bridging development and production.
Security Across the Lifecycle: Development vs. BAU
Security emerged as a central theme, with Charles contrasting development and BAU phases. During development, teams rapidly address Common Vulnerabilities and Exposures (CVEs) with frequent releases, leveraging tools like JFrog Xray and Clair to scan images for vulnerabilities. Xray integrates with Artifactory, while Clair, an open-source solution, scans registry images for known CVEs. However, in BAU, where releases are less frequent, unpatched vulnerabilities pose greater risks. Charles shared an anecdote about a PHP project where a dependency switch broke builds after two years, underscoring the need for ongoing maintenance. They advocated for practices like running containers in read-only mode and using non-root users to minimize attack surfaces. Tools like OWASP Dependency-Track, they suggested, could enhance visibility into library vulnerabilities, though current scanners often miss non-package dependencies. This dichotomy highlights the need for automated, proactive security measures throughout the lifecycle.
Organizational Strategies: Balancing Complexity and Responsibility
Drawing from their experiences, Charles and Jean-Christophe proposed organizational solutions to manage Kubernetes complexity. They introduced a “1-2-3 model” for image management: Level 1 uses vendor-provided images (e.g., official MySQL images) managed by operations; Level 2 involves base images built by dedicated teams, incorporating standardized tooling; and Level 3 allows project-specific images, with teams assuming maintenance responsibilities. This model clarifies ownership, reducing risks like disappearing maintainers when projects transition to BAU. They emphasized cross-team collaboration, encouraging developers and operations to share knowledge and align on practices like Dockerfile authorship and resource allocation in YAML configurations. Charles reflected on historical DevOps silos, advocating for shared vocabularies and traceable decisions to navigate evolving best practices. Their return-of-experience underscored the importance of balancing automation with human oversight to maintain robust, secure Kubernetes environments.
Links:
- Devoxx France 2019 Video
- Kubernetes Documentation
- Docker Documentation
- JFrog Xray Documentation
- Clair GitHub Repository
- OWASP Dependency-Track
- Dive GitHub Repository
Hashtags: #Kubernetes #Docker #DevOps #CICD #Security #DevoxxFR #CharlesSabourdin #JeanChristopheSirot #JFrog #Clair
[DevoxxFR 2019] Back to Basics: Stop Wasting Time with Dates
At Devoxx France 2019, Frédéric Camblor, a web developer at 4SH in Bordeaux, delivered an insightful session on mastering date and time handling in software applications. Drawing from years of noting real-world issues in a notebook, Frédéric aimed to equip developers with the right questions to ask when working with dates, ensuring they avoid common pitfalls like time zone mismatches, daylight saving time (DST) quirks, and leap seconds.
Understanding Time Fundamentals
Frédéric began by exploring the historical context of time measurement, contrasting ancient solar-based “true time” with modern standardized systems. He introduced Greenwich Mean Time (GMT), now deprecated in favor of Coordinated Universal Time (UTC), which is based on International Atomic Time. UTC, defined by the highly regular oscillations of cesium-133 atoms (9,192,631,770 per second), is geopolitically agnostic, free from DST or seasonal shifts, with its epoch set at January 1, 1970, 00:00:00 Greenwich time.
The distinction between GMT and UTC lies in the irregularity of Earth’s rotation, affected by tidal forces and earthquakes. To align astronomical time (UT1) with atomic time, leap seconds are introduced every six months by the International Earth Rotation and Reference Systems Service (IERS). In Java, these leap seconds are smoothed over the last 1,000 seconds of June or December, making them transparent to developers. Frédéric emphasized the role of the Network Time Protocol (NTP), which synchronizes computer clocks to atomic time via a global network of root nodes, ensuring sub-second accuracy despite local quartz oscillator drift.
Time Representations in Software
Frédéric outlined three key time representations developers encounter: timestamps, ISO 8601 datetimes, and local dates/times. Timestamps, the simplest, count seconds or milliseconds since the 1970 epoch but face limitations, such as the 2038 overflow issue on 32-bit systems (though mitigated in Java). ISO 8601 datetimes (e.g., 2019-04-18T12:00:00+01:00) offer human-readable precision with time zone offsets, enhancing clarity over raw timestamps. Local dates/times, however, are complex, often lacking explicit time zone or DST context, leading to ambiguities in scenarios like recurring meetings.
Each representation has trade-offs. Timestamps are precise but opaque, ISO 8601 is readable but requires parsing, and local times carry implicit assumptions that can cause bugs if not clarified. Frédéric urged developers to choose representations thoughtfully based on application needs.
Navigating Time Zones and DST
Time zones, defined by the IANA database, are geopolitical regions with uniform time rules, distinct from time zone offsets (e.g., UTC+1). Frédéric clarified that a time zone like Europe/Paris can yield different offsets (UTC+1 or UTC+2) depending on DST, which requires a time zone table to resolve. These tables, updated frequently (e.g., nine releases in 2018), reflect geopolitical changes, such as Russia’s abrupt time zone shifts or the EU’s 2018 consultation to abolish DST by 2023. Frédéric highlighted the importance of updating time zone data in systems like Java (via JRE updates or TZUpdater), MySQL, or Node.js to avoid outdated rules.
DST introduces further complexity, creating “local time gaps” during spring transitions (e.g., 2:00–3:00 AM doesn’t exist) and overlaps in fall (e.g., 2:00–3:00 AM occurs twice). Libraries handle these differently: Moment.js adjusts invalid times, while Java throws exceptions. Frédéric warned against scheduling tasks like CRON jobs at local times prone to DST shifts (e.g., 2:30 AM), recommending UTC-based scheduling to avoid missed or duplicated executions.
Common Pitfalls and Misconceptions
Frédéric debunked several myths, such as “a day is always 24 hours” or “comparing dates is simple.” DST can result in 23- or 25-hour days, and leap years (every four years, except centurial years not divisible by 400) add complexity. For instance, 2000 was a leap year, but 2100 won’t be. Comparing dates requires distinguishing between equality (same moment) and identity (same time zone), as Java’s equals()
and isEqual()
methods behave differently.
JavaScript’s Date
object was singled out for its flaws, including inconsistent parsing (dashes vs. slashes shift time zones), zero-based months, and unreliable handling of pre-1970 dates. Frédéric recommended using libraries like Moment.js, Moment-timezone, or Luxon to mitigate these issues. He also highlighted edge cases, such as the non-existent December 30, 2011, in Samoa due to a time zone shift, which can break calendar applications.
Best Practices for Robust Date Handling
Frédéric shared practical strategies drawn from real-world experience. Servers and databases should operate in UTC to avoid DST issues and expose conversion bugs when client and server time zones differ. For searches involving local dates (e.g., retrieving messages by date), he advocated defining a date range (e.g., 00:00–23:59 in the user’s time zone) rather than a single date to account for implicit time zone assumptions. Storing future dates requires capturing the user’s time zone to handle potential rule changes.
For time-only patterns (e.g., recurring 3:00 PM meetings), storing the user’s time zone is critical to resolve DST ambiguities. Frédéric advised against storing times in datetime fields (e.g., as 1970-01-01T15:00:00), recommending string storage with time zone metadata. For date-only patterns like birthdays, using dedicated data structures prevents inappropriate operations, and storing at 12:00 UTC minimizes time zone shift bugs. Finally, he cautioned against local datetimes without time zones, as they cannot be reliably placed on a timeline.
Frédéric concluded by urging developers to question assumptions, update time zone data, and use appropriate time scales. His engaging talk, blending humor, history, and hard-earned lessons, left attendees ready to tackle date and time challenges with confidence.
Links:
Hashtags: #DateTime #TimeZones #DST #ISO8601 #UTC #DevoxxFR2019 #FrédéricCamblor #4SH #Java #JavaScript
Gradle: A Love-Hate Journey at Margot Bank
At Devoxx France 2019, David Wursteisen and Jérémy Martinez, developers at Margot Bank, delivered a candid talk on their experience with Gradle while building a core banking system from scratch. Their 45-minute session, “Gradle, je t’aime: moi non plus,” explored why they chose Gradle over alternatives, its developer-friendly features, script maintenance strategies, and persistent challenges like memory consumption. This post dives into their insights, offering a comprehensive guide for developers navigating build tools in complex projects.
Choosing Gradle for a Modern Banking System
Margot Bank, a startup redefining corporate banking, embarked on an ambitious project in 2017 to rebuild its IT infrastructure, including a core banking system (CBS) with Kotlin and Java modules. The CBS comprised applications for payments, data management, and a central “core” module, all orchestrated with microservices. Selecting a build tool was critical, given the need for speed, flexibility, and scalability. The team evaluated Maven, SBT, Bazel, and Gradle. Maven, widely used in Java ecosystems, lacked frequent updates, risking obsolescence. SBT’s Scala-based DSL added complexity, unsuitable for a Kotlin-focused stack. Bazel, while powerful for monorepos, didn’t support generic languages well. Gradle emerged as the winner, thanks to its task-based architecture, where tasks like compile
, jar
, and assemble
form a dependency graph, executing only modified components. This incremental build system saved time, crucial for Margot’s rapid iterations. Frequent releases (e.g., Gradle 5.1.1 in 2019) and a dynamic Groovy DSL further cemented its appeal, aligning with Devoxx’s emphasis on modern build tools.
Streamlining Development with Gradle’s Features
Gradle’s developer experience shone at Margot Bank, particularly with IntelliJ IDEA integration. The IDE auto-detected source sets (e.g., main
, test
, integrationTest
) and tasks, enabling seamless task execution. Eclipse support, though less polished, handled basic imports. The Gradle Wrapper, a binary committed to repositories, automated setup by downloading the specified Gradle version (e.g., 5.1.1) from a custom URL, secured with checksums. This ensured consistency across developer machines, a boon for onboarding. Dependency management leveraged dynamic configurations like api
and implementation
. For example, marking a third-party client like AmazingMail
as implementation
in a web app module hid its classes from transitive dependencies, reducing coupling. Composite builds, introduced in recent Gradle versions, allowed local projects (e.g., a mailer
module) to be linked without publishing to Maven Local, streamlining multi-project workflows. A notable pain point was disk usage: open-source projects’ varying Gradle versions accumulated 4GB on developers’ machines, as IntelliJ redundantly downloaded sources alongside binaries. Addressing an audience question, the team emphasized selective caching (e.g., wrapper binaries) to mitigate overhead, highlighting Gradle’s balance of power and complexity.
Enhancing Builds with Plugins and Kotlin DSL
For script maintainers, standardizing configurations across Margot’s projects was paramount. The team developed an internal Gradle plugin to centralize settings for linting (e.g., Ktlint), Nexus repositories, and releases. Applied via apply plugin: 'com.margotbank.standard'
, it ensured uniformity, reducing configuration drift. For project-specific logic, buildSrc
proved revolutionary. This module housed Kotlin code for tasks like version management, keeping build.gradle
files declarative. For instance, a Versions.kt
object centralized dependency versions (e.g., junit:5.3.1
), with unused ones grayed out in IntelliJ for cleanup. Migrating from Groovy to Kotlin DSL brought static typing benefits: autocompletion, refactoring, and navigation. A sourceSet.create("integrationTest")
call, though verbose, clarified intent compared to Groovy’s dynamic integrationTest {}
. Migration was iterative, file by file, avoiding disruptions. Challenges included verbose syntax for plugins like JaCoCo, requiring explicit casts. A buildSrc
extension for commit message parsing (e.g., extracting Git SHAs) exemplified declarative simplicity. This approach, inspired by Devoxx’s focus on maintainable scripts, empowered developers to contribute to shared tooling, fostering collaboration across teams.
Navigating Performance and Memory Challenges
Gradle’s performance, driven by daemons that keep processes in memory, was a double-edged sword. Daemons reduced startup time, but multiple instances (e.g., 5.1.1 and 5.0.10) occasionally ran concurrently, consuming excessive RAM. On CI servers, Gradle crashed under heavy loads, prompting tweaks: disabling daemons, adjusting Docker memory, and upgrading to Gradle 4.4.5 for better memory optimization. Diagnostics remained elusive, as crashes stemmed from either Gradle or the Kotlin compiler. Configuration tweaks like enabling caching (org.gradle.caching=true
) and parallel task execution (org.gradle.parallel=true
) improved build times, but required careful tuning. The team allocated maximum heap space (-Xmx4g
) upfront to handle large builds, reflecting Margot’s resource-intensive CI pipeline. An audience question on caching underscored selective imports (e.g., excluding redundant sources) to optimize costs. Looking ahead, Margot planned to leverage build caching for granular task reuse and explore tools like Build Queue for cleaner pipelines. Despite frustrations, Gradle’s flexibility and evolving features—showcased at Devoxx—made it indispensable, though memory management demanded ongoing vigilance.
Links :
Hashtags: #Gradle #KotlinDSL #BuildTools #DavidWursteisen #JeremyMartinez #DevoxxFrance2019