config.rs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. use crate::github::GithubClient;
  2. use failure::Error;
  3. use std::collections::HashMap;
  4. use std::sync::{Arc, RwLock};
  5. use std::time::{Duration, Instant};
  6. static CONFIG_FILE_NAME: &str = "triagebot.toml";
  7. const REFRESH_EVERY: Duration = Duration::from_secs(2 * 60); // Every two minutes
  8. lazy_static::lazy_static! {
  9. static ref CONFIG_CACHE: RwLock<HashMap<String, (Arc<Config>, Instant)>> =
  10. RwLock::new(HashMap::new());
  11. }
  12. #[derive(serde::Deserialize)]
  13. pub(crate) struct Config {
  14. pub(crate) relabel: Option<RelabelConfig>,
  15. pub(crate) assign: Option<AssignConfig>,
  16. }
  17. #[derive(serde::Deserialize)]
  18. pub(crate) struct AssignConfig {
  19. #[serde(default)]
  20. _empty: (),
  21. }
  22. #[derive(serde::Deserialize)]
  23. #[serde(rename_all = "kebab-case")]
  24. pub(crate) struct RelabelConfig {
  25. #[serde(default)]
  26. pub(crate) allow_unauthenticated: Vec<String>,
  27. }
  28. pub(crate) fn get(gh: &GithubClient, repo: &str) -> Result<Arc<Config>, Error> {
  29. if let Some(config) = get_cached_config(repo) {
  30. Ok(config)
  31. } else {
  32. get_fresh_config(gh, repo)
  33. }
  34. }
  35. fn get_cached_config(repo: &str) -> Option<Arc<Config>> {
  36. let cache = CONFIG_CACHE.read().unwrap();
  37. cache.get(repo).and_then(|(config, fetch_time)| {
  38. if fetch_time.elapsed() < REFRESH_EVERY {
  39. Some(config.clone())
  40. } else {
  41. None
  42. }
  43. })
  44. }
  45. fn get_fresh_config(gh: &GithubClient, repo: &str) -> Result<Arc<Config>, Error> {
  46. let contents = gh
  47. .raw_file(repo, "master", CONFIG_FILE_NAME)?
  48. .ok_or_else(|| {
  49. failure::err_msg(
  50. "This repository is not enabled to use triagebot.\n\
  51. Add a `triagebot.toml` in the root of the master branch to enable it.",
  52. )
  53. })?;
  54. let config = Arc::new(toml::from_slice::<Config>(&contents)?);
  55. CONFIG_CACHE
  56. .write()
  57. .unwrap()
  58. .insert(repo.to_string(), (config.clone(), Instant::now()));
  59. Ok(config)
  60. }