Async programming means not waiting while tasks run in the background, while parallel programming means running multiple tasks simultaneously across different CPU cores; the mirai package enables both by running R expressions in separate processes (daemons) that can be scaled dynamically, allowing long-running computations to proceed without blocking the main R session and enabling efficient utilization of multi-core processors.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
Async & Parallel R with {mirai} | Charlie Gao | Data Science LabAdded:
Alright. It's time to announce our lab manager for today.
We are joined by Charlie.
Charlie Gao, would you like to introduce yourself?
Sure. Hi, everyone. Nice to see you all.
I'm Charlie Gao.
I'm a member of the open source team at POSIT.
And, you know, sort of icebreaker, I have on this, Conf T shirt from Seattle in twenty twenty four.
And as you can see, this is actually a participant's T shirt.
So Isabella has a green one, one of the, staff T shirts.
And and so at this the conference two conferences ago, I was a member of the ARC community, and it was really after that conference that I joined POSIT.
First, I was a contractor and and and then full time.
So what do I work on?
Well, work on sort of a number of things across open source.
So what I've been working on most recently has actually been Quarto.
So I've been actively involved in Quarti two, which is the new Rust rewrite.
That has been announced, so I'm free to sort of say that.
But as part of that, you will all be getting a collaborative editor.
Yes.
So that's been, an incredibly exciting project to be working on.
But apart from that, I'm also the creator and maintainer of a few R packages, Mirai, Nanonac, Secretbase, etcetera.
And these are all packages that are mostly written in c, actually, for high performance computing and networking.
So myself, I'm very deep into sort of async, apart from working on Mirai, which is the package I'm probably most well known for, I've also implemented modern async into packages that you all use often like Hida two and Elna.
I also maintain the yeah.
I also maintain the later package on behalf of Joan Winston.
Those are packages that they created very early on, and I've sort of taken over the maintainership as they've focused more on AI related applications.
Later powers the core event loop in Shiny and other sort of key R packages like Plumber.
And it is basically a way for different packages to cooperate with each other even though they're running at the same time.
So as you can see, I'm very much into sort of async, into sort of working on our internals, decode, and also communications.
So this is like HTTP, WebSockets, and hence my work with Shiny and now, on Quarto and the collaborative editor.
So today, I'm mostly gonna be focusing on Mirai and how to, use that for parallel and async programming.
Yes.
I would love to start with what the heck is async programming, and how is it different from parallel?
Sure.
So let me just hit that on the head very, like, straight away so we get rid you know, we cover all the sort of tech technical jargon.
Ace parallel is basically when you're running, two things at the same time.
And async is just you're not waiting around while that happens.
That is as simple as I can put it.
So let me share my screen, and I give you a concrete example of what I mean by that.
Yes, please.
Okay.
I'm gonna be sharing my whole desktop, and you see my Zoom screen, obviously.
K.
Everybody see okay with the size, or does anything need to be zoomed?
This is now is the time to let us know.
Brian says he's okay.
So if I'm if I'm typing stuff like this, is everyone not gonna be okay?
Let's see. Rest says size is okay.
I've zoomed this in already.
So this is We have some thumbs up.
Okay. If anybody needs us to stop, let us know.
We'll make it bigger.
Excellent.
So this is actually, before I even start with any code, if I just switch to the the package downside for Mirai itself, this might be if I just try and zoom this in.
Yeah. Okay.
So Mirai is sort of the main package I'm gonna be talking about today.
This is a package that I developed about three three to four years ago is when I started work on this.
So this is much more recent than any other sort of parallel code that you'll see in base R.
That code has been around for twenty to at at I'm not sure if it's thirty, but it's at least twenty years, and that hasn't changed.
So this is sort of a much more modern take on how to run our code in parallel and and and async.
Mirai, is Japanese for future for anyone who's wondering.
So this is an implementation of future.
So it's basically a computation that's gonna be ready sometime in the future, and Mirai just is future in Japanese.
So that's why it's called Mirai.
And maybe while I'm here on the website, just a digression before I get on to code.
And this is mirai dot arlib dot org.
So mirai sorry.
It's getting annoying.
So this is just mirai dot rlib dot org.
You'll see there's this ask deep wiki button, and this is on a few POSIT packages.
We use this on the Quarto site itself because Quarto is, you know, is very complicated.
It has a lot of components.
And it's this is just an easy way, for, users to ask questions.
So you can click in.
And this is sort of AI LLM powered.
There's ways to that you can use this programmatically, but, essentially, you can click in and it sort of it gives you, like, in-depth overview of, like, everything that's within Mirai, like its documentation and its functions.
But the great thing is you you you drop straight into this sort of chat box that you see here.
Right?
And you can ask any question that you have about Mirai.
So even after this lab is complete, you can just go in and you can ask any question.
And the great thing about this is you can put in your question in any language, and it will give you the answer in your own language of preference.
So if I say something like Wait a minute.
Do you French? Speak French, Charlie?
Sudden word drop.
Charlie speaks French.
No. I haven't really used it since, like, school.
It's just when I learned it.
But but you can see, you know, this gives you, like, a nice nice answer.
It gives you examples, runnable code, etcetera, in the language of your choosing, and this is, like it can be more helpful if you're, you know, in, like, working Japanese or Chinese or something like that.
It's like it's it's really sort of, you know, powerful, the sort of AI LLM power tools that we get nowadays.
But that's sort of, like, a nice affordance that's just there on the on the home page for me.
Right?
So I'm gonna switch back now to my Positron window.
And if I just spend, like, a couple of minutes again, I'm just, like, delaying the point where I actually, like, write code.
You're killing me, Tyler.
You're killing me.
No. Just building out the suspense.
So you can see, like, what I have here is basically, like, the two pane, like, view for Positron.
And I think this basically gives you a clue that I'm more of a software engineer than a data scientist because I don't have the default data science view.
And, like, if you're curious about how to get there, it's really simple.
If you click on this layout button, it's the side by side, and you just enable the sidebar, whatever it's called.
Yeah. The sidebar.
And the sidebar gives you all the usual tools, say files, search, GET integration, etcetera.
And you can see I have these buttons on along the top.
This is also key to sort of the the whole ergonomics of using Positron.
And this I I you've probably seen this before because this is you know, I'm sure Libby and Isabella has gone through this, but the default is is this activity bar is the default is sort of down the side, and that sort of, like, for me, takes up a lot of sort of screen real estate.
So the first thing I do and this is great, Piyos.
This is sort of remembered.
You only have to do this once, is to set this to top.
So activity bar position top, and you're good to go.
And this is sort of my default setting for all the work I'm sort of usually work on.
So I have my source files here on the left, and then I will have the R console or I have a terminal sorry.
I have a terminal session with something I was working on with Claude code earlier. It's not disappearing.
Okay.
So very simply, and I have some notes here just like this is like this session is totally unscripted, but this is just some notes of, like, what I definitely want to cover so I don't go completely off topic.
So, okay, act one. What is Mirai?
So first things first is launch the package.
If you haven't got it installed, then just install it either from CRAN, or I would actually encourage you to try and install the development version because there's some nice new features in there that if we have time, I will share with you.
And it will be the first time I've revealed these significant new features that will be released, hopefully, later this month.
And to install the install the dev version of Mewray, then you you can just do Packpack and, oops, sorry.
And you can install it from the GitHub repo r lib slash u r I.
So will you be using dev version today?
I will be. Okay.
And there's no difference from from what I'm showing you unless we go into what specifically I've implemented later on if we have time.
So if you haven't got it installed, feel free to sort of install it.
It will pull in the development version of Nanonets as well, which is what underlies Orion Powers or the sort of high performance networking.
So very quickly.
So now I've installed it, then I load the package.
And the main function in Mirai is just Mirai.
So there's nothing for you to sort of learn.
Then there aren't sort of there are no options.
There are no options or environment variables that you can set with Mirai.
Everything is very explicit.
The main function is Mirai.
So it's really designed so you don't have to sort of remember anything.
So to use Mirai, you can just say oh, I'm sorry.
Let me just start a new session because I just installed it.
Sometimes it doesn't like me running things.
So if I just if I just put something in Mirai and Mirai basically just runs whatever expression in another process.
Okay.
So you can put anything here.
So for example and any any expression.
So anything you can put in these brackets.
So we can say, like, sleep.
So start sleep two and then say, you know, have it return done or something like that.
Right?
So when you create a Mirai, this object is a Mirai.
And you can see, like, it's this is the the the result of this is basically available at data, which is done here.
Okay.
This this is too simple. But if we should sorry.
This is too this is over too quickly.
So if we have this sort of last ten seconds, then if we look at this object this isn't actually done yet.
You can see this this sort of brackets here.
This is just the print method. Right?
And then what we can do is we can say, is it resolved or not?
And unresolved. So this is now actually resolved.
So this is now finished. Right?
This task is now finished, and then it will be available at data.
K.
So this sort of shows you that, basically, when you have this on this is happening in another process, then we're free in our own session to do other tasks.
And that is essentially what async is.
So This is where I would love to hop in and ask Lauren's question, which is what was the motivation or the need for developing MRI?
What problem is this built to solve?
So I'm imagining as a person who in undergrad and grad school had to leave her computer running overnight to run projects, that this would mean if you have something that's a very, very long process that's going to take a very long time, you can do something else while you're waiting for that to finish.
Am I right?
Yes. So there are many ways you can use it.
One is, as you described, so if you have something like and sort of my background, I say I'm not a data scientist sort of now.
I did do sort of data science y type things, previously.
I was actually sort of, building these deep neural nets, actually.
So I was actually training these neural nets, and then I was actually running influence on them in inference on them.
Sorry.
And so I was using Mirai for both of those purposes.
Right?
So first of all, if you have something that's sort of ongoing for a long time, you can run them in parallel in background processes and that each of them is self contained.
So if something sort of errors and goes wrong in one of them, all the others will still progress to completion, hopefully, because they don't interact with each other.
That's one thing.
And the second part is really what led me to develop ERI, which is I was actually running inference with one of these neural nets, one of these models.
Right?
And I was actually also ingesting real time data.
And so this was actually financial market data that I was ingesting through an API in real time and trying to run this through this model and then save the inference results in basically a kind of database.
Right?
So because this all had to happen in real time, then I couldn't afford to just run things in a sort of a normal loop because if something falls over, then that basically, stops the whole thing.
So what, Mirai can allow you to do is it can allow you to offload different tasks into different processes so that your main loop can stay reactive.
So, essentially, your main loop, you're not doing, very much at all in it.
You're just checking to see if other parts of that you need are all done.
So whether that's ingesting data or that's writing data, those can be done in separate processes, and you can have basically redundancy and sort of fail fail over in your main loop.
That is a very sort of high level overview.
But, hopefully, that makes sense to everyone.
Well, we got, like, seven more questions based off the answer.
So I would say that it makes a little bit of sense, but we need more context.
So do you want to give another give another code example, and then we can hop in with more questions?
Excellent.
Let me go through some more of what I wanna show you.
So this so I was on here.
Right?
So we here if so one way we can sort of work with async is we have this thing that's running another process.
And then in Mirai, the if you do these brackets, right, this is the collect method.
So this is actually equivalent this is basically collect Mirai. Right?
This this basically says it's already done, but this will actually wait for the Miraille to complete and then return the results.
So if I do this again, then this will actually wait.
So this is basically parallel.
This is not really async while you're waiting, but this is one way that you can sort of get the results.
But this is where you can pair Mirai with promises to actually have actions happen as soon as a result is complete without you having to wait for it.
So this works something like this, and this is basically how Mirai with Shiny works.
So Shiny, you know, everything is async.
Your Shiny server serves many different users.
You can't have that server sort of, like, stop and wait for one particular user to finish.
So if I if I load up the promises package.
Yep.
So what I can do here is so, again, if I say something if I say sleep and then that basically if I just return a value.
And then how promises work is you can say, you know, once that's done, then do something else with the return value.
And here, like, an example I like using is just to use the b par function, and it will, like, play a sound.
So here's you know, this Mirai is gonna run for two two seconds, then it's gonna return two, and then it's gonna call beep ah beep two, which is the second beep sound.
And I realized, like, you don't hear this. Right?
No. No. No. You'd have to share your system, Sam.
We'll trust you that your computer is mute, though.
So, like, okay.
I you're gonna have to trust me, but this is basically goes ba ling.
So this is like it's like a sort of Mario sound.
Like yeah.
Like you're getting a coin in Mario.
Like like yeah. Exactly. It's it's the coin sound.
And so this is sort of like how this works.
And, you know, that sound plays without me having to sort of interact.
And to give you a more sort of concrete example of how this sort of works, if I do a a mirai map, so this is this is basically the equivalent of L apply or or per map, but this basically maps each individual element in a different background process.
Right?
So if I map sort of, you know, this thing to a function, and then this just sleeps for the specified number, so from one to five seconds and returns that number.
And this mural map has an argument which is called dot promise and basically works exactly the same as promises then.
So we can pass a function to to this.
And, again, if we use beeper beep, then this will sort of play all the first five beeps in in five seconds.
And let me try and swish the microphone so that you can actually If you just hit the share button again, then you can click share system sound, and it it should let you do it.
I think I just did it. Anyway sure.
If I just play this oh, okay.
So I hit an error.
So this is basically telling me that I need to set demons.
So I can just click through here and and set demons.
So demons, again, is another piece of jargons.
They are demons are basically just workers.
They are background processes. Right?
And the reason it asked me to set daemons for this map is for a map.
Here, I'm mapping only five elements, but that map could be over, like, a hundred or a thousand elements.
Right?
And if daemons weren't set, then you'd basically be launching a thousand different sessions on your own machine, and that will probably crash your machine.
So for a map, it will ask you to set the daemons beforehand because it's usually sort of an oversight or mistake as it was in this case.
So I've just gone ahead and set six daemons, which are basically background processes.
At any time in MRI, there's a function which is just info, and you can see, like, exactly the status of what's happened.
So we have six connections here. Okay.
We'll go through what the rest means in a bit.
So if I just attempt that function again, then Hope he heard that right. Okay.
Nope. That's okay. Oh.
Oh, you didn't? Oh, sorry.
What what do I need to you need to hit the share button and then you might have to hit advanced and then share system sound or there's a little checkbox on the right that says share system sound.
But it's okay if it doesn't work out, it's all right.
We have about fifty questions.
So I say Sure.
That we get some questions in here because there's a lot of confusion.
Right?
Like there's a lot of things that you have talked about, like future promises, things that we don't have any context for.
So let's dig into some of these really quickly here.
Definitely.
One of them is from Nathan.
Do the contents of Morai inherit definitions from the global environment?
No.
And this is is a conscious sort of design decision and it helps you sort of avoid mistakes.
Okay.
And like this is sort of like, to my mind, this is how sort of things are meant to be.
And I know, like, that future, like, does it differently, and that package has been around for a while.
So people sort of know that behavior.
But there are various sort of edge cases there.
And the sort of the the danger in trying to sort of automagically sort of infer what's sort of in your mirai can lead to sort of well, in the best case it can lead to errors, but it's like the worst case like it's subtly wrong and you get a plausible answer and you don't even know you're wrong.
So that arguably is sort of worse.
Mirai is sort of very explicit in that sense, and I'll I'll show you exactly what I mean.
So if I if I define something like if I define something like slow funk, right, So this say just function and this just just again just sleeps and then it returns something like done.
Okay.
So if I attempt to sort of run Mirai slow funk, right, you might think that would work, but what you would actually see is there's error and it just says error cannot find function slow funk because Mirai runs your expression in another process, and this is a clean process.
Every time you call Mirai, that is like a clean invocation.
There's nothing in that evaluation environment.
So what you would do here is you can call it, but then you would pass in SLOYFUNK to the MRI.
So so something something like this. Right?
So the expression is the same, Slyfunc, but then you would define Slyfunc inside the MRI is the Slyfunc which is this function that's living in my current environment.
Okay. And then we get the result we accept.
Okay.
So you have mentioned feature and promises again, and you were like, everyone knows what that is.
Charlie, we do not.
So if you could give us a little primer on the difference between Mirai and Promises and Future.
One of the questions was like, wait, I'm confused.
Why would I choose Mirai versus promises or future?
So promises is a way basically as I showed to, have actions occur when your Mirai or your or your future completes.
So they're they're designed to be used together, they do different things.
A Miraiwa feature is just a way to run an expression in another process.
Right?
Either in parallel or or async.
Okay.
So they things like feature and promises keep things running during these, like, long running tasks where if you have a chain of tasks that need to happen, for example, in a Shiny app, right, that need to happen one after another or reactive to each other, some of those future tasks need to be set aside and stored so that they can happen once something has finished running, and they can all happen all at one time.
Does that sound right?
Or, like, they can all happen happen in order.
Yes.
So a promise will be basically it's promise uses these verbs like then.
Right?
So this is the key this is the key function from sorry.
Promises.
Sorry. That's not very helpful.
So it's basically It's basically, you know, when when you have MRI and that's finished, then, like, then take the return value from that and pipe it into another function.
Okay.
So Renato in the chat says, wait. I'm lost.
Aren't our functions run sequentially anyway?
Okay.
So let me maybe just go through, like, the second part of my Will that answer it?
What I had what I had in sort of what I wanted to demonstrate.
So, like, sequential is basically so you're right.
R is single threaded.
So without a package like Mirai, everything will run sequentially.
And Mirai is basically designed to overcome that.
And why this is important?
Well, I mean, R has been around for, you know, thirty years or so.
I mean, back then you were lucky if you had sort of you know two or four cores that was sort of the of the norm.
But you know modern laptop has at least eight cores.
My MacBook, I have fourteen cores.
All your computations in R by default only uses one single core.
So easiest way to sort of demonstrate that is if I define a function again, DOM task, if I just define that as and again, I'm sort of using these generic functions because it's it's easier for me to control sort of how long they take rather than, like an actual, function that takes a long time.
So this will just leave for two seconds and then return the the number.
Okay?
So if I actually sort of time how long this takes, then if I apply this to, say, five, a long task.
Right?
Then, you know, five times two, expect this to last ten seconds as you can see.
And, you know, you're sort of this is just sleeping for two seconds, but, you know, you can imagine that could be doing some kind of, you know, either complex sort of matrix multiplications, you could be doing sort of or you could be like hitting some kind of API and waiting for sort of data to come in.
Right?
So that what you what you would want is for those to run-in parallel.
So or if you we set six daemons, are six workers, then if we do the same thing and time sort of a mirai map, is the the parallel equivalent of l apply.
Wrong task.
And here we actually we actually wait for these to complete because otherwise it will return immediately.
Then we can see that because they're done in parallel, this whole thing only takes two seconds.
Alright. That made a lot more sense to my brain.
We have each of these elements assigned to a different process, and they can all happen at the same time.
So I can say, I can be like, all right, I have these, let's say five modeling tasks, I think in statistical modeling.
So I have these five modeling tasks and they're going to take a while because they are each going to iterate over a bunch of things themselves.
And I can run all of them at the same time on different cores of my computer.
And I don't have to keep my laptop awake overnight in order to run them all and get all of those and wait for all of them sequentially to run on the same core.
That's right.
And, you know, these and so they don't have to be sort of, you know, even sort of simple functions.
They they can be really com they can be full scripts, and you can literally do MURAI, and you can say, you know, you can literally say source whatever, you know, whatever file you have.
And they can run your entire script, which, you know, may take hours.
It may take days even. Right?
And you can have them running in different in different processes.
And the key about Mirai is with Mirai, you don't need to care, like, whether that's just running in another process on your own machine.
So you're sort of utilizing all the cores that your laptop has.
Or if they're running in processes on another machine.
So if you have, like, a network server. Right?
If you have a workstation where you can send jobs.
Or if you're, you know, if you're yeah. Distributed.
Exactly.
If you're at a university and you have access to, like, an HPC cluster, Mirai allows you to do all of that.
And, hopefully, we'll have time where I can just show you something very simple.
I'm glad that you said that because I've been holding on to Hubert's question because I knew I knew we're gonna get there.
Hubert had asked, wait. Can you use Morai with the HPC? Yes.
Absolutely.
So we're distributing the work between cores right now on our laptop, on Charlie's laptop.
But we can assign distributed machines as our workers with Mirai as well.
And we can scale up and down depending on, our needs.
Right, Charlie?
Great.
And, hopefully, I before we run out of time, I want to just go through this code piece again.
You've hit the nail on the head.
There are two sort of core reasons why you would want to use Mirai.
And the first is you can scale up and down the resources you need dynamically.
So if you decide you need more workers to sort of crunch the tasks that you have on hand, you can simply add more workers.
So these things aren't fixed.
And what I want to show you is basically how this happens.
Right?
So Mirai basically works as if you think about it as a kind of a a hub model.
Right? So when you set up daemons, this basically you set up, like, something that listens for incoming connections.
Right?
So what you can do is you can set up daemons with a URL.
So this and you can and we have this helper function called local URL.
So if you do that, then what happens is that sets up what you can think of as a base station.
This listens for incoming connections from your daemons, from daemons that have started.
Right?
As long as they have access to this URL, then they can connect in and you have then you have a worker that's connected.
So if I set this up, then this info function is going to come in handy.
You can see that there are no connections at the moment.
And what you can do is you can launch local daemons with dysfunction.
Launch like sorry. Not like a local. Launch local.
Okay.
So launch scrambling Charlie's brain, y'all.
Yeah.
And you can say something like, you know, launch four local processes.
And that basically goes ahead and does that.
So if we look again, we have four processes.
So we can do things like, you know, if I just evaluate to move right, like nothing.
Then we can see that, you know, oh, wow.
We have one task that's completed here. Right?
Just to check that something's happening.
And, you know, assuming we set this up and, you know, we can be running lots of things.
So I'm just gonna copy this thing here.
So this just runs a bunch of long tasks and okay.
So the two that's executing, five that's completed, and now all seven tasks have completed.
But if you have a bunch of things and you you sort of you realize you have a large backlog, then you can basically simply just launch more daemons.
So you can say, oh, I want to launch another four daemons.
And now we basically have eight workers online.
So any tasks that are have been queued will just automatically use the number of available workers.
Okay. Wait. Wait.
That was the first two two seconds.
We have produced daemons.
We have created daemons automatically.
Do we need to manually close them?
Same with these processes that we're launching or these connections that we're launching.
Do we need to explicitly close both daemons and connections?
Yes.
So, I mean, daemons are connections, and they're the same thing.
Okay. And Good.
These it's always good practice to to close them, and the way to do that is to set demons to zero.
And that will close them straight away.
But if you forget to close them and you just end your R session, they will all disappear as well.
There's no danger of sort of leaving hanging processes at all.
They're all as soon as the connection drops, they're all designed to terminate themselves.
Perfect. Yes.
But, you know, if you're if you have a script or if you have markdown document, it's always good to pair a daemons with a daemon zero at the end.
Okay. Great. I interrupted you.
We have fifteen minutes left.
We still have so many questions, but I would love for you to be able to finish your side.
I thought I was gonna have too much time, which is why sort of, like, overdid the introduction and okay.
So the second part apart from so apart from sort of the scaling and sort of ability to add and subtract daemons at any time is you can run them anywhere.
So if you just do daemons and a number, this will just launch processes on your own machine.
Okay? But those processes can also be another machine.
And there are different ways you can launch them.
One is over SSH.
One is via clusters manager.
That's if you have access to a cluster.
The other is, via POSIT workbench.
So if you're lucky enough to be in an enterprise sort of environment that actually has Workbench, you can easily launch workers as Workbench jobs.
But I won't cover that.
I will try and cover SSH as an example.
Okay.
So the way you do that is you call daemons and you create a URL which is using this helper, which is host URL.
Okay.
So this creates a network socket which is available to network.
So other computers will be able to connect to this address, this URL.
Right?
And if I do that again, like, nothing's connected yet.
And what I can do is I can I can create a remote configuration?
And in this case, this will be a an SSH configuration.
And again, we have these helpers that really sort of, like, minimize what needs to be done.
So here, I create an SSH configuration.
And the own sorry.
There there there are arguments, but the only the only required argument is this remote's argument.
And that is simply the URL of the computer that you have SSH access to.
So to give you an example, I switched to my terminal here.
If I have sorry.
This is just so I I actually I'm actually connected to a VPN.
So this is I have access.
So if I can have SSH, right, over the so slash p, this is the port that you connect to.
And this is this is the address of the machine that you can connect to.
Sorry. Here.
And if I have access to this machine over SSH, and so this is like I'm actually running on this machine.
So I have a MacBook, but this is connected to a Linux machine now.
I'm gonna just exit out of that.
But essentially, that URL there, which was one nine two dot one six eight dot zero dot one zero one.
That's the only information I need to set up this configuration in Mirai.
Okay?
So once I have that, then I can actually launch use launch remotes and not launch local.
Launch remote.
So again, I can launch maybe two daemons, and I can pass that configuration in.
Okay?
See what happened.
Oh, ah, so we have a time.
So again, this is this is this is useful because, again, as I was explaining how Mirai works is you spin up this basically like this base station, right, which listens for incoming connections.
That means the computer that you have access SSH access to has to be able to dial in to your to the machine that you're running Mirai on.
And in this case, that's not possible because I don't have these ports that opened on my, like, called laptop.
Fortunately, Mirai allows you to connect using SSH tunneling.
So SSH tunneling, again, like, people tend to get confused, so I will try and explain it in as simple terms as possible.
SSH tunneling is basically when you connect to a computer using SSH, that creates a tunnel immediately.
So imagine there's a tunnel between the two sides.
Now instead of a connection being made between the two sides, each side connects to a local port.
So if I'm as Mirai, sort of if I set daemons, I'm listening to a local port, and then on the daemon side, that computer's dialing to a local port, and then the tunnel basically bridges the two sides.
So there's no longer any connection from that computer to my computer.
Connected to an intermediary.
Yes.
And, like, very concretely, if you follow this, you will get it.
So if I just if I if I just shut down the previous daemons, And in this case, what I'm gonna do is I'm gonna create a local URL.
Right?
So this is not is not the URL that's open to other computers on the network.
This is a local URL.
I'm gonna set TCP equals true because this is this is a TCP connection.
If I use status, this just gives me a little bit more information than info.
But you can see we're actually listening to this one two seven this address, which is the local host address.
So I'm now listening to a port on my own computer, and this is the port that the tunnel is gonna be opened on.
I can then create this SSH configuration.
And, again, I can connect to this address is one nine two dot one six eight dot zero dot one zero one.
And I actually need to use this port because that's how I've configured that.
And I just need to specify this this argument, which is tunnel equals true.
K?
I think I now.
If I if I try and if if I try and launch now using this this configuration, this should now hopefully work.
So yay. Now I have two it.
I have two workers, and they are on another machine that I have that's in London.
It's actually a very old sort of converted Mac mini, actually, but it's running Linux now.
And to prove to you that it's running Linux, I'm gonna run like Mirai, and I'm just gonna ask for the sys.
Info.
Okay?
From the worker, and you can see that, hey.
This is running Linux.
And just to prove that I'm not running Linux, this is my machine.
It's definitely some form of Mac.
Okay.
That was a whirlwind, but if you got that, you understand how sort of SSH timing.
But as you can see, all all you had to do was create this configuration, which is just this URL, which is if you can access that machine over SSH, you have all the information you need to to run to run Mirai over SSH.
Okay.
Charlie, this was so much information all at one time.
We have so many questions that we will not be able to get to all of them, but I want in our last five, four or five minutes here, to see if we can get to some of them.
So one of them from Brent was, I believe NumPy distributes calculations over multiple cores.
So does Mirai allow R to perform the same thing as well?
Yes. It does.
And the NumPy is very specific, so it will run only numerical work that NumPy handles.
Mirai allows you to run arbitrary expressions.
So anything you can do in R, can you can put in a Mirai.
That's that's the difference. Yeah.
Great. Any R processes. Okay.
Dan had also asked, does Mirai ship with some kind of task viewing dashboard, like Python's dash visualization so that you don't have to type info over and over?
Not built in.
Not built in. Okay. Great. Let's see.
We had another question that was, can we use parallel detect cores to see how many daemons we can use?
I really like this question because I don't know how many daemons I would have access to.
And that's great question. And Yeah.
Like, Mirage by design forces you to actually specify the number you want.
So that can be, you know, that can be fourteen, which is sort of number, of course, I have on my laptop.
So you can use something like parallel, sorry, parallel detect cores or whatever.
Bam.
But, you know, you can easily be on a server with, you know, two hundred and fifty six cores or something.
And, like, sometimes you don't want to use all your calls because you might be running something else.
Right? So, like, it never has that context.
You running a a automatic function.
The other reason is this like, you might want to be using your calls if what you're doing is compute intensive.
Right? You want to sort of utilize all your calls.
Fine.
But instead, if what you're doing is actually waiting on IO, so this is like if you're requesting, like, a download.
Right?
That is actually not taking all your computation power.
So for those kind of tasks, you might actually want to use more than the number of calls you have.
So you might wanna use, like, twenty eight, like, if all you're doing is, like, querying some remote API.
So that's also another reason why, like, I don't sort of try and assume, like, the number that people want.
And yeah.
Okay.
So with our last two minutes, Zach said he had to leave, but he had a great question.
He said, in typical data science work, would parallel processing be more useful than async processing, do you think?
Yes.
If and and Mirai actually powers a lot of things sort of under the hood.
Right? So if you're using parallel per, that uses Mirai.
So you set daemons, you use the null per syntax, and that is just parallel.
It's not async.
Where async really sort of comes into its own is if you're, using Mirai with Shiny or using Mirai with something like Plummer two.
So, again, Mirai powers Plummer two under the hood.
So if you use an async function in Plummer two, that implicitly uses Mirai.
Awesome. Okay.
I bet we can get in one more question.
One more. One more.
So Rob had asked, can you print progress slash percentages that only get shown on call, like, while things are running?
I think that's what that's asking.
Yes. Right.
So so very quickly, if you do, like, a Mirai Map, one of the collection options so instead of just collecting is you can do, like, progress, and and that gives you a progress indicator.
Okay. Cool.
Please carry on while I do something.
I'm going through and just looking at all these questions.
I think that I will get with Charlie since we are out of time, We'll see if we can answer some of these.
There is one from Nadebeco. There is one from David Diaz.
And they look like they could be answered pretty quickly.
So we'll answer them in the chat after the session.
Charlie will help.
Excellent.
All right.
The last thing I want to mention.
Oh no, I'm out of time.
Is a MiRai skill.
If you folks out have access to Claude code or OpenCode or some great AI agent, install the rlib skill, Mirai, and you can just invoke that.
You can trans like, you can transform all your sort of normal scripts into parallel and async code.
Amazing.
Oh, I just spelled sorcery wrong in the chat. Don't me.
Hold on. Let's fix it.
All right. Thank you so much, Charlie. That was amazing.
You're getting thank yous in the chat.
Thank you for being patient with us while we all try to muddle through what async is, what Parallel is, what Mirai does, what future and promises are.
I think we all learned a lot and have a lot to like go Google and think about.
I wish that I knew about this in undergrad and grad school.
I definitely didn't and it would have helped my life, quality of life with coding so much.
So thank you so much.
We will get with Charlie to answer some of the more simple questions afterwards in the chat.
We will see you all on Thursday at the Data Science Hangout if you would like.
Thank you, everybody. Have a fantastic week.
I'll see you when you see you. Thanks, Pauline.
Thanks, everybody.
Bye. Thank you, Charlie.
Related Videos
Agentforce NOW AMA: Build with React and Salesforce Multi-Framework
SalesforceDevs
490 views•2026-05-28
How agent o11y differs from traditional o11y — Phil Hetzel, Braintrust
aiDotEngineer
450 views•2026-05-28
WEB TECHNOLOGIES UNIT-2 | Degree 4th sem BCOM Computers web technologies unit-2 full explanation💯✅
LearnwithSahera
1K views•2026-05-29
More tests are always better? How to use AI to identify tests that bring little value
Alliance4Qualification
335 views•2026-05-29
Search Algorithms Explained in 60 Seconds! 🤖💨
samarthtuliofficial
218 views•2026-06-01
People of Game of Thrones using JavaScript DOM
AltCampus
296 views•2026-05-30
Introduction to Problem Solving Part - 1 | Lecture 1 | Intermediate DSA
ascensionix
107 views•2026-05-29
So What's Odin Lang Even Good For
TechOverTea
131 views•2026-06-01











