If you’ve ever tried to publish messages to Kafka or NATS right after writing to a database, you’ve probably run into that uncomfortable question: “What if the DB transaction succeeds, but the message publish fails?” This is one of those…
Most Saga tutorials either stop at “call service A then service B” or gloss over the annoying parts (async replies, idempotency, correlation, compensations). This post doesn’t. We’ll wire up: We’ll simulate a checkout The workflow publishes commands like cmd.payment.reserve. Services…
When building microservices, business transactions often span multiple services. For example, in an e-commerce system: Order Service → creates and manages orders. Payment Service → processes payments or holds funds. Inventory Service → reserves or releases stock. Shipping Service →…
Testing is a critical aspect of software development, ensuring code reliability, maintainability, and performance. In the Golang ecosystem, a variety of testing frameworks have emerged, each offering unique features and capabilities that cater to different needs. As a backend engineer…
Additional test packages Test files can declare an additional test package, matching the source files package with _test appended. Using the dedicated test package brings the following advantages:1. Prevents brittle tests: Restricting access to only exported functionality does not give…
Types of automated tests Automated testing suites involve tools and frameworks to verify the behavior of software systems. They provide a repeatable way of verifying system requirements. We divide them into several types of tests according to three criteria: System…
Every program is a set of instructions, whether it’s to add two numbers or send a request over the internet. Compilers and interpreters take human-readable code and convert it to computer-readable machine code. https://www.freecodecamp.org/news/compiled-versus-interpreted-languages/ Compiler Compilers will translate developers’s whole…
What Is Bytecode? Bytecode (also called portable code or p-code[citation needed]) is a form of instruction set designed for efficient execution by a software interpreter. The name bytecode stems from instruction sets that have one-byte opcodes followed by optional parameters. It’s not readable by a human programmer like source…
Recover is a built-in function that regains control of a panicking goroutine. If the current goroutine is panicking, a call to recover will capture the value given to panic and resume normal execution. Recover is only useful inside deferred functions. During…
The purpose of functions and subroutines is to save time and space by just calling a function/subroutine. Subroutines do not return any values, while functions return values. Subroutines are also allowed to change the values of the parameters while functions are supposed…