<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://elcaminodeunaprendiz.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://elcaminodeunaprendiz.com/" rel="alternate" type="text/html" hreflang="es" /><updated>2026-06-13T16:43:21+00:00</updated><id>https://elcaminodeunaprendiz.com/feed.xml</id><title type="html">El camino de un aprendiz</title><subtitle>Personal blog about software development, learning, books, games, and craft.</subtitle><author><name>Gabriel Moral Ortiz</name></author><entry><title type="html">Patterns, Principles, and Practice of Domain Driven Design book highlights</title><link href="https://elcaminodeunaprendiz.com/posts/patterns-principles-and-practices-ddd-highlights/" rel="alternate" type="text/html" title="Patterns, Principles, and Practice of Domain Driven Design book highlights" /><published>2020-06-16T17:00:00+00:00</published><updated>2020-06-16T17:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/patterns-principles-and-practices-ddd-highlights</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/patterns-principles-and-practices-ddd-highlights/"><![CDATA[<p>Recently in Aprendices book club, we have been reading <a href="https://www.goodreads.com/book/show/25531393-patterns-principles-and-practices-of-domain-driven-design">Patterns, Principles, and Practice od Domain Driven Design book</a> and I’d like to share a few points I consider important.</p>

<h4 id="domain-driven-design">Domain Driven Design</h4>

<p>DDD is an approach to software development where the focus is on the <strong>core domain</strong> of the business.
Subdomains using DDD should be treated as a <strong>product</strong> rather than a project. They are the part of the business that matters, they will grow over time and need special care by everyone. Not all the subdomains need to be implemented using DDD, DDD fits perfectly for the core domain.</p>

<p><strong>Shared/Ubiquitous language</strong> (UL) helps to connect the software model and the analysis model using the same terminology. By using UL with the business, the communication will be more explicit and both models will feed back and enrich. This is a key part of DDD that enables the domain experts and development teams to collaborate together.</p>

<p>Domain experts are usually people that are part of the organization, they can offer expertise in the problem domain. They could be a user of a current system. When talking with them try to keep the conversation focused on the problem space and do not jump to implementation details.</p>

<h4 id="implementation">Implementation</h4>

<ul>
  <li>Not all the bounded context need to be the same shape nor implemented using DDD, the important is to have clear <strong>boundaries</strong> between them.</li>
  <li>Physical boundaries are better to enforce clean models.</li>
  <li>A domain concept in one bounded context might mean something different in another bounded context.</li>
</ul>

<h5 id="tactical-patterns">Tactical patterns</h5>

<ul>
  <li><strong>Entities</strong> are domain concepts in the domain model. They are defined by their identity.</li>
  <li><strong>Value objects</strong> represent domain concepts by their treats, they don’t require identity.</li>
  <li><strong>Domain services</strong> encapsulate domain logic that doesn’t fit in entities/value objects.</li>
  <li><strong>Aggregates</strong> define transactional concurrency boundaries per object graph, they group entities and value objects. The aggregate must be the entry point for any business case.</li>
  <li><strong>Repositories</strong> are responsible for persisting and hydrating aggregates as an atomic unit. It abstracts the underlying persistence store from the domain model. Repositories are <em>not</em> required for UI/reporting purposes. Depending on the underlying persistence you domain model might be compromised, your domain model should be created without thinking on the persistence.</li>
</ul>

<h5 id="desing-patterns">Desing patterns</h5>

<ul>
  <li><strong>CQRS</strong> splits the domain model into two, a read model and a write model (transactional model). By applying this pattern, the transactional model does not need to expose internal state and be aware of the presentation concerns. It also helps to optimize/scaling the two models independently. There might be trade-offs when applying this pattern due to eventual consistency to the write or read model. Business must understand the <em>trade-off</em>.</li>
</ul>

<p>This information here is not even 1% of you will get from reading the book, if you are new to DDD or you would like to reinforce some knowledge I encourage you to give it a try.</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><summary type="html"><![CDATA[Recently in Aprendices book club, we have been reading Patterns, Principles, and Practice od Domain Driven Design book and I’d like to share a few points I consider important.]]></summary></entry><entry><title type="html">Monolith to microservices - Dealing with the Database</title><link href="https://elcaminodeunaprendiz.com/posts/monolith-to-microservices-dealing-with-the-database/" rel="alternate" type="text/html" title="Monolith to microservices - Dealing with the Database" /><published>2020-05-02T17:00:00+00:00</published><updated>2020-05-02T17:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/monolith-to-microservices-dealing-with-the-database</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/monolith-to-microservices-dealing-with-the-database/"><![CDATA[<p>One of the hardest tasks when moving into a monolithic to a microservice architecture is to separate the data owned by each microservice. Usually, the data is placed in one database schema and the goal when extracting microservices will be partition it accordingly without causing major issues. Sam Newman describes a few patterns in his book <a href="https://www.goodreads.com/book/show/44144499-monolith-to-microservices">Monolith to
Microservices Evolutionary Patterns to Transform Your Monolith</a> that would help with the task and I would like to give them briefly.</p>

