vineri, 12 decembrie 2025

 <optimization>

Assume you have several Docker containers running PostgreSQL — for example, postgres1, postgres2, and so on — and you want to dump their databases and copy them to another server. Doing this manually for each container quickly becomes tedious. Here’s a streamlined approach I use.

Instead of dumping each container manually, combine docker exec with xargs to iterate over them:

docker ps --filter "name=postgres" --format "{{.Names}}" | xargs -I {} docker exec {} pg_dumpall -U postgres > {}.sql

You can then use xargs with scp to transfer all dumps efficiently:

ls postgres*.sql | xargs -I {} scp {} user@remote-server:/path/to/dumps/

 

How I tracked down a thread block that looked like a database problem

 <method>

Recently I had a web application that behaved as if it were quietly freezing from the inside out. Threads were piling up, each one waiting forever, never terminating, like cars stuck behind an invisible traffic light that never turns green.

At first glance, the symptom looked straightforward: the threads were blocked at the database level. They were trying to update a table, couldn’t acquire a lock, and ended up waiting indefinitely. Because only operations related to a single element were stuck, I assumed it wasn’t a full table lock but a row lock. Unfortunately, I couldn’t confirm this, because by the time I saw the issue, the application had already been restarted, clearing all locks.

Still, the database block felt like a consequence, not the root cause. My job was to find the first thread that got stuck. That original thread triggered the row lock; all other threads simply joined the queue behind it.

So I needed a way to reconstruct the story from logs alone.

My method was simple:

  1. Export all logs from Graylog for the timeframe into a CSV.
  2. Instead of analysing it with Python/Pandas, I chose a quicker path: upload the CSV into a Postgres table with matching columns.
  3. Query the table to find the last time each thread wrote a log line. If a thread is blocked, you stop seeing it. And there it was: the first thread that went silent.
  4. Check what endpoint it called and with what parameters. And the second voilà: the request was trying to move a folder under itself.
  5. In parallel I checked the endpoint code with Cursor, and it clearly showed several recursive branches that could loop forever.
  6. Reproduce: call the endpoint with parameters that move a folder under itself. Instant block.
  7. Fix: add validation to prevent this. 

Momentul Contradicției: Punctul în Care Începe Învățarea

Necesitatea… dacă ai o necesitate, vrei să te miști și înveți.
Dacă n-ai necesitate, nu vrei să te miști din starea în care ești și nu înveți.

E una când povestești, dar când exersezi ajungi la momentul contradicției, când ceea ce știi nu te mai ajută să rezolvi ceva.
Prima reacție e că te enervezi.
Dar dacă continui, te forțezi să te schimbi, să faci o modificare sau o acumulare.

When Learning Jumps Levels: Rethinking the Path from Simple to Advanced

I often say that with complex topics, we need to approach them step by step, so that the reader understands how we arrived there: from simple to complex, just as one of the core principles of education suggests, where sequencing matters.
And indeed, the order does matter. But it seems to me that sometimes certain concepts, even though they are more advanced than earlier ones and should logically come later, might actually represent the start of a different stage of thinking and therefore could deserve to be introduced first.

I often think about this: when a problem appears, the first solution that comes to mind is usually the trivial one. But sometimes it would be better if the advanced, optimal solution came to mind first.

***

 From https://youtu.be/X1HSGEADAhE?t=1573 : 

***

We even teach student programmers in their first years, when they still don’t understand what programming is and are seeing a computer for the first time. Many of them we teach to program in C or C++.

And then, once they’ve learned C or C++, a year or two passes, and in their third or fourth year, or even later when they’ve already become programmers, we start retraining or further educating them in proper design.

We tell them:
"You know, objects are actually certain entities, certain abstractions inside your program. And these objects should have the property of encapsulation. They should hide information."

The programmer—well, the C-style programmer—looks at this and it’s all new to them.
"What do you mean, hide information? How is it that they should encapsulate data and not expose it?"

Well, in C, everything is exposed. In C, there’s global state basically everywhere.
Sure, it’s not encouraged, but people still do it. Global variables are a common practice.

And suddenly, in their third or fourth year—or even in their fifteenth year of working as a programmer—they’re told that everything should have been done differently in OOP. And that’s the problem.

So Richard proposes:
"Let’s introduce them to OOP in the first year—before we even teach them how to program, before they write their first program. Let’s explain what OOP is, why objects are needed, what encapsulation and polymorphism are."

He believes they can understand it—even if it’s with sticks and pictures, with some auxiliary or educational languages.

***