Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vertexclique committed Jul 21, 2019
0 parents commit be42fad
Show file tree
Hide file tree
Showing 24 changed files with 1,351 additions and 0 deletions.
21 changes: 21 additions & 0 deletions .gitignore
@@ -0,0 +1,21 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/target

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

/target
**/*.rs.bk

*.bc

bcs

# Intellij stuff
.idea/
8 changes: 8 additions & 0 deletions .travis.yml
@@ -0,0 +1,8 @@
language: rust
rust:
- nightly
matrix:
fast_finish: true
script:
- cargo build --verbose --all
- cargo test --verbose --all
70 changes: 70 additions & 0 deletions Cargo.toml
@@ -0,0 +1,70 @@
[package]
name = "bastion"
version = "0.1.0"
description = "Fault-tolerant Runtime for Rust applications"
authors = ["Mahmut Bulut <vertexclique@gmail.com>"]
keywords = ["fault-tolerant", "runtime", "actor", "system"]
categories = []
homepage = "https://github.com/vertexclique/bastion"
repository = "https://github.com/vertexclique/bastion"
documentation = "https://docs.rs/bastion"
readme = "README.md"
license = "MIT"
edition = "2018"
exclude = [
".github/*",
"examples/*",
"graphstore/*",
"tests/*",
"img/*",
"ci/*",
"benches/*",
"doc/*",
"*.png",
"*.dot",
"*.yml",
"*.toml",
"*.md"
]

[badges]
travis-ci = { repository = "vertexclique/bastion", branch = "master" }
maintenance = { status = "actively-developed" }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = "^0.1"
tokio-executor = "0.1.8"
tokio-threadpool = "0.1.15"
futures = "0.1.28"
log = "0.4.7"
env_logger = "0.6.1"
crossbeam-channel = "0.3.8"
ratelimit = "0.4.4"
backtrace = "0.3.32"
ego-tree = "0.6.0"
lazy_static = "1.3.0"
objekt = "0.1.2"
signal-hook = "0.1.10"

#futures-preview = "=0.3.0-alpha.16"
uuid = { version = "0.7", features = ["serde", "v4"] }

[dev-dependencies]
reqwest = "0.9.19"

[profile.bench]
panic = "unwind"
opt-level = 3
debug = false
rpath = false
lto = false
debug-assertions = false
codegen-units = 1

[profile.debug]
panic = "unwind"

[profile.release]
panic = "unwind"
21 changes: 21 additions & 0 deletions LICENSE
@@ -0,0 +1,21 @@
MIT License

Copyright (c) Mahmut Bulut

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
144 changes: 144 additions & 0 deletions README.md
@@ -0,0 +1,144 @@
<div align="center">
<img src="https://github.com/vertexclique/bastion/blob/master/img/bastion.png"><br>
</div>

-----------------

<h1 align="center">Bastion: Fault-tolerant Runtime for Rust applications</h1>

*The breeze of the cold winter had come. This time of the year, Crashers arrive in the village. These are the giants who can't be evaded. They born to destroy and take people to the Paniks Heights. Suddenly, The developer descried the blurry silhouettes of Crashers from afar.*

*With cold and cracked voice, he whispered:*

*It is time to go to **Bastion Fort**.*

---

<table align=left style='float: left; margin: 4px 10px 0px 0px; border: 1px solid #000000;'>
<tr>
<td>Latest Release</td>
<td>
<a href="https://crates.io/crates/bastion">
<img alt="Crates.io" src="https://img.shields.io/crates/v/bastion.svg?style=popout-square">
</a>
</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>License</td>
<td>
<a href="https://github.com/vertexclique/bastion/blob/master/LICENSE">
<img alt="Crates.io" src="https://img.shields.io/crates/l/bastion.svg?style=popout-square">
</a>
</td>
</tr>
<tr>
<td>Build Status</td>
<td>
<a href="https://travis-ci.org/vertexclique/bastion">
<img src="https://travis-ci.org/vertexclique/bastion.svg?branch=master" alt="travis build status" />
</a>
</td>
</tr>
<tr>
<td>Downloads</td>
<td>
<a href="https://crates.io/crates/bastion">
<img alt="Crates.io" src="https://img.shields.io/crates/d/bastion.svg?style=popout-square">
</a>
</td>
</tr>
<tr>
<td>Gitter</td>
<td>
<a href="https://gitter.im/bastionframework/community">
<img src="https://badges.gitter.im/Join%20Chat.svg" />
</a>
</td>
</tr>
</table>

---

Bastion is a Fault-tolerant Runtime for Rust applications.
It detect panics during runs of your code and serves a runtime to
prevent abrubt exits. Also, it enables you to continue serving in case of
a failure. You can select your own recovery scenario, scale your workers and
define whole application on top of it.

---

## Usage

Bastion comes with a default one-for-one strategy root supervisor.
You can use this to launch automatically supervised tasks.

Check [root supervisor](https://github.com/vertexclique/bastion/blob/master/examples/root_spv.rs) example in examples.

[Examples](https://github.com/vertexclique/bastion/blob/master/examples) cover all the use cases in the frame of the crate.

In most simple way you can use Bastion like here:
```rust
use bastion::bastion::Bastion;
use bastion::spawn::RuntimeSpawn;
use bastion::child::Message;

fn main() {
Bastion::platform();

let message = String::from("Some message to be passed");

Bastion::spawn(
|_context, msg: Box<dyn Message>| {
let received_msg = msg.as_any().downcast_ref::<String>().unwrap();

println!("Received message: {:?}", received_msg);
println!("root supervisor - spawn_at_root - 1");
},
message,
);

Bastion::start()
}
```

## Structure of the Runtime

Runtime is structured by the user. Only root supervision comes in batteries-included fashion.
Worker code, worker group redundancy, supervisors and their supervision strategies are defined by the user.

You can see overall architecture of the framework here:
![](img/bastion-arch.png)


## License

License is [MIT](https://github.com/vertexclique/bastion/blob/master/LICENSE)

## Documentation

Official documentation is hosted on [docs.rs](https://docs.rs/bastion).

## Getting Help
Please head to our [Gitter](https://gitter.im/bastionframework/community) or use [StackOverflow](https://stackoverflow.com/questions/tagged/bastionframework)

## Discussion and Development
We use [Gitter](https://gitter.im/bastionframework/community) for development discussions. Also please don't hesitate to open issues on GitHub ask for features, report bugs, comment on design and more!
More interaction and more ideas are better!

## Contributing to Bastion [![Open Source Helpers](https://www.codetriage.com/vertexclique/bastion/badges/users.svg)](https://www.codetriage.com/vertexclique/bastion)

All contributions, bug reports, bug fixes, documentation improvements, enhancements and ideas are welcome.

A detailed overview on how to contribute can be found in the [CONTRIBUTING guide](.github/CONTRIBUTING.md) on GitHub.

### Thanks

Thanks to my dear mom (Günnur Bulut) who is an artist with many things to do but
spending her efforts without any hesitation on small things that I requested
(Like this logo). My shining star.

Also thanks to my friend [Berkan Yavrı](http://github.com/yavrib) who came with the idea of making this.
Debated over the approaches that I took, spent time on thinking of this project with me.
26 changes: 26 additions & 0 deletions examples/root_spv.rs
@@ -0,0 +1,26 @@
use bastion::bastion::Bastion;
use bastion::child::Message;
use bastion::context::BastionContext;
use bastion::spawn::RuntimeSpawn;

fn main() {
Bastion::platform();

let message = String::from("Some message to be passed");

Bastion::spawn(
|context: BastionContext, msg: Box<dyn Message>| {
// Message can be casted and reused here.
let received_msg = msg.as_any().downcast_ref::<String>().unwrap();

println!("Received message: {:?}", received_msg);
println!("root supervisor - spawn_at_root - 1");

// Rebind to the system
context.hook();
},
message,
);

Bastion::start()
}
47 changes: 47 additions & 0 deletions examples/spv_one_for_all.rs
@@ -0,0 +1,47 @@
use bastion::bastion::Bastion;
use bastion::context::BastionContext;
use bastion::supervisor::SupervisionStrategy;
use std::{fs, thread};

fn main() {
Bastion::platform();

let message = "Supervision Message".to_string();
let message2 = "Some Other Message".to_string();

// Name of the supervisor, and system of the new supervisor
// By default if you don't specify Supervisors use "One for One".
// We are going to take a look at "One For All" strategy.
Bastion::supervisor("background-worker", "new-system")
.strategy(SupervisionStrategy::OneForAll)
.children(
|p: BastionContext, _msg| {
println!("File below doesn't exist so it will panic.");
fs::read_to_string("kakafoni").unwrap();

// Hook to rebind to the system.
p.hook();
},
message,
1_i32,
)
.children(
|p: BastionContext, _msg| {
// No early exit
let mut i = 0;
loop {
i = i + 1;
// Start everyone under this supervisor. Immediately for all of them.
println!("Going to fail {} :: {:?}", i, thread::current());

// Hook to rebind to the system.
p.clone().hook();
}
},
message2,
2_i32,
)
.launch();

Bastion::start()
}
51 changes: 51 additions & 0 deletions examples/spv_one_for_one.rs
@@ -0,0 +1,51 @@
use bastion::bastion::Bastion;
use bastion::context::BastionContext;
use bastion::supervisor::SupervisionStrategy;
use std::{fs, thread};

fn main() {
Bastion::platform();

let message = "Supervision Message".to_string();
let message2 = "Some Other Message".to_string();

// Name of the supervisor, and system of the new supervisor
// By default if you don't specify Supervisors use "One for One".
// Let's look at "One for One".
Bastion::supervisor("background-worker", "new-system")
.strategy(SupervisionStrategy::OneForOne)
.children(
|p: BastionContext, _msg| {
println!("File below doesn't exist so it will panic.");
fs::read_to_string("kakafoni").unwrap();

// Hook to rebind to the system.
p.hook();
},
message,
1_i32,
)
.children(
|p: BastionContext, _msg| {
// No early exit
let mut i = 0;
loop {
i = i + 1;
println!(
"This is not going to fail. \
One for One strategy behavior. {} :: {:?}",
i,
thread::current()
);

// Hook to rebind to the system.
p.clone().hook();
}
},
message2,
2_i32,
)
.launch();

Bastion::start()
}

0 comments on commit be42fad

Please sign in to comment.