<h3 id="shared-source-of-truth"><strong>Shared source of truth</strong></h3>
<p>The preferable option when extracting new microservices is also to move the data apart but that is not always possible to achieve, these patterns add options when facing this of scenario.</p>

<h4 id="shared-database"><strong>Shared Database</strong></h4>
<p>Multiple microservices use the same database as a source of truth.
It might be useful when the data to be accessed is read-only and highly stable or when the database is exposed as an endpoint (only read-only) to fulfil reporting needs or clients joining large amounts of data.</p>

<h4 id="database-view"><strong>Database view</strong></h4>
<p>Exposing different database views for each service might be useful to limit the data that services can access. 
Applying this pattern could help when the existing schema is difficult to decompose. If the end goal is to push for a full schema decomposition this pattern should be avoided.</p>

<h4 id="database-wrapping-service"><strong>Database wrapping service</strong></h4>
<p>It might be useful to add service as a wrapper of the database schema when is difficult to pull apart. This pattern will hide the database behind a service and introduce well define APIs. Clients that need the data can now consume the new service. This pattern intends to encourage people to stop making changes to the database and push for their services.</p>

<h4 id="database-as-service-interface"><strong>Database as service interface</strong></h4>
<p>With this pattern, there is a copy of the database in read-only mode. The new database is exposed directly to clients. This might be useful when dealing with reporting. An important obstacle that needs to be taken under consideration is the need for a mapping engine that will populate the new database from the source database.</p>

<h3 id="physical-or-logical-split"><strong>Physical or logical split?</strong></h3>
<p>Given the number of databases schemas are going to increase when splitting the monolith there are two options to consider if the databases share the same technology:</p>
<ul>
  <li>Have one single database engine with multiples schemas. By doing this there is only one point of failure.</li>
  <li>Have different database engines for each schema with the cost involved in it.</li>
</ul>

<h3 id="splitting-the-database-first"><strong>Splitting the database first</strong></h3>

<h4 id="repository-per-bounded-context"><strong>Repository per bounded context</strong></h4>
<p>Usually, within the monolith, the data access component is a big component. Instead of having that single repository layer, there are multiples components by bounded context. This technique helps to realise what data is needed in each bounded context and it is useful when looking into split the monolith to have a better understanding about what tables need to be moved apart as a new schema.</p>

<h4 id="database-per-bounded-context"><strong>Database per bounded context</strong></h4>
<p>Each bounded context has its database schema. This pattern is useful when the application is supposed to be split in the future into microservices. It is recommended to follow this approach when building new systems since with little effort developers will have more options available in the future.</p>

<h3 id="splitting-the-code-first"><strong>Splitting the code first</strong></h3>

<h4 id="aggregate-exposing-monolith"><strong>Aggregate exposing monolith</strong></h4>
<p>This pattern might be useful if the extracted microservice needs data owned by the monolith. Instead of accessing the data directly, the monolith exposes an API that is consumed by the new microservice. It also might help to discover other candidates to be extracted.</p>

<h4 id="multischema-storage"><strong>Multischema storage</strong></h4>
<p>This pattern fits in the scenario where the data owned by the microservice still lives under the monolith. The pattern can be applied when there is a new business capability for the microservice that need to add data into the schema. The new data should be added in the microservice schema instead of adding it into the monolith. This could open the door to move the entire data set out of the monolith.</p>

<h3 id="where-to-put-shared-static-data"><strong>Where to put shared static data?</strong></h3>
<p>This is a recurrent problem that can be solved with several approaches, let’s take a look.</p>

<h4 id="duplicate-static-reference-data"><strong>Duplicate static reference data</strong></h4>
<p>It might be useful when not all services need to have the same data. Answering these question should give a hint if we could apply it: How often does the data change and how consistent need to be across services?</p>

<h4 id="dedicated-reference-data-schema"><strong>Dedicated reference data schema</strong></h4>
<p>The data is placed under the same schema and is accessed by multiple services. Use it when changes are unlikely to happen. Take into account that a change in the schema might impact multiple services.</p>

<h4 id="static-reference-data-library"><strong>Static reference data library</strong></h4>
<p>Share the static data as a library might be an option for a small amount of data where different services can see multiple versions of that data.</p>

<h4 id="static-reference-data-service"><strong>Static reference data service</strong></h4>
<p>This option is obvious, the shared static data lives under a microservice who owns the data. This option might be feasible for organizations where creating a new microservice does not involve too much overhead.</p>

