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]

Reply via email to