Skip to content

Commit d929b6e

Browse files
andyleejordanSteveL-MSFT
authored andcommitted
WIP: Example using functional programming
1 parent 3f8d616 commit d929b6e

File tree

4 files changed

+60
-107
lines changed

4 files changed

+60
-107
lines changed

dsc_lib/src/discovery/command_discovery.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@
22
// Licensed under the MIT License.
33

44
use crate::discovery::{
5-
command_discovery_cache::{
6-
adapters_is_empty, extend_adapted_resources, extend_adapters, extend_extensions, extend_resources, extensions_is_empty,
7-
get_adapted_resource, get_adapted_resources, get_adapters, get_extensions, get_resource, get_resources, resources_is_empty,
8-
},
95
discovery_trait::{DiscoveryFilter, DiscoveryKind, ResourceDiscovery}
106
};
7+
use crate::{locked_is_empty, locked_extend, locked_clone, locked_get};
118
use crate::dscresources::dscresource::{Capability, DscResource, ImplementedAs};
129
use crate::dscresources::resource_manifest::{import_manifest, validate_semver, Kind, ResourceManifest, SchemaKind};
1310
use crate::dscresources::command_resource::invoke_command;
@@ -21,7 +18,7 @@ use rust_i18n::t;
2118
use semver::{Version, VersionReq};
2219
use schemars::JsonSchema;
2320
use serde::{Deserialize, Serialize};
24-
use std::collections::{BTreeMap, HashSet, HashMap};
21+
use std::{collections::{BTreeMap, HashMap, HashSet}, sync::{LazyLock, Mutex}};
2522
use std::env;
2623
use std::ffi::OsStr;
2724
use std::fs;
@@ -36,6 +33,12 @@ use crate::util::get_exe_path;
3633
const DSC_RESOURCE_EXTENSIONS: [&str; 3] = [".dsc.resource.json", ".dsc.resource.yaml", ".dsc.resource.yml"];
3734
const DSC_EXTENSION_EXTENSIONS: [&str; 3] = [".dsc.extension.json", ".dsc.extension.yaml", ".dsc.extension.yml"];
3835