<p>In the next post, I’ll try to describe a few techniques to migrate data from the monolith database into the new schemas.</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><summary type="html"><![CDATA[One of the hardest tasks when moving into a monolithic to a microservice architecture is to separate the data owned by each microservice. Usually, the data is placed in one database schema and the goal when extracting microservices will be partition it accordingly without causing major issues. Sam Newman describes a few patterns in his book Monolith to Microservices Evolutionary Patterns to Transform Your Monolith that would help with the task and I would like to give them briefly.]]></summary></entry><entry><title type="html">Monolith to microservices - Splitting patterns</title><link href="https://elcaminodeunaprendiz.com/posts/monolith-to-microservices-splitting-patterns/" rel="alternate" type="text/html" title="Monolith to microservices - Splitting patterns" /><published>2020-04-05T17:00:00+00:00</published><updated>2020-04-05T17:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/monolith-to-microservices-splitting-patterns</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/monolith-to-microservices-splitting-patterns/"><![CDATA[<p>During a period Iḿ going to be working with the team trying to improve the evolvability of a system with a lot of responsibilities. That involves splitting apart it into a few microservices. The first thing we did in the team was to buy the book called <a href="https://www.goodreads.com/book/show/44144499-monolith-to-microservices">Monolith to
Microservices Evolutionary Patterns to Transform Your Monolith</a> written by Sam Newman because we knew it would help us decide from where to start.</p>

<p>On the third chapter of the book, Sam enumerates and explains a few patterns that will help when extracting microservices:</p>

<h2 id="strangler-fig-application"><strong>Strangler Fig Application</strong></h2>

<p>It helps to move functionality out of the monolith without doing a big bang release.</p>

<ol>
  <li>Identify asset to move.</li>
  <li>Move asset (copy-paste if possible).</li>
  <li>Redirect calls.</li>
</ol>

<p>It’s recommended to extract a vertical slice of the functionality.
To use it with success, the functionality being extracted has to map clearly to an inbound call.</p>

<h4 id="where-to-use-it">Where to use it</h4>
<p>To move functionality to the new service without touching or making any change to it.</p>

<h2 id="ui-composition"><strong>UI Composition</strong></h2>
<p>Show together with a group of pages or widgets exposed by different microservices. Allow vertical slices to be migrated.</p>

<h4 id="where-to-use-it-1">Where to use it</h4>
<p>When composing UI from a different microservices makes sense. It must be possible to modify the existing user interface for the new functionality to be added.</p>

<h2 id="branch-by-abstraction"><strong>Branch by Abstraction</strong></h2>
<p>It allows adding a different implementation for the functionality you want to extract that will coexist with the old one until ready to migrate.</p>

<ol>
  <li>Create abstraction of the functionality to be replaced.</li>
  <li>Replace clients for them to use the abstraction.</li>
  <li>Create the new implementation of the abstraction.</li>
  <li>Change the abstraction to use the new implementation.</li>
  <li>Clean the old implementation and abstraction.</li>
</ol>

<p>It can be combined with feature toggles to change between implementations.
When switching to the new implementation, keeping the old one for some time can be useful as a fallback mechanism if something goes wrong with the new code.</p>

<h4 id="where-to-use-it-2">Where to use it</h4>
<p>If the functionality to be decomposed is deeper inside in the system and it is not possible to intercept the calls at the monolith boundaries.</p>

<h2 id="parallel-run"><strong>Parallel Run</strong></h2>
<p>It is used to mitigate the risk of introducing the new implementation having errors. The pattern allows comparing the results of the new implementation with the old one to verify that the new one will behave correctly. Only one implementation is, in this case, the source of truth.</p>

<h4 id="where-to-use-it-3">Where to use it</h4>
<p>Use it when the functionality to be replaced is high risk.</p>

<h2 id="decorating-collaborator"><strong>Decorating Collaborator</strong></h2>
<p>Introducing a proxy that can intercept inbound requests or responses from the monolith allows adding new behaviour that is in a new microservice.</p>

<h4 id="where-to-use-it-4">Where to use it</h4>
<p>Use it when the monolith code is complex or cannot be modified.</p>

<h2 id="change-data-capture"><strong>Change Data Capture</strong></h2>
<p>Instead of intercepting calls to the monolith, the pattern intercepts changes in the data store. A few options to implement this pattern can be:</p>

<ul>
  <li>Database Triggers.</li>
  <li>Transaction log pollers.</li>
  <li>Batch scheduled process.</li>
</ul>

<h4 id="where-to-use-it-5">Where to use it</h4>
<p>If there is a need to act to a data change in the monolith and there are no other options to intercept it differently.</p>

<p><strong>Useful articles about this topic</strong></p>

<ul>
  <li><a href="https://martinfowler.com/bliki/StranglerFigApplication.html">StranglerFigApplication</a></li>
  <li><a href="https://mrtinfowler.com/bliki/EventInterception.html">EventInterception</a></li>
  <li><a href="https://martinfowler.com/bliki/AssetCapture.html">AssetCapture</a></li>
  <li><a href="https://continuousdelivery.com/2011/05/make-large-scale-changes-incrementally-with-branch-by-abstraction/">Make Large Scale Changes Incrementally with Branch By Abstraction</a></li>
  <li><a href="https://paulhammant.com/2013/07/14/legacy-application-strangulation-case-studies/">Legacy Application Strangulation: Case Studies</a></li>
  <li><a href="https://martinfowler.com/articles/micro-frontends.html">Micro Frontends</a></li>
  <li><a href="https://micro-frontends.org/">What are Micro Frontends?</a></li>
  <li><a href="https://engineering.shopify.com/blogs/engineering/refactoring-legacy-code-strangler-fig-pattern">Refactoring Legacy Code with the Strangler Fig Pattern</a></li>
