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
86    fn info(&self) -> ServiceInfo {
87        self.inner.info()
88    }
89
90    fn capability(&self) -> Capability {
91        self.inner.capability()
92    }
93
94    async fn create_dir(
95        &self,
96        ctx: &OperationContext,
97        path: &str,
98        args: OpCreateDir,
99    ) -> Result<RpCreateDir> {
100        self.inner
101            .create_dir(ctx, path, args)
102            .instrument_await(format!("opendal::{}", Operation::CreateDir))
103            .await
104    }
105
106    fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
107        self.inner.read(ctx, path, args).map(AwaitTreeWrapper::new)
108    }
109
110    fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer> {
111        self.inner.write(ctx, path, args).map(AwaitTreeWrapper::new)
112    }
113
114    fn copy(
115        &self,
116        ctx: &OperationContext,
117        from: &str,
118        to: &str,
119        args: OpCopy,
120        opts: OpCopier,
121    ) -> Result<Self::Copier> {
122        self.inner
123            .copy(ctx, from, to, args, opts)
124            .map(AwaitTreeWrapper::new)
125    }
126
127    async fn rename(
128        &self,
129        ctx: &OperationContext,
130        from: &str,
131        to: &str,
132        args: OpRename,
133    ) -> Result<RpRename> {
134        self.inner
135            .rename(ctx, from, to, args)
136            .instrument_await(format!("opendal::{}", Operation::Rename))
137            .await
138    }
139
140    async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
141        self.inner
142            .stat(ctx, path, args)
143            .instrument_await(format!("opendal::{}", Operation::Stat))
144            .await
145    }
146
147    fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter> {
148        self.inner.delete(ctx).map(AwaitTreeWrapper::new)
149    }
150
151    fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
152        self.inner.list(ctx, path, args).map(AwaitTreeWrapper::new)
153    }
154
155    async fn presign(
156        &self,
157        ctx: &OperationContext,
158        path: &str,
159        args: OpPresign,
160    ) -> Result<RpPresign> {
161        self.inner
162            .presign(ctx, path, args)
163            .instrument_await(format!("opendal::{}", Operation::Presign))
164            .await
165    }
166}
167
168#[doc(hidden)]
169pub struct AwaitTreeWrapper<R> {
170    inner: R,
171}
172
173impl<R> AwaitTreeWrapper<R> {
174    fn new(inner: R) -> Self {
175        Self { inner }
176    }
177}
178
179impl<R: oio::ReadStream> oio::ReadStream for AwaitTreeWrapper<R> {
180    async fn read(&mut self) -> Result<Buffer> {
181        self.inner
182            .read()
183            .instrument_await(format!("opendal::{}", Operation::Read))
184            .await
185    }
186}
187
188impl<R: oio::Read> oio::Read for AwaitTreeWrapper<R> {
189    async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn oio::ReadStreamDyn>)> {
190        let (rp, stream) = self
191            .inner
192            .open(range)
193            .instrument_await(format!("opendal::{}", Operation::Read))
194            .await?;
195        Ok((
196            rp,
197            Box::new(AwaitTreeWrapper::new(stream)) as Box<dyn oio::ReadStreamDyn>,
198        ))
199    }
200
201    async fn read(&self, range: BytesRange) -> Result<(RpRead, Buffer)> {
202        self.inner
203            .read(range)
204            .instrument_await(format!("opendal::{}", Operation::Read))
205            .await
206    }
207}
208
209impl<R: oio::Write> oio::Write for AwaitTreeWrapper<R> {
210    async fn write(&mut self, bs: Buffer) -> Result<()> {
211        self.inner
212            .write(bs)
213            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
214            .await
215    }
216
217    async fn abort(&mut self) -> Result<()> {
218        self.inner
219            .abort()
220            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
221            .await
222    }
223
224    async fn close(&mut self) -> Result<Metadata> {
225        self.inner
226            .close()
227            .instrument_await(format!("opendal::{}", Operation::Write.into_static()))
228            .await
229    }
230}
231
232impl<R: oio::List> oio::List for AwaitTreeWrapper<R> {
233    async fn next(&mut self) -> Result<Option<oio::Entry>> {
234        self.inner
235            .next()
236            .instrument_await(format!("opendal::{}", Operation::List))
237            .await
238    }
239}
240
241impl<R: oio::Delete> oio::Delete for AwaitTreeWrapper<R> {
242    async fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
243        self.inner.delete(path, args).await
244    }
245
246    async fn close(&mut self) -> Result<()> {
247        self.inner
248            .close()
249            .instrument_await(format!("opendal::{}", Operation::Delete))
250            .await
251    }
252}
253
254impl<C: oio::Copy> oio::Copy for AwaitTreeWrapper<C> {
255    async fn next(&mut self) -> Result<Option<usize>> {
256        self.inner
257            .next()
258            .instrument_await(format!("opendal::{}", Operation::Copy.into_static()))
259            .await
260    }
261
262    async fn close(&mut self) -> Result<Metadata> {
263        self.inner
264            .close()
265            .instrument_await(format!("opendal::{}", Operation::Copy.into_static()))
266            .await
267    }
268
269    async fn abort(&mut self) -> Result<()> {
270        self.inner
271            .abort()
272            .instrument_await(format!("opendal::{}", Operation::Copy.into_static()))
273            .await
274    }
275}