This one is a bit more of a mini-tutorial than my other #golang tips and was very popular. Some great further discussion in the comments too.
Now available on https://t.co/oWZs2sn5s0
Diving deeper into #golang, I stumbled upon the surprising nuances of nil ๐คฏ. It tripped me up for a bit, so here's a quick tip that might help someone else! #golangtips
Just wrote my first-ever article! To-do apps become surprisingly complex when you add in recurring tasks/schedules ๐ https://t.co/eOZFCNquIG
#systemsdesign#database
๐ Made my first open-source contribution to the #Laravel Adjacency List package! ๐ The enhancement adds support for customized precision & scale for decimal columns, preventing SQL errors. Grateful for the opportunity to contribute! https://t.co/r5Q7LkVfXn
#Laravel Tip: Simplify eager loading with Laravel's withDefault() method. ๐ Load relationships and provide default values if the related model does not exist.
#Laravel Tip: ๐ก Cool vs. Useful! ๐ While the ?? operator is cool, the data_get helper in @laravelphp is more useful. ๐ Simplify null value handling and access complex data structures effortlessly. Boost code efficiency with data_get!
Laravel Precognition is ready to predict the future! ๐ง
Easily add real-time validation to your JS + Inertia powered Laravel apps without duplicating your validation logic on the front-end.
If you're using Livewire this is already easy for you. ๐
https://t.co/QSa2RT7bsq
One of my Laravel โจ best practices โจ is only using the 7 "restful" methods in my controllers.
Controllers only have: index, show, create, store, edit, update, delete.
Think you need another method? You really need another controller. Built *all* of Vapor like this.
Starting a new Laravel project? Add this to your AppServiceProvider. Your future self will thank you ๐
โจ No lazy loading
๐ซ Exceptions when assigning non-fillable attributes
๐ป Prevents accessing attributes that weren't retrieved or didn't exist
Some thoughts on ๐ฅ๐ฒ๐ฎ๐ฑ๐ถ๐ป๐ด ๐๐ฎ๐๐ฎ from ๐๐ฎ๐ณ๐ธ๐ฎ.
Kafka is an extremely important ๐๐ถ๐๐๐ฟ๐ถ๐ฏ๐๐๐ฒ๐ฑ ๐ ๐ฒ๐๐๐ฎ๐ด๐ถ๐ป๐ด ๐ฆ๐๐๐๐ฒ๐บ to understand, last time we covered Writing Data.
๐ฆ๐ผ๐บ๐ฒ ๐ฟ๐ฒ๐ณ๐ฟ๐ฒ๐๐ต๐ฒ๐ฟ๐:
โก๏ธ Clients writing to Kafka are called ๐ฃ๐ฟ๐ผ๐ฑ๐๐ฐ๐ฒ๐ฟ๐.
โก๏ธ Clients reading the Data are called ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ๐.
โก๏ธ Data is written into ๐ง๐ผ๐ฝ๐ถ๐ฐ๐ that can be compared to tables in Databases.
โก๏ธ Messages sent to ๐ง๐ผ๐ฝ๐ถ๐ฐ๐ are called ๐ฅ๐ฒ๐ฐ๐ผ๐ฟ๐ฑ๐.
โก๏ธ ๐ง๐ผ๐ฝ๐ถ๐ฐ๐ are composed of ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป๐.
โก๏ธ Each ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป is a combination of and behaves as a write ahead log.
โก๏ธ Data is written to the end of the ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป.
โก๏ธ Each ๐ฅ๐ฒ๐ฐ๐ผ๐ฟ๐ฑ has an ๐ข๐ณ๐ณ๐๐ฒ๐ assigned to it which denotes its order in the ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป.
โก๏ธ ๐ข๐ณ๐ณ๐๐ฒ๐๐ start at 0 and increment by 1 sequentially.
๐ฅ๐ฒ๐ฎ๐ฑ๐ถ๐ป๐ด ๐๐ฎ๐๐ฎ:
โก๏ธ Data is read sequentially per partition.
โก๏ธ ๐๐ป๐ถ๐๐ถ๐ฎ๐น ๐ฅ๐ฒ๐ฎ๐ฑ ๐ฃ๐ผ๐๐ถ๐๐ถ๐ผ๐ป can be set either to earliest or latest.
โก๏ธ Earliest position initiates the consumer at offset 0 or the earliest available due to retention rules of the ๐ง๐ผ๐ฝ๐ถ๐ฐ (more about this in later episodes).
โก๏ธ Latest position initiates the consumer at the end of a ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป - no ๐ฅ๐ฒ๐ฐ๐ผ๐ฟ๐ฑ๐ will be read initially and the ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ will wait for new data to be written.
โก๏ธ You could codify your consumers independently, but almost always the preferred way is to use ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ๐.
๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ๐:
โก๏ธ ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ is a logical collection of clients that read a ๐๐ฎ๐ณ๐ธ๐ฎ ๐ง๐ผ๐ฝ๐ถ๐ฐ and share the state.
โก๏ธ Groups of consumers are identified by the ๐ด๐ฟ๐ผ๐๐ฝ_๐ถ๐ฑ parameter.
โก๏ธ ๐ฆ๐๐ฎ๐๐ฒ is defined by the offsets that every ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป ๐ถ๐ป ๐๐ต๐ฒ ๐ง๐ผ๐ฝ๐ถ๐ฐ is being consumed at.
โก๏ธ ๐ฆ๐๐ฎ๐๐ฒ of ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ๐ is written by the ๐๐ฟ๐ผ๐ธ๐ฒ๐ฟ (more about this in later episodes) to an internal ๐๐ฎ๐ณ๐ธ๐ฎ ๐ง๐ผ๐ฝ๐ถ๐ฐ named __๐ฐ๐ผ๐ป๐๐๐บ๐ฒ๐ฟ_๐ผ๐ณ๐ณ๐๐ฒ๐๐.
โก๏ธ There can be multiple ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ๐ reading the same ๐๐ฎ๐ณ๐ธ๏ฟฝ๏ฟฝ๏ฟฝ ๐ง๐ผ๐ฝ๐ถ๐ฐ having their own independent ๐ฆ๐๐ฎ๐๐ฒ๐.
โก๏ธ Only one ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ per ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ can be reading a ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป at a single point in time.
๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ ๐ง๐ถ๐ฝ๐:
โ๏ธ If you have a prime number of ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป๐ in the ๐ง๐ผ๐ฝ๐ถ๐ฐ - you will always have at least one ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ per ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ consuming less ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป๐ than others unless number of ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ๐ equals number of ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป๐.
โ If you want an odd number of ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป๐ - set it to a ๐บ๐๐น๐๐ถ๐ฝ๐น๐ฒ ๐ผ๐ณ ๐ฃ๐ฟ๐ถ๐บ๐ฒ ๐ก๐๐บ๐ฏ๐ฒ๐ฟ.
โ๏ธ If you have more ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ๐ in the ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ then there are ๐ฃ๐ฎ๐ฟ๐๐ถ๐๐ถ๐ผ๐ป๐ in the ๐ง๐ผ๐ฝ๐ถ๐ฐ - some of the ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ๐ will be ๐๐ฑ๐น๐ฒ.
โ Make your ๐ง๐ผ๐ฝ๐ถ๐ฐ๐ large enough or have less ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ๐ per ๐๐ผ๐ป๐๐๐บ๐ฒ๐ฟ ๐๐ฟ๐ผ๐๐ฝ.
--------
Follow me to upskill in #MLOps, #MachineLearning, #DataEngineering, #DataScience and overall #Data space.
Also hit ๐to stay notified about new content.
๐๐ผ๐ปโ๐ ๐ณ๐ผ๐ฟ๐ด๐ฒ๐ ๐๐ผ ๐น๐ถ๐ธ๐ฒ ๐, ๐๐ต๐ฎ๐ฟ๐ฒ ๐ฎ๐ป๐ฑ ๐ฐ๐ผ๐บ๐บ๐ฒ๐ป๐!
Join a growing community of Data Professionals by subscribing to my ๐ก๐ฒ๐๐๐น๐ฒ๐๐๐ฒ๐ฟ.
I have used the CQRS pattern on a few different projects now.
Here's what I think about it.
Pros of CQRS:
- Single responsibility - Commands / Queries
- Decoupling
- Flexibility - Single DB, separate read/write DB, event sourcing
- Testability
Cons of CQRS:
- Complexity
- Learning curve
- Harder to debug
- Many smaller components
I want to share a few more observations.
New people on the project become productive very quickly
CQRS is about logically splitting reads and writes.
You learn to treat reads and writes differently and optimize each use case.
P.S. If you like actionable tips on .NET, consider joining my newsletter.
I write an email to 14,000+ engineers every Saturday that helps you learn software architecture and the latest .NET trends, all in 5 minutes or less.
Subscribe here: https://t.co/M6og1UeWzm
Have you used the CQRS pattern?
โก Database Tip
Recursive queries are a great solution to e.g. querying multiple levels in a tree with just one query. But you should use cycle detection otherwise your query might run forever or fail for loops in your data.
https://t.co/DaAVDMLv1N