17 releases (5 breaking)

Uses old Rust 2015

0.6.0 Jun 27, 2018
0.5.0 May 20, 2018
0.4.2 May 7, 2018
0.3.2 Apr 14, 2018
0.1.8 Jun 29, 2016

#3 in #effort

41 downloads per month

MIT license

24KB
426 lines

hotswap

Crates.io Linux Build Status Windows Build Status

A library for hotswapping running code with minimal effort, requires a nightly rust build.

Beware that the library is a prototype for now, and it may crash frequently.

Usage

  • Add the hotswap and hotswap-runtime dependencies to your Cargo.toml.
  • Add a dylib build with the same project name and path to your Cargo.toml.
  • Add the #![feature(plugin, const_fn)] feature gates.
  • Import the plugin #![plugin(hotswap)].
  • Annotate the functions you want to hotswap with the #[hotswap] modifier.
  • Add #![hotswap_header] attribute to the top of your program.
  • Add unsafe { hotswap_start!() } to the entry point of your program, before you call any hotswapped functions.

Current Limitations

  • Changing hotswapped function signatures WILL result in a segfault.
    • Maybe this can be fixed by storing the types as metadata.
  • Requires user code to use some non-local feature gates.

Example

# Cargo.toml

[package]
name = "hotswapdemo"
version = "0.1.0"

[lib]
# This must be the same as the package name (with hyphens replaced with
# underscores). Anything else will cause an error at runtime.
name = "hotswapdemo"
crate-type = ["dylib"]
path = "src/main.rs"

[dependencies]
hotswap = "*"
hotswap-runtime = "*"
// main.rs

#![feature(plugin, const_fn)]
#![plugin(hotswap)]
#![hotswap_header]

use std::thread::sleep;
use std::time::Duration;

#[hotswap]
fn test(test: i32) -> () {
    println!("Foo: {}", test);
}

fn main() {
    unsafe { hotswap_start!() }

    let mut i = 1;
    loop {
        test(i);
        i += 1;
        sleep(Duration::from_millis(2000));
    }
}

That's it!

From there you can run the binary

> cargo run
     Running `target/debug/hotswapdemo`
Foo: 1
Foo: 2
Foo: 3

Then, once it is running, you can edit the printing code, e.g.

    println!("Bar: {} :)", test);

Once you recompile the code on another terminal (or on the same one using background), you'll see the changes!

> cargo build --lib
   Compiling hotswapdemo v0.1.0 [...]
> fg
Foo: 7
Foo: 8
Bar: 9 :)
Bar: 10 :)

The running code will update without restarting the binary or losing state!

See Also

No runtime deps