Skip to main content

opendal_layer_await_tree/
lib.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#![doc = include_str!("../README.md")]
19#![cfg_attr(docsrs, feature(doc_cfg))]
20#![cfg_attr(docsrs, doc(auto_cfg))]
21#![deny(missing_docs)]
22use await_tree::InstrumentAwait;
23use std::sync::Arc;
24
25use opendal_core::raw::*;
26use opendal_core::*;
27
28/// `AwaitTreeLayer` instruments service operations for actor-based applications.
29///
30/// # AwaitTree
31///
32/// `await-tree` lets developers dump the execution tree at runtime and annotates
33/// each future's span with `instrument_await`.
34/// Read more about [await-tree](https://docs.rs/await-tree/latest/await_tree/)
35///
36/// # Examples
37///
38/// ```no_run
39/// # use opendal_core::services;
40/// # use opendal_core::Operator;
41/// # use opendal_core::Result;
42/// # use opendal_layer_await_tree::AwaitTreeLayer;
43/// #
44/// # fn main() -> Result<()> {
45/// let _ = Operator::new(services::Memory::default())?
46///     .layer(AwaitTreeLayer::new());
47/// # Ok(())
48/// # }
49/// ```
50#[derive(Clone, Debug, Default)]
51#[non_exhaustive]
52pub struct AwaitTreeLayer {}
53
54impl AwaitTreeLayer {
55    /// Create a new [`AwaitTreeLayer`].
56    pub fn new() -> Self {
57        Self::default()
58    }
59}
60
61impl Layer for AwaitTreeLayer {
62    fn apply_service(&self, inner: Servicer) -> Servicer {
63        Arc::new(self.layer(inner))
64    }
65}
66
67impl AwaitTreeLayer {
68    fn layer(&self, inner: Servicer) -> AwaitTreeAccessor {
69        AwaitTreeAccessor { inner }
70    }
71}
72
73#[doc(hidden)]
74#[derive(Debug)]
75pub struct AwaitTreeAccessor {
76    inner: Servicer,
77}
78
79impl Service for AwaitTreeAccessor {
80    type Reader = AwaitTreeWrapper<oio::Reader>;
81    type Writer = AwaitTreeWrapper<oio::Writer>;
82    type Lister = AwaitTreeWrapper<oio::Lister>;
83    type Deleter = AwaitTreeWrapper<oio::Deleter>;
84    type Copier = AwaitTreeWrapper<oio::Copier>;
85    type Composer = oio::Composer;
86
87    fn info(&self) -> ServiceInfo {
88        self.inner.info()
89    }
90
91    fn capability(&self) -> Capability {
92        self.inner.capability()
93    }
94
95    fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
96        self.inner.compose(ctx, to, args)
97    }
98
99    async fn create_dir(
100        &self,
101        ctx: &OperationContext,
102        path: &str,
103        args: OpCreateDir,
104    ) -> Result<RpCreateDir> {
105        self.inner
106            .create_dir(ctx, path, args)
107            .instrument_await(format!("opendal::{}", Operation::CreateDir))
108            .await
109    }
110
111    fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
112        self.inner.read(ctx, path, args).map(AwaitTreeWrapper::new)
113    }
114
115    fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer> {
116        self.inner.write(ctx, path, args).map(AwaitTreeWrapper::new)
117    }
118
119    fn copy(
120        &self,
121        ctx: &OperationContext,
122        from: &str,
123        to: &str,
124        args: OpCopy,
125    ) -> Result<Self::Copier> {
126        self.inner
127            .copy(ctx, from, to, args)
128            .map(AwaitTreeWrapper::new)
129    }
130
131    async fn rename(
132        &self,
133        ctx: &OperationContext,
134        from: &str,
135        to: &str,
136        args: OpRename,
137    ) -> Result<RpRename> {
138        self.inner
139            .rename(ctx, from, to, args)
140            .instrument_await(format!("opendal::{}", Operation::Rename))
141            .await
142    }
143
144    async fn restore(
145        &self,
146        ctx: &OperationContext,
147        path: &str,
148        args: OpRestore,
149    ) -> Result<RpRestore> {
150        self.inner
151            .restore(ctx, path, args)
152            .instrument_await(format!("opendal::{}", Operation::Restore))
153            .await
154    }
155
156    async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
157        self.inner
158            .stat(ctx, path, args)
159            .instrument_await(format!("opendal::{}", Operation::Stat))
160            .await
161    }
162
163    fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter> {
164        self.inner.delete(ctx).map(AwaitTreeWrapper::new)
165    }
166
167    fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
168        self.inner.list(ctx, path, args).map(AwaitTreeWrapper::new)
169    }
170
171    async fn presign(
172        &self,
173        ctx: &OperationContext,
174        path: &str,
175        args: OpPresign,
176    ) -> Result<RpPresign> {
177        self.inner
178            .presign(ctx, path, args)
179            .instrument_await(format!("opendal::{}", Operation::Presign))
180            .await
181    }
182}
183
184#[doc(hidden)]
185pub struct AwaitTreeWrapper<R> {
186    inner: R,
187}
188
189impl<R> AwaitTreeWrapper<R> {
190    fn new(inner: R) -> Self {
191        Self { inner }
192    }
193}
194
195impl<R: oio::ReadStream> oio::ReadStream for AwaitTreeWrapper<R> {
196    async fn read(&mut self) -> Result<Buffer> {
197        self.inner
198            .read()
199            .instrument_await(format!("opendal::{}", Operation::Read))
200            .await
201    }
202}
203
204impl<R: oio::Read> oio::Read for AwaitTreeWrapper<R> {
205    async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn oio::ReadStreamDyn>)> {
206        let (rp, stream) = self
207            .inner
208            .open(range)
209            .instrument_await(format!("opendal::{}", Operation::Read))
210            .await?;
211        Ok((
212            rp,
213            Box::new(AwaitTreeWrapper::new(stream)) as Box<dyn oio::ReadStreamDyn>,
214        ))
215    }
216
217    async fn read(&self, range: BytesRange) -> Result<(RpRead, Buffer)> {
218        self.inner
219            .read(range)
220            .instrument_await(format!("opendal::{}", Operation::Read))
221            .await
222    }
223}
224
225impl<R: oio::Write> oio::Write for AwaitTreeWrapper<R> {
226    async fn write(&mut self, bs: Buffer) -> Result<()> {
227        self.inner
228            .write(bs)
229            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
230            .await
231    }
232
233    async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
234        self.inner
235            .copy_from(path, args, range)
236            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
237            .await
238    }
239
240    async fn abort(&mut self) -> Result<()> {
241        self.inner
242            .abort()
243            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
244            .await
245    }
246
247    async fn close(&mut self) -> Result<Metadata> {
248        self.inner
249            .close()
250            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
251            .await
252    }
253}
254
255impl<R: oio::List> oio::List for AwaitTreeWrapper<R> {
256    async fn next(&mut self) -> Result<Option<oio::Entry>> {
257        self.inner
258            .next()
259            .instrument_await(format!("opendal::{}", Operation::List))
260            .await
261    }
262}
263
264impl<R: oio::Delete> oio::Delete for AwaitTreeWrapper<R> {
265    async fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
266        self.inner.delete(path, args).await
267    }
268
269    async fn close(&mut self) -> Result<()> {
270        self.inner
271            .close()
272            .instrument_await(format!("opendal::{}", Operation::Delete))
273            .await
274    }
275}
276
277impl<C: oio::Copy> oio::Copy for AwaitTreeWrapper<C> {
278    async fn next(&mut self) -> Result<Option<usize>> {
279        self.inner
280            .next()
281            .instrument_await(format!("opendal::{}", Operation::Copy.into_static()))
282            .await
283    }
284
285    async fn close(&mut self) -> Result<Metadata> {
286        self.inner
287            .close()
288            .instrument_await(format!("opendal::{}", Operation::Copy.into_static()))
289            .await
290    }
291
292    async fn abort(&mut self) -> Result<()> {
293        self.inner
294            .abort()
295            .instrument_await(format!("opendal::{}", Operation::Copy.into_static()))
296            .await
297    }
298}