Even if a server for a website might not use this specifically, the ability to run native code to interact outside the confines of a browser then use the browser as a tool to create frontends is super powerful. This reminds me a lot of mopidy which is a music playing server that has several web based frontend plugins available. This also could allow more performant processing of certain data by offloading that to another more performant language while still handling all the web stuff in elixir so you can, for example, combine the speed of rust and serve those results easily to thousands of concurrent connections in real time.
Thanks for the feedback! I wish I knew Zig (and will probably be looking into it soon) because the integration through the ~Z sigil looks really smooth.
This has been a great video! As others said, I really did not notice that 17 minutes have passed. The animation are on point, and the fact that there was no music in the background let me properly focus, great work! One quick question, did you have a build step for Tailwind, or did you import all of the classes? I usually have some sort of build step in order to not have the huge bundle of all the css classes. (note that I'm not at all familiar with Elixir, I'm asking out of curiosity)
Great tutorial. The only thing that might be worth mentioning is that a NIF should not run for more than 1millisecond, ore else bad things happen (it messes with the Erlang scheduler). Given that the Rust library is async, I suspect it's because its functions take more than 1ms to run, so a better approach would be, from the Rust side, to start a new thread with the Tokio runtime that's running continuously, and use something like crossbeam_channel to communicate between the NIF and the Tokio thread. The NIF for reading the sensor would only send the request to read to the Tokio thread and return immediately. When the Tokio thread has the result, it can send a message directly to Elixir. From the Elixir side, you call the NIF, and then use a receive block to wait for the message passed by the Tokio thread. I know that this complicates things a lot, but it would be the more correct way of doing NIFs
Totally makes sense. In this case I did end up marking the functions as dirty IO in the project pushed on GitHub to avoid harming the scheduler. A crossbeam channel / receive sounds really interesting though, maybe for a future rustler video!
Awesome example of NIFs and LiveView! I'd love to see this taken one step further, where you use Nerves to run the sensor code and web server on a Raspberry Pi or something, because this feels like an IoT project.
I think there’s some unavoidable time spent communicating with the device (which is why I introduced the GenServer as a managed cache), but I might explore an approach like @FrancoBugnano described that uses a receive block. Either approach will take around the same amount of time to get data, but the latter would be more efficient on the beam side.
I don't understand both rust and elixer but this was amazing. The sensor and FFI was cool but I was stunned by how easly you could create a websocket enabled site with elixer. It's websockt right or is it a SSE?
Very cool! I know this is out of scope for this tutorial, but tokio runtime should probably be stored in a lazy evaluated static? Not sure if FFI will cause problems here
Thanks! I didn’t want to get too deep into more complicated things like lazy static but you’re totally right. I think the way NIFs are loaded would be fine with a static, but I’ve never tried it
Great example of combining Elixir with Rust!!!!!
I didn't even notice this was a 17 min video, felt too short! A follow up would be soo good
More rustler and zigler content please!
Even if a server for a website might not use this specifically, the ability to run native code to interact outside the confines of a browser then use the browser as a tool to create frontends is super powerful. This reminds me a lot of mopidy which is a music playing server that has several web based frontend plugins available.
This also could allow more performant processing of certain data by offloading that to another more performant language while still handling all the web stuff in elixir so you can, for example, combine the speed of rust and serve those results easily to thousands of concurrent connections in real time.
Very cool demo! Thanks for sharing.
One more sign I should start learning Rust! (Also heard Zig with Zigler being a good option)
Thanks for the feedback! I wish I knew Zig (and will probably be looking into it soon) because the integration through the ~Z sigil looks really smooth.
Such a remarkable video, amazing work!
The best elixir content creator
This has been a great video! As others said, I really did not notice that 17 minutes have passed.
The animation are on point, and the fact that there was no music in the background let me properly focus, great work!
One quick question, did you have a build step for Tailwind, or did you import all of the classes? I usually have some sort of build step in order to not have the huge bundle of all the css classes. (note that I'm not at all familiar with Elixir, I'm asking out of curiosity)
Thanks! I’m glad you enjoyed it!
By default, modern Phoenix apps come with a Tailwind build step by default-no config needed.
Love this! A great way to combine the best of both languages.
This was super interesting, thanks for the video!
Great tutorial. The only thing that might be worth mentioning is that a NIF should not run for more than 1millisecond, ore else bad things happen (it messes with the Erlang scheduler). Given that the Rust library is async, I suspect it's because its functions take more than 1ms to run, so a better approach would be, from the Rust side, to start a new thread with the Tokio runtime that's running continuously, and use something like crossbeam_channel to communicate between the NIF and the Tokio thread. The NIF for reading the sensor would only send the request to read to the Tokio thread and return immediately. When the Tokio thread has the result, it can send a message directly to Elixir. From the Elixir side, you call the NIF, and then use a receive block to wait for the message passed by the Tokio thread. I know that this complicates things a lot, but it would be the more correct way of doing NIFs
Totally makes sense. In this case I did end up marking the functions as dirty IO in the project pushed on GitHub to avoid harming the scheduler. A crossbeam channel / receive sounds really interesting though, maybe for a future rustler video!
Loving your videos! Please keep it up!!
Great explanation and extraordinary editing skills for _only_ 1k subs! Keep going
Great video! Thanks!
Awesome example of NIFs and LiveView!
I'd love to see this taken one step further, where you use Nerves to run the sensor code and web server on a Raspberry Pi or something, because this feels like an IoT project.
Thanks! It definitely crossed my mind, I just don’t have a modern Raspberry Pi (yet!)
Thanks for the content 😊
Great demo but as a next step could you show us how to do this without a blocking call? What if we want the data without waiting?
I think there’s some unavoidable time spent communicating with the device (which is why I introduced the GenServer as a managed cache), but I might explore an approach like @FrancoBugnano described that uses a receive block. Either approach will take around the same amount of time to get data, but the latter would be more efficient on the beam side.
I don't understand both rust and elixer but this was amazing. The sensor and FFI was cool but I was stunned by how easly you could create a websocket enabled site with elixer. It's websockt right or is it a SSE?
Phoenix LiveView uses Websockets with an automatic fallback to long polling on failure. Definitely a superpower
Does a package like Rustler exist but for golang?
Great tutorial! =)
We not gonna talk about how it's 80 degrees in his office!
Haha, it’s hard to record with the AC background noise and it was like 110 degrees F outside!
Very cool!
I know this is out of scope for this tutorial, but tokio runtime should probably be stored in a lazy evaluated static?
Not sure if FFI will cause problems here
Thanks! I didn’t want to get too deep into more complicated things like lazy static but you’re totally right. I think the way NIFs are loaded would be fine with a static, but I’ve never tried it