Xuanwo commented on code in PR #3484:
URL: 
https://github.com/apache/incubator-opendal/pull/3484#discussion_r1387738037


##########
bindings/nodejs/src/lib.rs:
##########
@@ -686,6 +691,117 @@ impl PresignedRequest {
     }
 }
 
+pub trait NodeLayer: Send + Sync {
+    fn layer(&self, op: opendal::Operator) -> opendal::Operator;
+}
+
+struct NodeLayerWrapper {
+    inner: Box<dyn NodeLayer>,
+}
+
+#[napi]
+impl Operator {
+    /// Add a layer to this operator.
+    #[napi]
+    pub fn layer(&self, env: Env, layer: JsObject) -> Result<Self> {
+        let ctx: &mut NodeLayerWrapper = env
+            .unwrap(&layer)
+            .map_err(|e| Error::from_reason(format!("failed to unwrap layer: 
{}", e)))?;
+        Ok(Self(ctx.inner.layer(self.0.clone())))
+    }
+}
+
+/// A layer that will retry the request if it fails.
+/// It will retry with exponential backoff.
+///
+/// ## Parameters
+///
+/// - `jitter`<bool>: Whether to add jitter to the backoff.
+/// - `max_times`<number>: The maximum number of times to retry.
+/// - `factor`<number>: The exponential factor to use.
+/// - `max_delay`<number>: The maximum delay between retries. The unit is 
microsecond.
+/// - `min_delay`<number>: The minimum delay between retries. The unit is 
microsecond.
+#[napi]
+pub struct RetryLayer(opendal::layers::RetryLayer);
+
+impl NodeLayer for RetryLayer {
+    fn layer(&self, op: opendal::Operator) -> opendal::Operator {
+        op.layer(self.0.clone())
+    }
+}
+
+/// RetryLayer constructor.
+#[js_function(1)]
+pub fn create_retry_layer(ctx: CallContext) -> Result<JsObject> {
+    let mut retry = opendal::layers::RetryLayer::default();
+
+    let config: Either<JsObject, JsUndefined> = ctx.try_get::<JsObject>(0)?;
+
+    if let Either::A(config) = config {
+        let jitter = config.get_named_property::<JsBoolean>("jitter");
+        if let Ok(jitter) = jitter {
+            let jitter = jitter.get_value();
+            if let Ok(jitter) = jitter {
+                if jitter {
+                    retry = retry.with_jitter();
+                }
+            }
+        }
+
+        let max_times = config.get_named_property::<JsNumber>("maxTimes");
+        if let Ok(max_times) = max_times {
+            let max_times = max_times.get_uint32();
+            if let Ok(max_times) = max_times {
+                retry = retry.with_max_times(max_times as usize);
+            }
+        }
+        //

Review Comment:
   not used.



##########
bindings/nodejs/src/lib.rs:
##########
@@ -686,6 +691,117 @@ impl PresignedRequest {
     }
 }
 
+pub trait NodeLayer: Send + Sync {
+    fn layer(&self, op: opendal::Operator) -> opendal::Operator;
+}
+
+struct NodeLayerWrapper {
+    inner: Box<dyn NodeLayer>,
+}
+
+#[napi]
+impl Operator {
+    /// Add a layer to this operator.
+    #[napi]
+    pub fn layer(&self, env: Env, layer: JsObject) -> Result<Self> {
+        let ctx: &mut NodeLayerWrapper = env
+            .unwrap(&layer)
+            .map_err(|e| Error::from_reason(format!("failed to unwrap layer: 
{}", e)))?;
+        Ok(Self(ctx.inner.layer(self.0.clone())))
+    }
+}
+
+/// A layer that will retry the request if it fails.
+/// It will retry with exponential backoff.
+///
+/// ## Parameters
+///
+/// - `jitter`<bool>: Whether to add jitter to the backoff.
+/// - `max_times`<number>: The maximum number of times to retry.
+/// - `factor`<number>: The exponential factor to use.
+/// - `max_delay`<number>: The maximum delay between retries. The unit is 
microsecond.
+/// - `min_delay`<number>: The minimum delay between retries. The unit is 
microsecond.
+#[napi]
+pub struct RetryLayer(opendal::layers::RetryLayer);
+
+impl NodeLayer for RetryLayer {
+    fn layer(&self, op: opendal::Operator) -> opendal::Operator {
+        op.layer(self.0.clone())
+    }
+}
+
+/// RetryLayer constructor.
+#[js_function(1)]
+pub fn create_retry_layer(ctx: CallContext) -> Result<JsObject> {
+    let mut retry = opendal::layers::RetryLayer::default();
+
+    let config: Either<JsObject, JsUndefined> = ctx.try_get::<JsObject>(0)?;

Review Comment:
   Do we have better way to handle the default value?



##########
bindings/nodejs/src/lib.rs:
##########
@@ -15,6 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
+#![allow(clippy::not_unsafe_ptr_arg_deref)]

Review Comment:
   Please mark them as unsafe instead of allow clippy.



##########
bindings/nodejs/src/lib.rs:
##########
@@ -686,6 +691,117 @@ impl PresignedRequest {
     }
 }
 
+pub trait NodeLayer: Send + Sync {
+    fn layer(&self, op: opendal::Operator) -> opendal::Operator;
+}
+
+struct NodeLayerWrapper {
+    inner: Box<dyn NodeLayer>,
+}
+
+#[napi]
+impl Operator {
+    /// Add a layer to this operator.
+    #[napi]
+    pub fn layer(&self, env: Env, layer: JsObject) -> Result<Self> {
+        let ctx: &mut NodeLayerWrapper = env
+            .unwrap(&layer)
+            .map_err(|e| Error::from_reason(format!("failed to unwrap layer: 
{}", e)))?;
+        Ok(Self(ctx.inner.layer(self.0.clone())))
+    }
+}
+
+/// A layer that will retry the request if it fails.
+/// It will retry with exponential backoff.
+///
+/// ## Parameters
+///
+/// - `jitter`<bool>: Whether to add jitter to the backoff.
+/// - `max_times`<number>: The maximum number of times to retry.
+/// - `factor`<number>: The exponential factor to use.
+/// - `max_delay`<number>: The maximum delay between retries. The unit is 
microsecond.
+/// - `min_delay`<number>: The minimum delay between retries. The unit is 
microsecond.
+#[napi]
+pub struct RetryLayer(opendal::layers::RetryLayer);
+
+impl NodeLayer for RetryLayer {
+    fn layer(&self, op: opendal::Operator) -> opendal::Operator {
+        op.layer(self.0.clone())
+    }
+}
+
+/// RetryLayer constructor.
+#[js_function(1)]
+pub fn create_retry_layer(ctx: CallContext) -> Result<JsObject> {

Review Comment:
   The code in this function seems a bit verbose. Can we make it better?



##########
bindings/nodejs/index.js:
##########
@@ -20,6 +20,9 @@
 /// <reference types="node" />
 
 require('dotenv').config()
-const { Operator } = require('./generated.js')
+const { Operator, RetryLayer } = require('./generated.js')
 
 module.exports.Operator = Operator
+module.exports.layers = {

Review Comment:
   We don't need expose `Entry`, `Metadata` and `Lister`?



-- 
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]

Reply via email to