About Me
Felipe Fernández
- Work as Software Craftsman for Codurance
- Currently with Crowdmix
- Blog: http://codurance.com/blog/author/felipe-fernandez
- Twitter: @felipefzdz
Defining delusion
“An idiosyncratic belief or impression maintained despite being contradicted by reality or rational argument, typically as a symptom of mental disorder.”
About the talk
- 1. Operations
- 2. Testing
- 3. Design
1. Operations
- Operations from a developer perspective
- Not really talking about how to keep a system up
- But how to build the infra that support that system
- Devops is not only a buzz word
- But something real if you work in a small company
Operations
I’ll have a look whenever is needed
- Overconfidence or just laziness
- It's easy just think in happy path scenarios
- But the cost of addressing that later is higher
Operations: I’ll have a look whenever is needed
Diagnosis in distributed environments
- When your tests are not enough
- You need to query the state of your system
Operations: I’ll have a look whenever is needed
Diagnosis methodologies
- Debugging
- Querying datastores
- Logging
- Easy to do it in a non-clustered syncronous monolith with a well known single datastore
- Explain how to do it in monolith
Operations: I’ll have a look whenever is needed
Distributed diagnosis methodologies
- Debugging -> LOL
- Querying datastores -> Fragmentation
- Logging -> Madness
- Forget about debuggers, anyway, it was never a good idea in production
- Don't store stuff in binary.
- Be sure that you master you clients, you don't want to learn those when the fire is on
- Centralised logging
- Correlations Ids
Operations
I’ll have a look whenever is needed
Please don't, it could be really hard and you want to be prepared
Operations
I need to remove that duplication NOW
- Duplication hurts if you care about your code
- DRY is a well know design principle
- But addressing duplication prematurely causes pain
Operations: I need to remove that duplication NOW
Generalising deployment pipelines
- DIY deployment pipelines
- Microservices context
- If you tailor your own scripts and integrations is likely that duplication will arise soon
- But if you are in a microservices context you want some kind of flexibility
- So don't go with convention over configuration until you're stable
Operations: I need to remove that duplication NOW
Generalization assumptions
- Versioning
- Checking
- Continuous integration
- You can assume that your version information relies in the same structure of your project
- But you can decide in the future use different submodules strategies or even build systems
- Not every deployable unit has a health rest endpoint to check if is up and running
- Not every deployable unit has the same needs from a CI point of view
Operations
I need to remove that duplication NOW
Do it when you're stable enough
- Twitter example. Let 1000 thousand flowers bloom
Operations
I guess that is ready
Operations: I guess that is ready
Creating real walking skeletons
- That includes provisioning and deploying
- Smoke test as driver
- Let's talk about what is a walking skeleton
- If you only care about the application code you're not really doing it
- First test should be a real black box test.
Operations: I guess that is ready
GOOS Philosophy
- Address your non-functional challenges asap
- Antidote against technical debt
- Include non-functional concerns in your definition of done
- If you start from there you will figure out if your architecture is hard to test
- If it's hard to test you know what you have to do
Operations
I guess that is ready
Don't guess, double check
Testing
The parts are working, so the whole
- A system is not only the sum of its parts
- Integration is full of caveats
Testing: The parts are working, so the whole
Distributed testing
Don't give up on unit testing
But that's not enough
- The combinatorial explosion of not using unit tests is simply not feasible
- There are too many branches in almost any system and the overlapping can kill you
- But being confident is your unit tests is not enough
Testing: The parts are working, so the whole
Contract testing
Start designing your APIs with respect
The customer is always right
- You can't enforce compile safety about the dispatch of those messages
- It's not only the bugs introduced by developers, but the unrealiability of networks
Testing: The parts are working, so the whole
Smoke testing
We need more than a red test
Centralised logging and correlation ids
- When a smoke test fails in a distributed environment, you don't really know if the test is flaky or production code is broken.
- Investigating logs is painful or even impossible without correlation ids or centralised logging.
- You lose the defect localisation of fine grained unit tests so you have to be more clever than before.
Testing
The parts are working, so the whole
Don't understimate the complexity of distributed systems
Testing
Testing is always good
- Most of developers that loves programming loves testing
- But they don't come for free
- Be aware of the trade-offs of every approach
Testing: Testing is always good
Testing trade-offs
- Micro unit tests
- Slow tests
- Hard to read/write tests
- Tests that are too coupled to implementations are brittle. If you change the implementation of some behaviour tests fail even the behaviour is the same
- Slow feedback kills TDD flow and in the end the love for testing of the developers
- As an example, tests that uses json are painful to read and write
Testing: Testing is always good
Trade-offs are just trade offs
- Micro unit tests
- Slow tests
- Hard to read/write tests
- Unit tests provides pressure on your design, gives you defect localisation and forces you to do baby steps.
- Integration tests are inherently slow and still they're useful
- It could make sense to include json in your back-end acceptance tests if you want to use them as communication tool with your front-end developers
Testing
Testing is always good
As long as you understand the trade-offs
3. Design
- Design is the key of mantainable systems
- It's hard to say if you're over engineering
- In the end we want to deliver features
- But easy is not simple
Design
Language approximations are ok
- We know that writing an email cand be hard if we want to be precise
- Our code is an email that is going to be read it tons of time in the future
- Let's move the work then to the single writer not to the miriad of readers
Design: Language approximations are ok
Bounded Contexts
Core DDD concept
Impact mapping or even Event Storming can help you to identify them
- When you have contexts with tightly coupled concepts the mess starts
- You don't need to go to nano services, so there is not golden rule, but the judgement of the team
- Once you split them, be aware of the subtle similarities
- A UserId in service A, could be a userIdFromServiceA in service B
Design: Language approximations are ok
Hexagonal Architecture
- Split between core and infrastructure
- Stop thinking in layers
- Check your imports to see if there is IO libraries into your core
- Useful not only because you maybe want to change your rest layer in the future, but because your domain is free
of library/framework restrictiosn
- Ports and adapters is much easier to explain to a newbie than MVC or layered architectures
Design
Language approximations are ok
Often I think that our profession is closer to literature than maths
Design
Business needs are stable
- The point of Agile is fighting against that naive thought
- Your design should be flexible too, not only your processes
Design: Business needs are stable
CQRS
- Split your command and queries
- Thay makes your entities focused
- More over that gives flexibility, as we can add different queries (views) on demand
Design: Business needs are stable
CQRS
Extremely perfomant
Adds overhead
- Don't use it unless your domain is really rich
- Or your scalability needs are demanding
Design
Business needs are stable
That's not true. Design with that in mind.
Delusion Driven Development
And why you shouldn't do it
Created by Felipe Fernández / @felipefzdz