Slide 1

Slide 1 text

What can Rust do for my Node.js?

Slide 2

Slide 2 text

Software Engineer at Tuenti MadRust co-organizer  jrvidal  _rvidal

Slide 3

Slide 3 text

Beware of Greeks Rustaceans bearing gifts

Slide 4

Slide 4 text

Systems programming You know, like C/C++

Slide 5

Slide 5 text

Why coming here to talk/hear about Rust?

Slide 6

Slide 6 text

Moving the needle

Slide 7

Slide 7 text

Show me the money Native Extensions WebAssembly Async I/O Reinventing the wheel Node.js

Slide 8

Slide 8 text

fn main() { println!("Hello Javascripters"); } But first...

Slide 9

Slide 9 text

Rust is... 1. Typed fn my_middleware(req: Request) -> Response; 2. Compiled, and... $ rustc hello_world.rs && ./hello_world Hello, world! 3. ... compiled natively $ rustc hello_world.rs --target=aarch64-apple-ios && ./hello_world # good luck

Slide 10

Slide 10 text

const http = require("http"); const hostname = "127.0.0.1"; const port = 8000; const server = http.createServer((req, res) => { res.statusCode = 200; res.end("Hello World\n"); }); server.listen(port, hostname, () => { console.log( `Listening at http://${hostname}:${port}/` ); }); Node.js — Getting Started

Slide 11

Slide 11 text

extern crate tiny_http; use tiny_http::{Server, Response}; fn main() { let addr = "127.0.0.1:8000"; let server = Server::http(&addr) .unwrap(); println!("Listening at {}", addr); for request in server.incoming_requests() { let response = Response::from_string("Hello World\n"); request.respond(response); } }

Slide 12

Slide 12 text

We want it all Frankie Cordoba

Slide 13

Slide 13 text

We want it all Memory safety without Garbage collection Abstraction without Overhead Stability without Stagnation Hack without Fear

Slide 14

Slide 14 text

Memory safety without Garbage collection and Speed fn main() { let some_number : &u32 = get_me_a_number(); println!("The number is {}", some_number); } fn get_me_a_number() -> &u32 { let numbers = vec![1, 2, 3]; &numbers[2] }

Slide 15

Slide 15 text

Memory safety without Garbage collection and Speed fn main() { let some_number : &u32 = get_me_a_number(); println!("The number is {}", some_number); } fn get_me_a_number() -> &u32 { let numbers = vec![1, 2, 3]; // ⚠ ERROR &numbers[2] //^^^^^^^ borrowed value // does not live long enough }

Slide 16

Slide 16 text

Server::new(|req| { let user_id = req.params.user_id; user_collection .find(|u| u.id == user_id) .map(|u| Response::from(u)) .or_else(|| Response::not_found()) }) .listen(&addr); Abstraction without Overhead and Speed

Slide 17

Slide 17 text

Stability without Stagnation $ cargo new nodejsmad Created binary (application) `nodejsmad` project $ cd nodejsmad $ cargo add num_cpus Adding num_cpus v1.8.0 to dependencies $ cargo run Updating registry `https://github.com/rust-lang/crates.io-index` Compiling libc v0.2.43 Compiling num_cpus v1.8.0 Compiling nodejsmad v0.1.0 Finished dev [unoptimized + debuginfo] target(s) in 8.54s Running `target/debug/nodejsmad` Hello, world!

Slide 18

Slide 18 text

Native Extensions Chan Walrus

Slide 19

Slide 19 text

Native Extensions [...] the method for implementing Addons is rather complicated, involving knowledge of several components [...] Node.js docs/api/addons.html

Slide 20

Slide 20 text

Native Extensions [...] the method for implementing Addons is rather complicated, involving knowledge of several components [...] Node.js docs/api/addons.html npm install -g neon-cli

Slide 21

Slide 21 text

Getting started with Neon #[macro_use] extern crate neon; use neon::prelude::*; fn hello(mut cx: FunctionContext) -> JsResult { Ok(cx.string("hello node")) } register_module!(mut cx, { cx.export_function("hello", hello) }); ~ ~ ~ ~ ~ ~ ~ ~ ~ "native/src/lib.rs" 12L, 219C 00:00

Slide 22

Slide 22 text

Advanced: native BigInts Watch for: num = "0.2" is all the required "business logic". JS classes are defined through macros: declare_types!( class JsBigInt for BigInt { init(cx) { /* ... */ } method toIntString(cx) { /* ... */ } } ) See: BigInts with Neon and num

Slide 23

Slide 23 text

WebAssembly Rubendene (CC BY-SA 4.0)

Slide 24

Slide 24 text

const binary = fs.readFileSync("./program.wasm"); const { instance } = await WebAssembly.instantiate(binary); instance.exports.expensiveComputation(); (module (export "expensiveComputation" (func $f)) (func $f (result i32) i32.const 1)) WebAssembly

Slide 25

Slide 25 text

Getting started with wasm-pack extern crate cfg_if; extern crate wasm_bindgen; mod utils; use wasm_bindgen::prelude::*; #[wasm_bindgen] extern { #[wasm_bindgen(js_namespace=console)] fn log(s: &str); } #[wasm_bindgen] pub fn greet() { log("Hello, madridwasm!"); } ~ ~ ~ ~ 00:00

Slide 26

Slide 26 text

Advanced: Exif metadata parser Watch for: Again, business logic contained in kamadak-exif = "0.3" More complex types crossing the Rust/Wasm-JS boundary: #[wasm_bindgen] pub fn get_exif(source: &[u8]) -> Vec Throwing from Rust/Wasm to JS: wasm_bindgen::throw_str(&format!("{:?}", error)) > pkg.get_exif([]) Error: InvalidFormat("Broken JPEG file") See: Exif parsing with Rust + Wasm

Slide 27

Slide 27 text

Reinventing Node.js Christo Anestev

Slide 28

Slide 28 text

Mode.js (ModeJsMadrid) /source % cargo run Compiling modejs v0.1.0 (file:///source) Finished dev [unoptimized + debuginfo] target(s) in 3.26s Running `target/debug/modejs` > 1 1 > var x = {foo: 2} undefined > x 00:00

Slide 29

Slide 29 text

Async I/O Tamorlan (CC-BY-3.0)

Slide 30

Slide 30 text

Everybody ends up in (callback) hell let ping_4ever = loop_fn(Client::new(), |client| { client.send_ping() .and_then(|client| client.receive_pong()) .and_then(|(client, done)| { if done { Ok(Loop::Break(client)) } else { Ok(Loop::Continue(client)) } }) });

Slide 31

Slide 31 text

#[async] fn fetch( client: Client ) -> IoResult { let response = await!(client.get(URL))?; if !response.status().is_success() { return Err( IoError::new(IoErrorKind::Other, FAIL_MSG) ); } let body = await!(response.body().concat())?; let string = String::from_utf8(body)?; Ok(string) }

Slide 32

Slide 32 text

Where to go from here? https://www.rust-lang.org/documentation.html "The Book" Rust by Example https://www.meetup.com/MadRust/ Reddit, users forum WebAssembly: Rust and WebAssembly WG (check the !) wasm-pack (check the !) wasm-bindgen (check the !) Native addons, Neon: neon-bindings Web development, async I/O Are we web yet? Network Services WG We love "newbies"

Slide 33

Slide 33 text

Keep Node-ing Thanks!