</ul>]]></content><author><name>Gabriel Moral Ortiz</name></author><summary type="html"><![CDATA[During a period Iḿ going to be working with the team trying to improve the evolvability of a system with a lot of responsibilities. That involves splitting apart it into a few microservices. The first thing we did in the team was to buy the book called Monolith to Microservices Evolutionary Patterns to Transform Your Monolith written by Sam Newman because we knew it would help us decide from where to start.]]></summary></entry><entry><title type="html">Microservices Patterns - Conceptual Map</title><link href="https://elcaminodeunaprendiz.com/posts/microservices-patterns-conceptual-map/" rel="alternate" type="text/html" title="Microservices Patterns - Conceptual Map" /><published>2020-03-09T17:00:00+00:00</published><updated>2020-03-09T17:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/microservices-patterns-conceptual-map</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/microservices-patterns-conceptual-map/"><![CDATA[<p>During the first months of the year, I’ve been reading the book <a href="https://microservices.io/book"><strong>Microservices Patterns</strong></a> written by <strong>Chris Richardson</strong>.</p>

<p>In my opinion, even if you are not familiar with microservices or you already use microservices it will help you to understand the pros and cons of using microservices as architectural style. The book explains well-known patterns about how to do microservices properly that you can benefit of.</p>

<p>I’ve created this conceptual map collecting the most important ideas and patterns explained in the book.</p>

<p><a href="/assets/Microservices.jpg"><img src="https://elcaminodeunaprendiz.com/assets/Microservices.jpg" alt="Microservices Patterns conceptual map" /></a></p>

<p><a href="https://cmapscloud.ihmc.us:443/rid=1VKDHYV46-1P1WGWN-71Y5QD">Original map</a></p>

<p><a href="https://cmap.ihmc.us/">Cmap</a> is the tool I’ve used to model the map.</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><summary type="html"><![CDATA[During the first months of the year, I’ve been reading the book Microservices Patterns written by Chris Richardson.]]></summary></entry><entry><title type="html">Problems, not solutions</title><link href="https://elcaminodeunaprendiz.com/posts/problems-not-solutions/" rel="alternate" type="text/html" title="Problems, not solutions" /><published>2019-12-14T08:00:00+00:00</published><updated>2019-12-14T08:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/problems-not-solutions</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/problems-not-solutions/"><![CDATA[<p>IMHO CTOs, product managers and stakeholders should stop offering solutions and start talking about problems. Have you found yourself in a situation like this one?:</p>
<blockquote>
  <p>“Hey buddy we need to do X, Y, Z.”</p>
</blockquote>

<p>It happens all the time and I think we the software developers are responsible to educate people that we are not only solution implementors. We are also problem thinkers.</p>

<p>Why? Are we not paid to build software? Yes, we are. 
Are others not supposed to think about the problems and leave us the implementation? Of course not. I truly believe that developers must be involved in the context of the problems.</p>

<p>For us, the issue starts when we do not understand the problem and we are given a solution. Usually, thinking only in the solution leads to overcomplicated code, misjudge complexity, unused features and detachment of what the customer wants.</p>

<p>In the last years, I have realised that when developers think first about problems and not solutions the result is far better. And this is not something I am making up, this idea is in almost every agile book. Exploring the problem space is key in the context of the company trying to build the right thing. Even more when the company does not have loads of money to spend.</p>

<p>Perhaps the outcome of the exploration problem process is that the company does not need software to solve the problem. Trying first with a manual process might be enough until discovering more about the problem. Maybe we just to gather data and postpone the decision for the future when we are in a better position.</p>

<p>Probably, we do not want to make that thinking process alone. What if instead of just developers or CTOs, product managers and stakeholders, we were able to speak about problems together? Again this is not something new, Agile manifesto, fourth principle:</p>

<blockquote>
  <p><strong><em>Business people and developers must work together daily throughout the project</em></strong>.</p>
</blockquote>

<p>This might look basic stuff but companies get lost with this kind of reasoning.</p>

<p>As my last reflection/open question, are we the responsible of being detached of the problems? Do we put too much focus on technology and that blinds us for what it matters that is helping people? Would we be able to assume the leadership of this matter?</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><summary type="html"><![CDATA[IMHO CTOs, product managers and stakeholders should stop offering solutions and start talking about problems. Have you found yourself in a situation like this one?: “Hey buddy we need to do X, Y, Z.”]]></summary></entry><entry><title type="html">AWS Solution Architect Associate Exam Notes</title><link href="https://elcaminodeunaprendiz.com/posts/aws-solution-architect-associate-exam-notes/" rel="alternate" type="text/html" title="AWS Solution Architect Associate Exam Notes" /><published>2019-12-08T15:00:00+00:00</published><updated>2019-12-08T15:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/aws-solution-architect-associate-exam-notes</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/aws-solution-architect-associate-exam-notes/"><![CDATA[<p>Last week I was able to pass the AWS Solution Architect Associate exam certification and I would like to share the process I followed to prepare the exam.</p>

