dependency.rs 2.29 KB
Newer Older
SamwiseFilmore's avatar
SamwiseFilmore committed
1
use std::collections::HashMap;
2

SamwiseFilmore's avatar
SamwiseFilmore committed
3
use failure::{Error, err_msg};
SamwiseFilmore's avatar
SamwiseFilmore committed
4
use generational_arena::Index;
5

SamwiseFilmore's avatar
SamwiseFilmore committed
6 7
use dependency_graph::DepGraph;
use service::{Service, State};
8

SamwiseFilmore's avatar
SamwiseFilmore committed
9 10
pub fn graph_from_services(mut services: Vec<Service>) -> DepGraph<Service> {
    let mut graph = DepGraph::with_capacity(services.len());
11
    
SamwiseFilmore's avatar
SamwiseFilmore committed
12 13 14 15 16 17 18 19
    let services: HashMap<String, Index> = services.drain(..)
        .map(|service| (service.name.clone(), graph.insert(service)) )
        .collect();
    
    for parent in services.values() {
        let dependencies = graph.get(*parent)
            .expect("services were just added")
            .dependencies.clone();
20
        
SamwiseFilmore's avatar
SamwiseFilmore committed
21 22 23 24 25 26 27 28 29
        if let Some(ref dependencies) = dependencies {
            for dependency in dependencies.iter() {
                match services.get(dependency) {
                    Some(child) => graph.dependency(*parent, *child)
                        .unwrap_or_else(|_| warn!("failed to add dependency") ),
                    // It's not a super big deal if a dependency doesn't exist
                    // I mean, it is, but IDK what to do in that situation
                    //   It's really a pkg problem at that point
                    None => warn!("dependency not found: {}", dependency)
30 31 32 33
                }
            }
        }
    }
SamwiseFilmore's avatar
SamwiseFilmore committed
34 35
    graph
}
36

SamwiseFilmore's avatar
SamwiseFilmore committed
37 38 39 40 41 42 43
pub fn start_services(mut graph: DepGraph<Service>, provide_hooks: HashMap<String, impl Fn()>) -> Result<(), Error> {
    let resolved = graph.linear_resolve();
    
    for index in resolved.iter() {
        let service = graph.get_mut(*index)
            // These should all exist, we just got them out
            .expect("resolved service index did not exist");
SamwiseFilmore's avatar
SamwiseFilmore committed
44
        
SamwiseFilmore's avatar
SamwiseFilmore committed
45 46 47 48 49
        if let Some(method) = service.methods.get("start") {
            method.wait();
        } else {
            let msg = format!("service {} missing 'start' method", service.name);
            return Err(err_msg(msg));
50
        }
SamwiseFilmore's avatar
SamwiseFilmore committed
51
        
SamwiseFilmore's avatar
SamwiseFilmore committed
52 53 54 55 56 57 58 59
        //TODO: Better solution to this
        //  Should be able to get rid of the mutable borrow here I hope
        service.state = State::Online;
        
        if let Some(ref provides) = service.provides {
            for provide in provides.iter() {
                if let Some(on_provided) = provide_hooks.get(provide) {
                    on_provided();
SamwiseFilmore's avatar
SamwiseFilmore committed
60 61 62 63
                }
            }
        }
    }
SamwiseFilmore's avatar
SamwiseFilmore committed
64
    Ok(())
65
}