- 3 Minutes Wednesdays
- Posts
- Tricky Parts of Async Mirai Magic
Tricky Parts of Async Mirai Magic
Remember how I bamboozled Excel users with my cool PDF automation?
If you want to pull that off too, check out my freshly released "Report Automation With Typst" course.
Moin Moin! š
Many Greetings from Munich, Germany (using a greeting from the North of Germany š¤Ŗ). Let us finish our journey from last week. Today, weāre going to unravel how to prepare your Mirai daemons so that they can use database connections.
How Database Connections Fail
We start by investigating what kind of problem we have. Thatās always a good start. After all, you probably donāt want to take my word for it. So hereās an example.
Imagine you have a database connection. Here, this will just be a connection to a local database stored in a .sqlite file. But it doesnāt matter whether we use SQLite or Postgres or something else. Itās always the same issue.

Cool, weāve got a local database. It even has our favorite penguin data stored inside of it. Thatās nifty. But letās have a look at what Mirai does when we try do use our database connection:

Loading Generics
Ahh thatās annoying. We passed our con variable into the Mirai worker like we learned last time but we still get an error. Here, the error signals that R does not know a function dbListTables() for a SQLiteConnection.
This happens even though the full function reference (using DBI::) is used. The reason for that is that the {RSQLite} package is not loaded in the worker. You see, DBI::dbListTables() is a generic function. This means that it behaves differently depending on what you stick into it.
And if you create your own type of database connection (you know, like a SQLiteConnection). Then youāll also have to tell DBI::dbListTables() how to behave with that type of connection. And thatās what happens in the package that created that object. So we can use everywhere() like last time to load the package on all Mirai workers:

Fixing bad pointers
Two things we can notice from this:
Nice: We made some progress. š„³
Not so nice: We get a different type of error. š
To understand whatās going on here, we have to understand how database connections work. The thing is: A variable like con comprises out of a lot of things:

And one of these things is an external pointer to some address in the memory of my computer.

In simplified terms, this address is where the actual engine that talks to the database lives. Unfortunately, the Mirai workers cannot reach the address that this pointer is pointing to. So that is why we get the bad pointer error message.
Establishing a new connection per worker
One way to fix that could be to simply call db::dbConnect() within the Mirai worker. Letās try this out in combination with mirai_map().

Nice! This approach works and in the results you can see that we manage to successfully list our āpenguinsā table.
Iāve also taken the liberty of extracting the address of the database pointer. As you can see, this is a different one in each iteration. Youāll have to be careful there and evaluate if thatās what you want. Your database might not like to be flooded with lots of connections.
Alternatively, you could use everywhere() in combination with the magical <<- assignment operator. This one assigns variables outside the confinement of the calling environment. Thatās how you can persist the same connection for all workers:

See how these pointers always have the same address? Thatās what you get with everywhere() here. But (once again) youāll have to decide if thatās what you want. Now, connections are not isolated anymore and when you work with database transactions, this may or may not cause problems for you. So as always: itās a tradeoff.
Either way, you now have a way to successfully use generics and pointy objects with Mirai. Thatās something, isnāt it? Hope you enjoyed this weekās newsletter. As always, feel free to hit the reply button to share your thoughts.
Happy Coding and see you next week,
Albert
Whenever youāre ready, there are three I can help you:
Automate Your Data Reports: This course helps data analysts eliminate manual copy-paste reporting by automating PDF reports end-to-end, saving hours every cycle and preventing costly mistakes. (Using the lovely Typst language š)
Generate Insights in Minutes, not Hours: This comprehensive course teaches you to handle data faster, smarter, and more efficiently.
Bespoke Data Science Solutions: Iāve helped clients build their own data science solutions. Whether building custom web apps, PDF reports, AI automations or teaching workshops, Iāve got you covered. You can reach out to me via this form (or simply hit reply to this email)
Reply