Ephes Blog

Miscellaneous things. Mostly Weeknotes and links I stumbled upon.

Date -

Weeknotes 2025-04-28

, Jochen
You can tell the Old Testament is the product of a desert people, because when they tried to imagine the end of the world they went with “rained for forty days and forty nights”, which in Ireland is just called Spring. --Simon McGarr

Attending DjangoConEU 2025

Last week I headed to DjangoCon Europe 2025 in Dublin, and it was fantastic. I met some wonderful people and had countless fascinating conversations. Since all the Python Podcast hosts were there with their audio gear, we pulled off the impressive feat of recording an episode every single day (day1, day2, day3) – and actually got them published within 24 hours of recording. We set up shop in the hotel lobby, initially worried about background noise, but Auphonic worked so well at filtering that I actually had to dial back the settings to keep some of the atmosphere in the recordings! I also got to watch another podcast being recorded at the conference, which was eye-opening. It was honestly surprising to see how differently various people approach the same task.

Dublin itself is a captivating city, and we managed to explore quite a bit. Here's something interesting: after chatting with other attendees, I discovered I'm not alone in finding software development work challenging right now (except for one person who never missed a chance to remind me they're probably the notable exception to the rule – you know who you are!). The tech market seems to be in a rough patch at the moment. At least I got some validation that it's not just me struggling.

Monitoring Pet Project

I haven't had time for much "vibe coding" on my monitoring pet project, but I've been thinking about the architecture, which is almost as good. Monitoring is essentially about waiting for I/O. You periodically poll the database to see which checks to run next, make HTTP requests (or other network calls) to actually perform those checks, and write the results back to the database.

The most straightforward way to handle I/O waiting in Python is using async functions and coroutines with an event loop. But here's the catch: you can only await async functions from within another async function. The problem is that most of my business logic – like deciding whether to run a check or determining if a failed check means a service should be marked as down – doesn't benefit from being async at all. In fact, it would be cleaner to keep the core domain logic synchronous and only use async for actual I/O operations.

So here's what I really want: a sync core for business logic that deals with the monitoring domain, with all the async I/O hidden behind adapters. But this raises a tricky question: how do you call async adapters from sync domain code?

There's another practical consideration: I'll likely want to build a Django dashboard at some point, and integrating synchronous business logic with Django is much more straightforward.

My plan involves using anyio for I/O since I want the flexibility to switch async backends later. Anyio has this neat concept called "portals" that let you run async code in another thread's event loop. Here's my current plan:

  1. Use dependency injection to provide a blocking portal to any event or command handlers that need it
  2. Keep all handlers synchronous, but allow them to pass the portal to adapters
  3. Let adapters run async code using the portal – either waiting for completion with portal.call() or fire-and-forget with portal.start_task_soon()
  4. When async adapters need to call business logic, they can do so directly (since calling sync business logic from async code should be fine)

This approach seems like a clean way to keep my domain logic simple while still leveraging async for I/O efficiency.

Articles

Software

Fediverse