Attempt to bind to the listen address before starting server. (#92)
This commit is contained in:
parent
5783ee2b51
commit
0c91dd9d7a
|
@ -7,7 +7,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
<!-- next-header -->
|
||||
|
||||
## [Unreleased] - ReleaseDate
|
||||
|
||||
## [0.1.0] - 2019-07-29
|
||||
### Added
|
||||
- Effective birth of the crate.
|
||||
|
|
|
@ -22,6 +22,7 @@ hdrhistogram = "7.1"
|
|||
hyper = { version = "0.13", default-features = false, features = ["tcp"] }
|
||||
tokio = { version = "0.2", features = ["rt-core", "tcp", "time", "macros"] }
|
||||
parking_lot = "0.11"
|
||||
thiserror = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
quanta = "0.6"
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// 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.
|
|
@ -29,7 +29,7 @@ fn main() {
|
|||
"The time taken for iterations of the TCP server event loop."
|
||||
);
|
||||
|
||||
let clock = Clock::new();
|
||||
let mut clock = Clock::new();
|
||||
let mut last = None;
|
||||
|
||||
// Loop over and over, pretending to do some work.
|
||||
|
|
|
@ -17,31 +17,26 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
|||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::{collections::HashMap, time::SystemTime};
|
||||
use thiserror::Error as ThisError;
|
||||
use tokio::{pin, runtime, select};
|
||||
|
||||
type PrometheusRegistry = Registry<CompositeKey, Handle>;
|
||||
type HdrHistogram = hdrhistogram::Histogram<u64>;
|
||||
|
||||
/// Errors that could occur while installing a Prometheus recorder/exporter.
|
||||
#[derive(Debug)]
|
||||
#[derive(ThisError, Debug)]
|
||||
pub enum Error {
|
||||
/// Creating the networking event loop did not succeed.
|
||||
Io(io::Error),
|
||||
#[error("failed to spawn Tokio runtime for endpoint: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
|
||||
/// Binding/listening to the given address did not succeed.
|
||||
#[error("failed to bind to given listen address: {0}")]
|
||||
Hyper(#[from] HyperError),
|
||||
|
||||
/// Installing the recorder did not succeed.
|
||||
Recorder(SetRecorderError),
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(e: io::Error) -> Self {
|
||||
Error::Io(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SetRecorderError> for Error {
|
||||
fn from(e: SetRecorderError) -> Self {
|
||||
Error::Recorder(e)
|
||||
}
|
||||
#[error("failed to install exporter as global recorder: {0}")]
|
||||
Recorder(#[from] SetRecorderError),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -420,7 +415,7 @@ impl PrometheusBuilder {
|
|||
/// An error will be returned if there's an issue with creating the HTTP server or with
|
||||
/// installing the recorder as the global recorder.
|
||||
pub fn install(self) -> Result<(), Error> {
|
||||
let (recorder, exporter) = self.build();
|
||||
let (recorder, exporter) = self.build()?;
|
||||
metrics::set_boxed_recorder(Box::new(recorder))?;
|
||||
|
||||
let mut runtime = runtime::Builder::new()
|
||||
|
@ -452,10 +447,13 @@ impl PrometheusBuilder {
|
|||
/// provides the flexibility to do so.
|
||||
pub fn build(
|
||||
self,
|
||||
) -> (
|
||||
PrometheusRecorder,
|
||||
impl Future<Output = Result<(), HyperError>> + Send + Sync + 'static,
|
||||
) {
|
||||
) -> Result<
|
||||
(
|
||||
PrometheusRecorder,
|
||||
impl Future<Output = Result<(), HyperError>> + Send + Sync + 'static,
|
||||
),
|
||||
Error,
|
||||
> {
|
||||
let inner = Arc::new(Inner {
|
||||
registry: Registry::new(),
|
||||
distributions: RwLock::new(HashMap::new()),
|
||||
|
@ -470,6 +468,8 @@ impl PrometheusBuilder {
|
|||
};
|
||||
|
||||
let address = self.listen_address;
|
||||
let server = Server::try_bind(&address)?;
|
||||
|
||||
let exporter = async move {
|
||||
let make_svc = make_service_fn(move |_| {
|
||||
let inner = inner.clone();
|
||||
|
@ -486,10 +486,10 @@ impl PrometheusBuilder {
|
|||
}
|
||||
});
|
||||
|
||||
Server::bind(&address).serve(make_svc).await
|
||||
server.serve(make_svc).await
|
||||
};
|
||||
|
||||
(recorder, exporter)
|
||||
Ok((recorder, exporter))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue