-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/service persistence #171
Changes from all commits
5ac7454
e30f3f7
516a32a
b398c5c
6dbc755
fd103cd
a0993b4
6d8f443
03f37f6
53665e3
6609439
342bef8
e7cef03
8c0fca5
73a05ec
97b6a0e
0d17414
e7730c3
0d0bc33
7bd7ede
d5eed7e
656f79a
1a4a43f
397853c
1343af0
cb349aa
8235ccc
85397d4
9ff3420
131e976
9a96713
2543516
21bd0e8
614b60a
9bfa746
11d606a
1cbb6f2
bdcfe81
a341f52
b260879
44a49d1
c45e85d
1d82585
9b9fed7
bcac889
1dd7460
348260c
e7c11d5
24f9152
ab993d7
a65d6b4
98cc48f
9eecac4
d5dea8e
522ac8b
76d7c6d
58c7f52
6d7fb2a
eba02a0
04d2ac0
dd854d3
e43b950
c0231ab
afa624c
5997556
f81441e
4d4ecb9
cf5e7bb
b685903
324a6c4
66bda28
535ae4a
d7be512
36fdbb5
36d4f04
8737a0e
1986839
c547751
2da3a8b
a4ec792
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,4 +6,5 @@ | |
target | ||
.env | ||
/.vscode/settings.json | ||
validator/.vscode | ||
sample-configs/validator-config.toml |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# For documentation on how to configure this file, | ||
# see diesel.rs/guides/configuring-diesel-cli | ||
|
||
[print_schema] | ||
file = "src/schema.rs" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use super::*; | ||
use bodyparser::Struct; | ||
use iron::mime::Mime; | ||
use iron::status; | ||
use iron::Handler; | ||
|
||
/// Holds data for a capacity update (json) | ||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Capacity { | ||
value: usize, | ||
} | ||
|
||
pub struct Update { | ||
service: Arc<Mutex<mixmining::Service>>, | ||
} | ||
|
||
impl Update { | ||
pub fn new(service: Arc<Mutex<mixmining::Service>>) -> Update { | ||
Update { service } | ||
} | ||
} | ||
|
||
impl Handler for Update { | ||
fn handle(&self, req: &mut Request) -> IronResult<Response> { | ||
let json_parse = req.get::<Struct<Capacity>>(); | ||
|
||
if json_parse.is_ok() { | ||
let capacity = json_parse | ||
.unwrap() | ||
.expect("Unexpected JSON parsing problem") | ||
.value; | ||
self.service.lock().unwrap().set_capacity(capacity); | ||
Ok(Response::with(status::Created)) | ||
} else { | ||
let error = json_parse.unwrap_err(); | ||
Ok(Response::with((status::BadRequest, error.detail))) | ||
} | ||
} | ||
} | ||
|
||
pub struct Get { | ||
service: Arc<Mutex<mixmining::Service>>, | ||
} | ||
|
||
impl Get { | ||
pub fn new(service: Arc<Mutex<mixmining::Service>>) -> Get { | ||
Get { service } | ||
} | ||
} | ||
|
||
impl Handler for Get { | ||
fn handle(&self, _: &mut Request) -> IronResult<Response> { | ||
let content_type = "application/json".parse::<Mime>().unwrap(); | ||
let value = self.service.lock().unwrap().capacity(); | ||
let c = Capacity { value }; | ||
let json = serde_json::to_string(&c).unwrap(); | ||
Ok(Response::with((content_type, status::Ok, json))) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,33 +11,62 @@ | |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
use crate::services::mixmining; | ||
use iron::prelude::*; | ||
use presence::mixnode; | ||
use presence::topology; | ||
use router::Router; | ||
use std::sync::{Arc, Mutex}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be entirely wrong about this, but this is based on some random comments on the internet I've read (so the most reliable source there is), but I think in an async setup, like we have here, i.e. tokio runtime, we want to be using this mutex: https://docs.rs/futures/0.3.4/futures/lock/struct.Mutex.html . As from what I understand, waiting for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am blocking way more than I need to anyway - I'm planning to move the mutex from the Service (where it is now) to the level of each individual datastore (when those exist), because right now every request is basically going to hit the mutex for every other request. I'll switch mutexes when I do that next bit of work (right now I only have 1 datastore so it doesn't really make much difference) - if you happen to have the source on the futures vs std mutex please shoot it to me in Keybase, I'm interested to see! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be totally wrong about this, however, based on some comments I've read on the internet (so the most reliable source on the planet), you want to be using this mutex: https://docs.rs/futures/0.3.4/futures/lock/struct.Mutex.html . As from what I understand, |
||
|
||
mod models; | ||
mod routes; | ||
mod capacity; | ||
mod presence; | ||
mod staking; | ||
|
||
pub struct Api {} | ||
pub struct Api { | ||
mixmining_service: Arc<Mutex<mixmining::Service>>, | ||
} | ||
|
||
impl Api { | ||
pub fn new() -> Api { | ||
Api {} | ||
pub fn new(mixmining_service: mixmining::Service) -> Api { | ||
let service = Arc::new(Mutex::new(mixmining_service)); | ||
Api { | ||
mixmining_service: service, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at how many places are using |
||
} | ||
} | ||
|
||
/// Run the REST API. | ||
pub async fn run(self) { | ||
let port = 3000; | ||
println!("* starting REST API on localhost:{}", port); | ||
let port = 3000; // TODO: make this configurable | ||
let address = format!("localhost:{}", port); | ||
println!("* starting REST API on http://{}", address); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we be consistent and use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a difference between log messages (which I think are mostly for developers) and output messages (which should always exist and not be configurable by log level). There is no situation in which I ever want the startup messages about components to not print out (e.g. if somebody knocked log level down). I think maybe we need to argue this one out a bit more, but I'd say the reverse: some of the things that are currently configured as log messages actually are not - they're important messages from the running system to the user. Things like major subsystems starting, progress messages etc are not things that I think should be configurable as log messages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we be consistent and use |
||
|
||
let router = self.setup_router(); | ||
|
||
let router = self.setup_routes(); | ||
Iron::new(router) | ||
.http(format!("localhost:{}", port)) | ||
.unwrap(); | ||
Iron::new(router).http(address).unwrap(); | ||
} | ||
|
||
pub fn setup_routes(&self) -> Router { | ||
/// Tie together URL route paths with handler functions. | ||
fn setup_router(self) -> Router { | ||
// define a Router to hold our routes | ||
let mut router = Router::new(); | ||
router.get("/topology", routes::topology::get, "topology_get"); | ||
|
||
// set up handlers | ||
let capacity_update = capacity::Update::new(Arc::clone(&self.mixmining_service)); | ||
let capacity_get = capacity::Get::new(Arc::clone(&self.mixmining_service)); | ||
let presence_mixnode_create = | ||
mixnode::CreatePresence::new(Arc::clone(&self.mixmining_service)); | ||
let topology_get = topology::GetTopology::new(Arc::clone(&self.mixmining_service)); | ||
|
||
// tie routes to handlers | ||
router.get("/capacity", capacity_get, "capacity_get"); | ||
router.post("/capacity", capacity_update, "capacity_update"); | ||
router.get("/topology", topology_get, "topology_get"); | ||
router.post( | ||
"/presence/mixnodes", | ||
presence_mixnode_create, | ||
"presence_mixnodes_post", | ||
); | ||
|
||
router | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will be using this very soon for better time units in config files : )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. I had it in my validator implementation for a little bit, then it came out. I was planning to either delete or uncomment when it become totally clear if I'd really need it.