kwsc98 commented on code in PR #184:
URL: https://github.com/apache/dubbo-rust/pull/184#discussion_r1528190054
##########
dubbo/src/extension/mod.rs:
##########
@@ -141,61 +141,95 @@ impl ExtensionDirectory {
}
}
+type ExtensionCreator<T> = Box<
+ dyn Fn(Url) -> Pin<Box<dyn Future<Output = Result<T, StdError>> + Send +
'static>>
+ + Send
+ + Sync
+ + 'static,
+>;
+pub(crate) struct ExtensionPromiseResolver<T> {
+ resolved_data: Option<T>,
+ creator: ExtensionCreator<T>,
+ url: Url,
+}
+
+impl<T> ExtensionPromiseResolver<T>
+where
+ T: Send + Clone + 'static,
+{
+ fn new(creator: ExtensionCreator<T>, url: Url) -> Self {
+ ExtensionPromiseResolver {
+ resolved_data: None,
+ creator,
+ url,
+ }
+ }
+
+ fn resolved_data(&self) -> Option<T> {
+ self.resolved_data.clone()
+ }
+
+ async fn resolve(&mut self) -> Result<T, StdError> {
+ match (self.creator)(self.url.clone()).await {
+ Ok(data) => {
+ self.resolved_data = Some(data.clone());
+ Ok(data)
+ }
+ Err(err) => {
+ error!("create extension failed: {}", err);
+ Err(LoadExtensionError::new(
+ "load extension failed, create extension occur an
error".to_string(),
+ )
+ .into())
+ }
+ }
+ }
+}
+
pub(crate) struct LoadExtensionPromise<T> {
- extension: Arc<Option<T>>,
- fut: Option<Pin<Box<dyn Future<Output = Result<T, StdError>> + Send +
'static>>>,
- semaphore: Arc<Semaphore>,
+ resolver: Arc<RwLock<ExtensionPromiseResolver<T>>>,
}
impl<T> LoadExtensionPromise<T>
where
T: Send + Clone + 'static,
{
- pub(crate) fn new(
- fut: Pin<Box<dyn Future<Output = Result<T, StdError>> + Send +
'static>>,
- ) -> Self {
+ pub(crate) fn new(creator: ExtensionCreator<T>, url: Url) -> Self {
+ let resolver = ExtensionPromiseResolver::new(creator, url);
LoadExtensionPromise {
- extension: Arc::new(None),
- fut: Some(fut),
- semaphore: Arc::new(Semaphore::new(0)),
+ resolver: Arc::new(RwLock::new(resolver)),
}
}
- fn get_extension(&self) -> Option<T> {
- self.extension.as_ref().as_ref().map(|a| a.clone())
- }
-
pub(crate) async fn resolve(&mut self) -> Result<T, StdError> {
Review Comment:
Can be simplified like
```rust
pub(crate) async fn resolve(&mut self) -> Result<T, StdError> {
// get read lock
let resolver_read_lock = self.resolver.read().await;
// if extension is not None, return it
if let Some(extension) = resolver_read_lock.resolved_data() {
return Ok(extension);
}
drop(resolver_read_lock);
let mut resolver_write_lock = self.resolver.write().await;
Ok(match resolver_write_lock.resolved_data() {
Some(data) => data,
None => resolver_write_lock.resolve().await?,
})
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]