<p>I decided to prepare the exam when my company <a href="http://www.ding.com">Ding</a> asked me if I would like to attend a course in Amazon offices about Architecting on AWS. Before attending the course I had no idea about what cloud services AWS offered, I knew only about EC2 and Lambda so yes I learnt a lot during the 5 days. Thanks to Ding for the opportunity.</p>

<p>As Sandro Mancuso mentions in his book, we the developers should own the learning path for ourselves. For that reason, I committed to knowing more about what AWS provides and how it can help developers to build products.</p>

<p>I started for signing up in a learning platform called <a href="https://acloud.guru/">A Cloud Guru</a> where it provides several courses to prepare different cloud vendor certifications. I liked the way the course is structured. The best part is they encourage you to practice a lot with the AWS console and some of the lessons are purely practical which is very good. They also have an exam simulator where you can practice and prepare for the exam.</p>

<p>After finishing the course I continued reading a few AWS whitepapers:</p>
<ul>
  <li><a href="https://d1.awsstatic.com/whitepapers/architecture/AWS_Well-Architected_Framework.pdf">AWS Well-Architected Framework</a></li>
  <li><a href="https://d1.awsstatic.com/whitepapers/AWS_Cloud_Best_Practices.pdf">AWS Cloud Best Practices</a></li>
  <li><a href="https://d1.awsstatic.com/whitepapers/AWS_Serverless_Multi-Tier_Architectures.pdf">AWS Serverless Multi-Tier Architectures</a></li>
</ul>

<p>From the multiple AWS cloud services, I would say that the most relevant for the exam are <strong>S3</strong>, <strong>EC2</strong>, <strong>RDB</strong>, <strong>DynamoDB</strong>, <strong>ELB</strong>, <strong>EBS</strong> and <strong>VPC</strong>. Reading the FAQ for these services will give you an overview of the purpose of the services and how they work.</p>

<p>Another important point is that you should be able to create from scratch a VPC with Subnets, Internet Gateways, NAT instances / NAT Gateways and Route tables. That is only possible with practice with the AWS Console or the AWS CLI.</p>

<p>During the almost two months of preparation, I took some notes to study the multiple services. The notes are mostly extracted from A Cloud Guru platform and the FAQ of each service:
<a href="https://github.com/gabrielmoral/aws-solution-architect-associate-exam-notes">AWS Solution Architect Associate Exam Notes</a></p>

<p>I imagine the notes will get obsolete at some point since AWS changes very fast the services in the platform, although the fundamentals should not change too much.</p>

<p>As my final advise, do not focus just on getting the certification done. For me, it was much more rewarding the travel through the path of learning than the actual certification.</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><category term="Certification" /><category term="Cloud" /><category term="Learning" /><summary type="html"><![CDATA[Last week I was able to pass the AWS Solution Architect Associate exam certification and I would like to share the process I followed to prepare the exam.]]></summary></entry><entry><title type="html">ShipItCon 2019</title><link href="https://elcaminodeunaprendiz.com/posts/shipitconf-2019/" rel="alternate" type="text/html" title="ShipItCon 2019" /><published>2019-09-06T08:00:00+00:00</published><updated>2019-09-06T08:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/shipitconf-2019</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/shipitconf-2019/"><![CDATA[<p>Today I’ve attended to the ShipItCon 2019 conference hosted for a second year in Dublin. The speakers mainly talk about how they and their companies deliver software into production and what practices and tools they use.</p>

<p>I’d like to highlight the two talks I liked most. Although they don’t expose the newest tech I think is interesting how understanding a few principles could help you to prevent errors in production and help to deliver software with shorter feedback loops.</p>

<p>The first one is <strong>What Breaks Our Systems: A Taxonomy of Black Swans</strong> by Laura Nolan <a href="https://twitter.com/lauralifts">@lauralifts</a>. Her presentation exposed a few major outages that big companies had and how they could have been avoided.</p>

<p><strong>Soft and hard dependencies</strong></p>

<p>She explained that most of the time when a new dependency is introduced in the software, we the developers, don’t think enough if that dependency should be hard or a soft one. For instance, she gave the example of a system that relies on an external dependency at initialization time could cause the unavailability of our software if measures are not put in place. 
Developers should take into account when adding new dependencies and thinking if the system can work without the dependency, and if it can, the software should not fail if the dependency is not available.</p>

<p><strong>Retries</strong></p>

<p>Normally when a system talks to other systems problems like connectivity and network issues might happen. A few alternatives might be retries with exponential backoff and the circuit breaker pattern. A lot of errors as oversized queues or exhausted systems might happen because retries are not well implemented. Ignoring problems in this area might lead to serious systems outages.</p>

<p>The second talk <strong>Immutable Deployments – Implementing a wicked fast deployment strategy</strong> by <a href="https://twitter.com/grandazz">@grandazz</a> is about practices to deploy software into production.</p>

<p>He talked about how the team he is part of uses <strong>feature flags</strong> for every single feature they put in production. How features flags have changed the way they make software and how their codebase is better than before having always that constraint in mind.</p>

