Compare commits

...

9 Commits

Author SHA1 Message Date
Paul van Tilburg c070877384
Bump the version to 0.3.0
Check, Test and Lint Using Cargo / Lints (push) Successful in 3m8s Details
Check, Test and Lint Using Cargo / Check (push) Successful in 2m39s Details
2023-04-15 12:16:30 +02:00
Paul van Tilburg 732d4b83f2
Update the changelog 2023-04-15 12:15:40 +02:00
Paul van Tilburg 12a797baa9
Cargo update
Check, Test and Lint Using Cargo / Check (push) Successful in 2m53s Details
Check, Test and Lint Using Cargo / Lints (push) Successful in 3m3s Details
2023-04-14 23:26:07 +02:00
Paul van Tilburg 5586ae4d70
Update build dependecy on the vergen crate to 8.1.1
This change allows for dropping the dependency on the `anyhow` crate.
2023-04-14 23:25:25 +02:00
Paul van Tilburg 59e3b53263
Implement backoff for login/update API calls (closes: #8)
Check, Test and Lint Using Cargo / Check (push) Successful in 3m45s Details
Check, Test and Lint Using Cargo / Lints (push) Successful in 3m35s Details
Start from an interval of 10 seconds, increase with a factor of 2.0 on
each failure up to a maximum of 320 seconds.

This commit also fixes an issue where the update loop would be aborted
if a relogin fails.
2023-04-14 23:02:21 +02:00
Paul van Tilburg f236499125
Fix login errors not being detected 2023-04-14 22:54:54 +02:00
Paul van Tilburg 02a4d1ca9b
Update to Rocket 0.5.0-rc.3
Check Details
Lints Details
2023-03-24 14:38:42 +01:00
Paul van Tilburg 3fff79a2cd
Fix missing build script/git repo during build
Check Details
Lints Details
When building the dependencies, the build script should not be
considered. When building the actual binary, the git repository needs to
be present and the build script should be run.
2023-03-22 15:27:12 +01:00
Paul van Tilburg 9200a10cef
Speed up build by using sparse Cargo index for crates.io 2023-03-22 15:26:45 +01:00
9 changed files with 328 additions and 470 deletions

View File

@ -5,9 +5,6 @@ target
Dockerfile*
docker-compose*
# Git folder
.git
# Dot files
.gitignore

View File

@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.3.0] - 2023-04-15
### Added
* Implement backoff for login/update API call failures (#8)
### Changed
* Update dependencies
* Speed up Docker image builds by using sparse Cargo index for crates.io
### Fixed
* Fix login errors not being detected for My Autarco
* Fix missing build script/git repository during Docker image build
## [0.2.2] - 2023-03-22
### Added
@ -65,7 +81,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Rename Autarco Scraper project to Solar Grabber.
[Unreleased]: https://git.luon.net/paul/solar-grabber/compare/v0.2.2...HEAD
[Unreleased]: https://git.luon.net/paul/solar-grabber/compare/v0.3.0...HEAD
[0.3.0]: https://git.luon.net/paul/solar-grabber/compare/v0.2.2...v0.3.0
[0.2.2]: https://git.luon.net/paul/solar-grabber/compare/v0.2.1...v0.2.2
[0.2.1]: https://git.luon.net/paul/solar-grabber/compare/v0.2.0...v0.2.1
[0.2.0]: https://git.luon.net/paul/solar-grabber/compare/v0.1.1...v0.2.0

709
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "solar-grabber"
version = "0.2.2"
version = "0.3.0"
authors = ["Paul van Tilburg <paul@luon.net>"]
edition = "2021"
description = """"
@ -19,13 +19,12 @@ enum_dispatch = "0.3.9"
md-5 = "0.10.5"
once_cell = "1.9.0"
reqwest = { version = "0.11.6", features = ["cookies", "json"] }
rocket = { version = "0.5.0-rc.2", features = ["json"] }
rocket = { version = "0.5.0-rc.3", features = ["json"] }
thiserror = "1.0.38"
url = "2.2.2"
[build-dependencies]
anyhow = "1.0.68"
vergen = { version = "7.5.0", default_features = false, features = ["build", "git"] }
vergen = { version = "8.1.1", features = ["build", "git", "gitcl"] }
[package.metadata.deb]
maintainer = "Paul van Tilburg <paul@luon.net>"

View File

@ -7,13 +7,16 @@
FROM docker.io/rust:1 as builder
# Build the dependencies first
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
RUN USER=root cargo new --bin /usr/src/solar-grabber
WORKDIR /usr/src/solar-grabber
COPY ./Cargo.* ./
RUN sed -i -e 's/^build =/#build =/' Cargo.toml
RUN cargo build --release
RUN rm src/*.rs
# Add the real project files from current folder
COPY ./Cargo.toml ./
ADD . ./
# Build the actual binary from the copied local files

View File

@ -1,7 +1,9 @@
use anyhow::Result;
use vergen::{vergen, Config};
use std::error::Error;
use vergen::EmitBuilder;
fn main() -> Result<()> {
fn main() -> Result<(), Box<dyn Error>> {
// Generate the `cargo:` instructions to fill the appropriate environment variables.
vergen(Config::default())
EmitBuilder::builder().all_build().all_git().emit()?;
Ok(())
}

View File

@ -97,7 +97,7 @@ impl VersionInfo {
/// Retrieves the version information from the environment variables.
fn new() -> Self {
Self {
version: String::from(env!("VERGEN_BUILD_SEMVER")),
version: String::from(env!("CARGO_PKG_VERSION")),
timestamp: String::from(env!("VERGEN_BUILD_TIMESTAMP")),
git_sha: String::from(&env!("VERGEN_GIT_SHA")[0..7]),
git_timestamp: String::from(env!("VERGEN_GIT_COMMIT_TIMESTAMP")),
@ -142,7 +142,7 @@ pub fn setup() -> Rocket<Build> {
.attach(AdHoc::on_liftoff("Version", |_| {
Box::pin(async move {
let name = env!("CARGO_PKG_NAME");
let version = env!("VERGEN_BUILD_SEMVER");
let version = env!("CARGO_PKG_VERSION");
let git_sha = &env!("VERGEN_GIT_SHA")[0..7];
println!("☀️ Started {name} v{version} (git @{git_sha})");

View File

@ -92,14 +92,17 @@ impl super::Service for Service {
/// It mainly stores the acquired cookie in the client's cookie jar. The login credentials come
/// from the loaded configuration (see [`Config`]).
async fn login(&mut self) -> Result<()> {
let login_url = login_url().expect("valid login URL");
let params = [
("username", &self.config.username),
("password", &self.config.password),
];
let login_url = login_url().expect("valid login URL");
self.client.post(login_url).form(&params).send().await?;
Ok(())
let response = self.client.post(login_url).form(&params).send().await?;
match response.error_for_status() {
Ok(_) => Ok(()),
Err(e) if e.status() == Some(StatusCode::UNAUTHORIZED) => Err(Error::NotAuthorized),
Err(e) => Err(e.into()),
}
}
/// Retrieves a status update from the API of the My Autarco site.

View File

@ -9,6 +9,22 @@ use crate::{
STATUS,
};
/// The default sleep interval to use between checks.
const DEFAULT_SLEEP_INTERVAL: u64 = 10;
/// The sleep interval upper limit when applying exponential backoff.
const MAX_SLEEP_INTERVAL: u64 = 320;
/// The backoff factor.
const BACKOFF_FACTOR: f64 = 2.0;
/// Calculates the new interval by applying the backoff factor and taking the maximum into account.
fn back_off(interval: u64) -> u64 {
let new_interval = (interval as f64 * BACKOFF_FACTOR) as u64;
new_interval.min(MAX_SLEEP_INTERVAL)
}
/// Main update loop that logs in and periodically acquires updates from the API.
///
/// It updates the mutex-guarded current update [`Status`](crate::Status) struct which can be
@ -23,9 +39,10 @@ pub(super) async fn update_loop(service: Services) -> color_eyre::Result<()> {
let mut last_updated = 0;
let poll_interval = service.poll_interval();
let mut sleep_interval = DEFAULT_SLEEP_INTERVAL;
loop {
// Wake up every 10 seconds and check if an update is due.
sleep(Duration::from_secs(10)).await;
sleep(Duration::from_secs(sleep_interval)).await;
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
@ -39,15 +56,24 @@ pub(super) async fn update_loop(service: Services) -> color_eyre::Result<()> {
Ok(status) => status,
Err(Error::NotAuthorized) => {
eprintln!("💥 Update unauthorized, trying to log in again...");
service.login().await?;
if let Err(e) = service.login().await {
eprintln!("💥 Login failed: {e}; will retry in {sleep_interval} seconds...");
sleep_interval = back_off(sleep_interval);
continue;
};
println!("⚡ Logged in successfully!");
sleep_interval = DEFAULT_SLEEP_INTERVAL;
continue;
}
Err(e) => {
eprintln!("💥 Failed to update status: {}", e);
eprintln!(
"💥 Failed to update status: {e}; will retry in {sleep_interval} seconds..."
);
sleep_interval = back_off(sleep_interval);
continue;
}
};
sleep_interval = DEFAULT_SLEEP_INTERVAL;
last_updated = timestamp;
println!("⚡ Updated status to: {:#?}", status);