summaryrefslogtreecommitdiffstats
path: root/src/filestore/merged.rs
blob: 0b19d8557c1cf9d4ab9e109aceb21c147c7e0700 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//
// Copyright (c) 2020-2021 science+computing ag and other contributors
//
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//

// TODO: The MergedStores is not used at all anymore, because we removed the feature while doing
// the rewrite
#![allow(unused)]


use std::sync::Arc;
use std::path::Path;

use anyhow::Result;
use getset::Getters;
use log::trace;
use tokio::sync::RwLock;

use crate::filestore::Artifact;
use crate::filestore::path::ArtifactPath;
use crate::filestore::ReleaseStore;
use crate::filestore::StagingStore;


/// A type that merges the release store and the staging store
///
/// The stores are not actually merged (on disk or in memory), but the querying mechanism works in
/// a way where it _always_ preferes the staging store over the release store.
///
#[derive(Getters)]
pub struct MergedStores {
    release: Arc<RwLock<ReleaseStore>>,

    #[getset(get = "pub")]
    staging: Arc<RwLock<StagingStore>>,
}

impl MergedStores {
    pub fn new(release: Arc<RwLock<ReleaseStore>>, staging: Arc<RwLock<StagingStore>>) -> Self {
        MergedStores { release, staging }
    }

    pub async fn get_artifact_by_path(&self, p: &Path) -> Result<Option<Artifact>> {
        trace!("Fetching artifact from path: {:?}", p.display());
        let artifact_path = ArtifactPath::new(p.to_path_buf())?;

        let staging = &mut self.staging.write().await.0;
        let staging_path = staging.root_path().join(&artifact_path)?;
        trace!("staging_path = {:?}", staging_path.display());

        if staging_path.exists() {
            let art = if let Some(art) = staging.get(&artifact_path) {
                art
            } else {
                trace!("Loading path from staging store: {:?}", artifact_path.display());
                staging.load_from_path(&artifact_path)?
            };

            return Ok(Some(art.clone()))
        }

        let release = &mut self.release.write().await.0;
        let release_path = release.root_path().join(&artifact_path)?;
        trace!("release_path = {:?}", release_path);

        if release_path.exists() {
            let art = if let Some(art) = release.get(&artifact_path) {
                art
            } else {
                trace!("Loading path from release store: {:?}", artifact_path.display());
                release.load_from_path(&artifact_path)?
            };
            return Ok(Some(art.clone()))
        }

        Ok(None)
    }
}