<p>He categorised the feature flags in two categories, <strong>business and ops feature flags</strong>. The first one with a short duration in time and used by business people to decide what feature activate and when. The last is own by developers enabling them to make refactors or even deactivate features on demand.</p>

<p>Last but not least he showed how feature branches go <strong>directly to production</strong> without exposing the functionality to the final user. That allows them to make tests in production. They have also in place a way to rollback quickly because the application allows them to change between different  versions in case of any problem.</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><category term="Conferences" /><summary type="html"><![CDATA[Today I’ve attended to the ShipItCon 2019 conference hosted for a second year in Dublin. The speakers mainly talk about how they and their companies deliver software into production and what practices and tools they use.]]></summary></entry><entry><title type="html">Curso de TDD con Jason Gorman</title><link href="https://elcaminodeunaprendiz.com/posts/jason-gorman-curso-tdd/" rel="alternate" type="text/html" title="Curso de TDD con Jason Gorman" /><published>2019-02-10T08:00:00+00:00</published><updated>2019-02-10T08:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/jason-gorman-curso-tdd</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/jason-gorman-curso-tdd/"><![CDATA[<p>Hace algunas semanas tuve el placer de asistir al curso de <a href="https://twitter.com/jasongorman">Jason Gorman</a> en Londres sobre TDD. El curso no fue el típico de tres días que Jason hace <a href="http://www.codemanship.co.uk/tdd.html">normalmente</a>, sino un solo día con el primer tercio del contenido del curso.</p>

<p>El día fue muy ameno en cuanto a contenidos. Jason empezó el curso introduciendo que es TDD y explicando conceptos “básicos” (muchos decimos que ya los sabemos pero no siempre es así) como las mecánicas de TDD y por qué hacer TDD.</p>

<p>Durante el día nos dio tiempo a ver muchísimos conceptos, algunos relacionados con el diseño de los tests, diseño simple, refactorización o consejos para dar buenos nombres. Parece mucho para un solo día pero como no éramos demasiados participantes dio tiempo a verlo todo. Una de las cosas que me gustó mucho es que entre un concepto y otro había una parte práctica (parecido a una kata) para poder aplicar lo que has aprendido.</p>

<p>A continuación voy a ir comentando algunas de las prácticas y conceptos que me han parecido interesantes después de haber hecho el curso.</p>

<h3 id="diseño-de-los-tests">Diseño de los tests.</h3>

<ul>
  <li>
    <p>Un test solamente debe comprobar un ejemplo/regla y por lo tanto solo debe de fallar por un motivo.</p>
  </li>
  <li>
    <p>Al Igual que esperamos a ver la duplicación tres veces<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> para eliminarla en el código, la misma regla debería aplicar también a los tests. Tener paciencia a la hora de refactorizar los tests es importante ya que un generalización prematura podría ofuscar su significado.</p>
  </li>
  <li>
    <p>Crear generalizaciones en los tests puede ayudar a minimizar el impacto de los cambios cuando el código de producción cambia. Varios ejemplos serían crear una fachada para crear instancias de un objeto o extraer la configuración de un mock a un único lugar.</p>
  </li>
  <li>
    <p>Parametrizar los tests, siempre y cuando tenga sentido, puede ser una buena opción para incrementarla cobertura de código o hacer mutation testing.</p>
  </li>
  <li>
    <p>Al escribir un test deberíamos de empezar por la aserción y continuar completando el test hacia arriba. Esta práctica ayuda a centrarnos en lo que queremos probar y a no crear un setup innecesario.</p>
  </li>
</ul>

<h3 id="refactorizar">Refactorizar</h3>

<p>Una de las frases que mencionó Jason durante el curso y que me resultó muy reveladora:</p>
<blockquote>
  <p>Don’t leave the path. Don’t go to the deep forest.</p>
</blockquote>

<p>Quien no se ha encontrado en la fase de refactorización y cambiando un montón de código/ficheros y cuando nos damos cuenta se nos ha ido de las manos. Otra situación muy común es que no ejecutamos los test con cada pequeño cambio y después están en rojo y no sabemos a que se debe.</p>

<p>A estos dos ejemplos es a lo que se refiere la frase de Jason, es muy importante hacer commits muy pequeños durante la refactorización y ejecutar los tests muy a menudo para comprobar en todo momento que no se ha roto el código de producción.</p>

<h3 id="nombres">Nombres</h3>

<p>Una de las tareas más complicadas en programación es dar buenos nombres a las abstracciones que creamos. Para los componentes que creemos tengan una correlación conceptual con el negocio, podemos apoyarnos en herramientas como un generador de nube de tags<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>. Por ejemplo, utilizar el texto de la historia de usuario para generar tags puede ayudarnos a descubrir palabras y nombres que nos pueden ser de utilidad.</p>

<h3 id="diseño-simple">Diseño simple</h3>

<p>Otra de las cosas que hicimos fue enumerar qué es diseño simple en los siguientes puntos:</p>