36+
// use BTreeMap so that the results are sorted by the typename, the Vec is sorted by version
37+
static ADAPTERS: LazyLock<Mutex<BTreeMap<String, Vec<DscResource>>>> = LazyLock::new(|| Mutex::new(BTreeMap::new()));
38+
static RESOURCES: LazyLock<Mutex<BTreeMap<String, Vec<DscResource>>>> = LazyLock::new(|| Mutex::new(BTreeMap::new()));
39+
static EXTENSIONS: LazyLock<Mutex<BTreeMap<String, DscExtension>>> = LazyLock::new(|| Mutex::new(BTreeMap::new()));
40+
static ADAPTED_RESOURCES: LazyLock<Mutex<BTreeMap<String, Vec<DscResource>>>> = LazyLock::new(|| Mutex::new(BTreeMap::new()));
41+
3942
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
4043
pub enum ImportedManifest {
4144
Resource(DscResource),
@@ -79,9 +82,7 @@ impl CommandDiscovery {
7982
}
8083

8184
#[must_use]
82-
pub fn get_extensions(&self) -> BTreeMap<String, DscExtension> {
83-
get_extensions()
84-
}
85+
pub fn get_extensions(&self) -> BTreeMap<String, DscExtension> { locked_clone!(EXTENSIONS) }
8586

8687
fn get_resource_path_setting() -> Result<ResourcePathSetting, DscError>
8788
{
@@ -305,7 +306,7 @@ impl ResourceDiscovery for CommandDiscovery {
305306
match kind {
306307
DiscoveryKind::Resource => {
307308
// Now we need to call discover extensions and add those resource to the list of resources
308-
for extension in get_extensions().values() {
309+
for extension in locked_clone!(EXTENSIONS).values() {
309310
if extension.capabilities.contains(&ExtensionCapability::Discover) {
310311
debug!("{}", t!("discovery.commandDiscovery.callingExtension", extension = extension.type_name));
311312
let discovered_resources = extension.discover()?;
@@ -318,27 +319,27 @@ impl ResourceDiscovery for CommandDiscovery {
318319
}
319320
}
320321
}
321-
extend_adapters(adapters);
322-
extend_resources(resources);
322+
locked_extend!(ADAPTERS, adapters);
323+
locked_extend!(RESOURCES, resources);
323324
},
324325
DiscoveryKind::Extension => {
325-
extend_extensions(extensions);
326+
locked_extend!(EXTENSIONS, extensions);
326327
}
327328
}
328329

329330
Ok(())
330331
}
331332

332333
fn discover_adapted_resources(&mut self, name_filter: &str, adapter_filter: &str) -> Result<(), DscError> {
333-
if resources_is_empty() && adapters_is_empty() {
334+
if locked_is_empty!(RESOURCES) && locked_is_empty!(ADAPTERS) {
334335
self.discover(&DiscoveryKind::Resource, "*")?;
335336
}
336337

337-
if adapters_is_empty() {
338+
if locked_is_empty!(ADAPTERS) {
338339
return Ok(());
339340
}
340341

341-
let adapters = get_adapters();
342+
let adapters = locked_clone!(ADAPTERS);
342343
let regex_str = convert_wildcard_to_regex(adapter_filter);
343344
debug!("Using regex {regex_str} as filter for adapter name");
344345
let mut regex_builder = RegexBuilder::new(&regex_str);
@@ -430,7 +431,7 @@ impl ResourceDiscovery for CommandDiscovery {
430431
return Err(DscError::AdapterNotFound(adapter_filter.to_string()));
431432
}
432433

433-
extend_adapted_resources(adapted_resources);
434+
locked_extend!(ADAPTED_RESOURCES, adapted_resources);
434435

435436
Ok(())
436437
}
@@ -440,18 +441,18 @@ impl ResourceDiscovery for CommandDiscovery {
440441
if *kind == DiscoveryKind::Resource {
441442
if adapter_name_filter.is_empty() {
442443
self.discover(kind, type_name_filter)?;
443-
for (resource_name, resources_vec) in &get_resources() {
444+
for (resource_name, resources_vec) in &locked_clone!(RESOURCES) {
444445
resources.insert(resource_name.clone(), resources_vec.iter().map(|r| ImportedManifest::Resource(r.clone())).collect());
445446
}
446-
for (adapter_name, adapter_vec) in &get_adapters() {
447+
for (adapter_name, adapter_vec) in &locked_clone!(ADAPTERS) {
447448
resources.insert(adapter_name.clone(), adapter_vec.iter().map(|r| ImportedManifest::Resource(r.clone())).collect());
448449
}
449450
} else {
450451
self.discover(kind, "*")?;
451452
self.discover_adapted_resources(type_name_filter, adapter_name_filter)?;
452453

453454
// add/update found adapted resources to the lookup_table
454-
let adapted_resources = get_adapted_resources();
455+
let adapted_resources = locked_clone!(ADAPTED_RESOURCES);
455456
add_resources_to_lookup_table(&adapted_resources);
456457

457458
for (adapted_name, adapted_vec) in &adapted_resources {
@@ -460,7 +461,7 @@ impl ResourceDiscovery for CommandDiscovery {
460461
}
461462
} else {
462463
self.discover(kind, type_name_filter)?;
463-
for (extension_name, extension) in &get_extensions() {
464+
for (extension_name, extension) in &locked_clone!(EXTENSIONS) {
464465
resources.insert(extension_name.clone(), vec![ImportedManifest::Extension(extension.clone())]);
465466
}
466467
}
@@ -470,7 +471,7 @@ impl ResourceDiscovery for CommandDiscovery {
470471

471472
fn find_resources(&mut self, required_resource_types: &[DiscoveryFilter]) -> Result<BTreeMap<String, Vec<DscResource>>, DscError> {
472473
debug!("{}", t!("discovery.commandDiscovery.searchingForResources", resources = required_resource_types : {:?}));
473-
if resources_is_empty() {
474+
if locked_is_empty!(RESOURCES) {
474475
self.discover(&DiscoveryKind::Resource, "*")?;
475476
}
476477
let mut found_resources = BTreeMap::<String, Vec<DscResource>>::new();
@@ -480,7 +481,7 @@ impl ResourceDiscovery for CommandDiscovery {
480481
}
481482

482483
for filter in required_resource_types {
483-
if let Some(resources) = get_resource(filter.resource_type()) {
484+
if let Some(resources) = locked_get!(RESOURCES, filter.resource_type()) {
484485
filter_resources(&mut found_resources, &mut required_resources, &resources, filter);
485486
}
486487
if required_resources.values().all(|&v| v) {
@@ -494,11 +495,11 @@ impl ResourceDiscovery for CommandDiscovery {
494495
}
495496

496497
// now go through the adapters, this is for implicit adapters so version can't be specified so use latest version
497-
for adapter_name in get_adapters().keys() {
498+
for adapter_name in locked_clone!(ADAPTERS).keys() {
498499
self.discover_adapted_resources("*", adapter_name)?;
499-
add_resources_to_lookup_table(&get_adapted_resources());
500+
add_resources_to_lookup_table(&locked_clone!(ADAPTED_RESOURCES));
500501
for filter in required_resource_types {
501-
if let Some(adapted_resources) = get_adapted_resource(filter.resource_type()) {
502+
if let Some(adapted_resources) = locked_get!(ADAPTED_RESOURCES, filter.resource_type()) {
502503
filter_resources(&mut found_resources, &mut required_resources, &adapted_resources, filter);
503504
}
504505
if required_resources.values().all(|&v| v) {
@@ -514,10 +515,10 @@ impl ResourceDiscovery for CommandDiscovery {
514515
}
515516

516517
fn get_extensions(&mut self) -> Result<BTreeMap<String, DscExtension>, DscError> {
517-
if extensions_is_empty() {
518+
if locked_is_empty!(EXTENSIONS) {
518519
self.discover(&DiscoveryKind::Extension, "*")?;
519520
}
520-
Ok(get_extensions())
521+
Ok(locked_clone!(EXTENSIONS))
521522
}
522523
}
523524

dsc_lib/src/discovery/command_discovery_cache.rs

Lines changed: 0 additions & 79 deletions
This file was deleted.

dsc_lib/src/discovery/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT License.
33

44
pub mod command_discovery;
5-
mod command_discovery_cache;
65
pub mod discovery_trait;
76

87
use crate::discovery::discovery_trait::{DiscoveryKind, ResourceDiscovery, DiscoveryFilter};

dsc_lib/src/util.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,35 @@ fn get_settings_policy_file_path() -> String
212212
// This location is writable only by admins, but readable by all users
213213
Path::new("/etc").join("dsc").join("dsc.settings.json").display().to_string()
214214
}
215+
216+
#[macro_export]
217+
macro_rules! locked_is_empty {
218+
($lockable:expr) => {{
219+
$lockable.lock().unwrap().is_empty()
220+
}};
221+
}
222+
223+
#[macro_export]
224+
macro_rules! locked_extend {
225+
($lockable:expr, $items:expr) => {{
226+
$lockable.lock().unwrap().extend($items);
227+
}};
228+
}
229+
230+
#[macro_export]
231+
macro_rules! locked_clone {
232+
($lockable:expr) => {{
233+
$lockable.lock().unwrap().clone()
234+
}};
235+
}
236+
237+
#[macro_export]
238+
macro_rules! locked_get {
239+
($lockable:expr, $key:expr) => {{
240+
if let Some(v) = $lockable.lock().unwrap().get($key) {
241+
Some(v.clone())
242+
} else {
243+
None
244+
}
245+
}};
246+
}

0 commit comments

Comments
 (0)