<ol>
  <li>Funciona (Pasan los tests)</li>
  <li>Revela la intención</li>
  <li>Libre de duplicación</li>
  <li>Partes simples</li>
  <li>Responsabilidad única</li>
  <li>Tell don’t ask (Feature envy)</li>
  <li>Interfaces especificas por parte del cliente</li>
  <li>Intercambiable</li>
</ol>

<p>Son básicamente los mismos puntos que Kent Beck<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup> enumeró en su libro Extreme Programming con un mayor nivel de detalle.</p>

<p>Otro consejo con el que me quedo del curso:</p>
<blockquote>
  <p>Clases que crean objetos no deberían usarlos, clases que los usan no deberían crearlos.</p>
</blockquote>

<p>Para finalizar el post me gustaría recomendar el curso a todos ellos que quieran aprender TDD o quieran mejorar su técnica. A mi me resultó muy útil y volveré para completarlo si hay una segunda y tercera parte.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p><a href="http://wiki.c2.com/?ThreeStrikesAndYouRefactor">http://wiki.c2.com/?ThreeStrikesAndYouRefactor</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p><a href="https://www.jasondavies.com/wordcloud/">https://www.jasondavies.com/wordcloud/</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p><a href="https://martinfowler.com/bliki/BeckDesignRules.html">https://martinfowler.com/bliki/BeckDesignRules.html</a> <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Gabriel Moral Ortiz</name></author><category term="Aprendizaje" /><category term="TDD" /><summary type="html"><![CDATA[Hace algunas semanas tuve el placer de asistir al curso de Jason Gorman en Londres sobre TDD. El curso no fue el típico de tres días que Jason hace normalmente, sino un solo día con el primer tercio del contenido del curso.]]></summary></entry><entry><title type="html">Designing Data-Intensive Applications. Chapter 8</title><link href="https://elcaminodeunaprendiz.com/posts/designing-data-intensive-applications-chapter-8/" rel="alternate" type="text/html" title="Designing Data-Intensive Applications. Chapter 8" /><published>2019-02-03T08:00:00+00:00</published><updated>2019-02-03T08:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/designing-data-intensive-applications-chapter-8</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/designing-data-intensive-applications-chapter-8/"><![CDATA[<p>So far, this chapter is the most depressing and pessimistic until now. Which is also good because it helps us to realise that not all is a bed of roses in distributed systems. Martin Kleppmann explains <strong>The Trouble with Distributed Systems</strong> and why it is naive to think that faults are the exception. For that reason, we should consider a range of possible faults such as <strong>Unreliable Networks</strong> or <strong>Unreliable Clocks</strong>.</p>

<h3 id="unreliable-networks">Unreliable Networks</h3>

<p>In shared-nothing systems, the network is the only way machines can communicate between themselves. The network cannot guarantee when a message will arrive or even if it will arrive at all. A few things can go wrong:</p>

<ul>
  <li>The request has been lost.</li>
  <li>The request may have been queued and will be delivered later.</li>
  <li>The remote node has failed.</li>
  <li>The remote node may have temporarily stopped responding.</li>
  <li>The remote node may have been processed the request but the response has been lost on the network.</li>
  <li>The remote node may have been processed the request but the response has been delayed and will be delivered later.</li>
</ul>

<p>These issues are impossible to identify, you only know you have not received a response. The usual way of handling that is through <strong>timeouts</strong>. With timeouts, some questions arise, i.e. how long the timeout should be? should we retry after a while?</p>

<h3 id="unreliable-clocks">Unreliable Clocks</h3>

<p>The communication in distributed systems is tricky because sometimes is not immediate, it takes time for a message to reach the destination machine.</p>

<p>Moreover, each machine on the network has its own clock, which is not a perfectly accurate hardware component. The most common option to synchronize clocks is Network Time Protocol (NTP) where the clock adjusts taking into account the time reported for a group of servers. Although, there are more reliable options like GPS receivers.</p>

<p>The methods for getting a clock to tell the right time are no accurate or reliable as we might think. But it is also true that most data processing systems do not need real-time guarantees. The effort to build it taking those details into account may be neither appropriate nor economical.</p>

<p><br /></p>

<p>In summary, a distributed system cannot rely on a single node because that node can fail unexpectedly. Distributed systems rely on quorum algorithms. The nodes need an absolute majority of more than half of them to take a decision (there are other kinds of quorums). For instance, even if a quorum decides that a node is dead the node will be declared dead, even although the node is still alive.</p>

<p><img src="https://elcaminodeunaprendiz.com/assets/chapter8.map.jpg" alt="Chapter 8 map" />
Provided by <a href="https://twitter.com/mintxelas" target="_blank">@mintxelas</a></p>

<p><a href="/posts/designing-data-intensive-applications-chapter-7/">&lt;- Chapter 7. Transactions</a></p>]]></content><author><name>Gabriel Moral Ortiz</name></author><category term="data-intensive-applications" /><category term="book" /><summary type="html"><![CDATA[So far, this chapter is the most depressing and pessimistic until now. Which is also good because it helps us to realise that not all is a bed of roses in distributed systems. Martin Kleppmann explains The Trouble with Distributed Systems and why it is naive to think that faults are the exception. For that reason, we should consider a range of possible faults such as Unreliable Networks or Unreliable Clocks.]]></summary></entry><entry><title type="html">Designing Data-Intensive Applications. Chapter 7</title><link href="https://elcaminodeunaprendiz.com/posts/designing-data-intensive-applications-chapter-7/" rel="alternate" type="text/html" title="Designing Data-Intensive Applications. Chapter 7" /><published>2019-01-26T08:00:00+00:00</published><updated>2019-01-26T08:00:00+00:00</updated><id>https://elcaminodeunaprendiz.com/posts/designing-data-intensive-applications-chapter-7</id><content type="html" xml:base="https://elcaminodeunaprendiz.com/posts/designing-data-intensive-applications-chapter-7/"><![CDATA[<p>In this chapter the author deeps in the world of transactions. <strong>Transactions</strong> have been for decades the mechanism of choice for simplifying:</p>
<ul>
  <li>Databases failures.</li>
  <li>Network interruptions.</li>
  <li>Application crashes.</li>
  <li>Race conditions.</li>
</ul>

<h3 id="acid">ACID</h3>

<p>It is important to define what ACID means since it is used to describe the safety guarantees provided by transactions.</p>

<p><strong>Atomicity</strong> is the ability to abort a transaction on error have all the writes from that transaction discarded.</p>

<p><strong>Consistency</strong> is in part relied on the application to preserve certain statements about the data (invariants). Specific invariants can be checked by the database, e.g., foreign keys.</p>

<p><strong>Isolation</strong> means that concurrent transactions are isolated from each other. Each transaction can pretend that is the only one running on the database.</p>

<p><strong>Durability</strong> promises that one the data has been committed successfully, the data will remain there.</p>

<p>It is worth to mention that ACID implementations are different in each database vendor.</p>

<h3 id="weak-isolation-levels">Weak Isolation Levels</h3>

<p>Databases have tried to hide concurrency problems from application developers by providing <em>transaction isolation</em>. In practice, it is not that simple. There is a level of isolation called <em>Serializable isolation</em> that comes with the price of worst performance. For that reason database systems implement weaker levels of isolation.</p>

<h4 id="read-committed">Read Committed</h4>

<ul>
  <li>Reading will only read data already committed (no dirty reads).</li>
  <li>Writing will only override data already committed (no dirty writes).</li>
</ul>

<p>Commonly databases prevent dirty writes using row-level lock where only one transaction can hold the lock for a given object.</p>

<p>Most databases avoid dirty reads remembering the old committed value and the new value for a written object. Having that, the database can provide the old value for reads until the new value is committed.</p>

<p>It is the default option in Oracle 11g, PostgreSQL, SQL Server 2012, MemSQL.</p>

<h4 id="snapshot-isolation">Snapshot isolation</h4>

<p>With Snapshot isolation level transactions read from a consistent snapshot of the database. This technique avoids other transactions to see data that is changed by another transaction, each transaction sees only the old data from that particular point in time.</p>

<h4 id="preventing-lost-updates">Preventing Lost Updates</h4>

<p>The lost update problem can happen when the application reads a value from the database and modifies it. If two transactions do this concurrently, one of the updates might be lost because the second update does not have the first modification.</p>

<p>In order to avoid this issue a few solutions can be applied:</p>

<ul>
  <li>Atomic write operations avoid the necessity of reading first from the database to modify a value.</li>
  <li>The application can lock the objects that are going to be modified rejecting the second update.</li>
</ul>

<h3 id="serializability">Serializability</h3>

<p>Serializable isolation is the strongest isolation level. It guarantees even transactions run in parallel, the result will be as if they had executed one at a time. All the race conditions are prevented by the database.</p>

<p>Most of the databases today implement serializable isolation use one of these techniques:</p>

<ul>
  <li>Executing transactions in a serial order (Actual Serial Execution).</li>
  <li>Two-phase locking.</li>
  <li>Optimistic concurrency control techniques such as serializable snapshot isolation (SSI).</li>
</ul>

<p>Since this post only touches the surface of the book chapter. I would encourage you to read the full book chapter to understand better how transactions work behind the scenes.</p>

<p><img src="https://elcaminodeunaprendiz.com/assets/chapter7.map.jpg" alt="Chapter 7 map" />
Provided by <a href="https://twitter.com/mintxelas" target="_blank">@mintxelas</a></p>

<p><a href="/posts/designing-data-intensive-applications-chapter-6/">&lt;- Chapter 6. Partitioning</a></p>

<p style="text-align: right">
<a href="/posts/designing-data-intensive-applications-chapter-8/">Chapter 8. The Trouble with Distributed Systems -&gt;</a>
</p>]]></content><author><name>Gabriel Moral Ortiz</name></author><category term="data-intensive-applications" /><category term="book" /><summary type="html"><![CDATA[In this chapter the author deeps in the world of transactions. Transactions have been for decades the mechanism of choice for simplifying: Databases failures. Network interruptions. Application crashes. Race conditions.]]></summary></entry></feed>