Skip to main content

opendal_layer_async_backtrace/
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 std::sync::Arc;
23
24use opendal_core::raw::*;
25use opendal_core::*;
26
27/// `AsyncBacktraceLayer` records efficient logical stack traces for asynchronous
28/// service operations.
29///
30/// # Async Backtrace
31///
32/// `async-backtrace` lets developers inspect the stack traces of asynchronous functions.
33/// Read more about [async-backtrace](https://docs.rs/async-backtrace/latest/async_backtrace/)
34///
35/// # Examples
36///
37/// ```no_run
38/// # use opendal_core::services;
39/// # use opendal_core::Operator;
40/// # use opendal_core::Result;
41/// # use opendal_layer_async_backtrace::AsyncBacktraceLayer;
42/// #
43/// # fn main() -> Result<()> {
44/// let _ = Operator::new(services::Memory::default())?
45///     .layer(AsyncBacktraceLayer::new());
46/// # Ok(())
47/// # }
48/// ```
49#[derive(Clone, Debug, Default)]
50#[non_exhaustive]
51pub struct AsyncBacktraceLayer {}
52
53impl AsyncBacktraceLayer {
54    /// Create a new [`AsyncBacktraceLayer`].
55    pub fn new() -> Self {
56        Self::default()
57    }
58}
59
60impl Layer for AsyncBacktraceLayer {
61    fn apply_service(&self, inner: Servicer) -> Servicer {
62        Arc::new(self.layer(inner))
63    }
64}
65
66impl AsyncBacktraceLayer {
67    fn layer(&self, inner: Servicer) -> AsyncBacktraceAccessor {
68        AsyncBacktraceAccessor { inner }
69    }
70}
71
72#[doc(hidden)]
73#[derive(Debug)]
74pub struct AsyncBacktraceAccessor {
75    inner: Servicer,
76}
77
78impl Service for AsyncBacktraceAccessor {
79    type Reader = AsyncBacktraceWrapper<oio::Reader>;
80    type Writer = AsyncBacktraceWrapper<oio::Writer>;
81    type Lister = AsyncBacktraceWrapper<oio::Lister>;
82    type Deleter = AsyncBacktraceWrapper<oio::Deleter>;
83    type Copier = oio::Copier;
84    type Composer = oio::Composer;
85
86    fn info(&self) -> ServiceInfo {
87        self.inner.info()
88    }
89
90    fn capability(&self) -> Capability {
91        self.inner.capability()
92    }
93
94    fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
95        self.inner.compose(ctx, to, args)
96    }
97
98    #[async_backtrace::framed]
99    async fn create_dir(
100        &self,
101        ctx: &OperationContext,
102        path: &str,
103        args: OpCreateDir,
104    ) -> Result<RpCreateDir> {
105        self.inner.create_dir(ctx, path, args).await
106    }
107
108    fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
109        self.inner
110            .read(ctx, path, args)
111            .map(AsyncBacktraceWrapper::new)
112    }
113
114    fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer> {
115        self.inner
116            .write(ctx, path, args)
117            .map(AsyncBacktraceWrapper::new)
118    }
119
120    fn copy(
121        &self,
122        ctx: &OperationContext,
123        from: &str,
124        to: &str,
125        args: OpCopy,
126    ) -> Result<Self::Copier> {
127        self.inner.copy(ctx, from, to, args)
128    }
129
130    #[async_backtrace::framed]
131    async fn rename(
132        &self,
133        ctx: &OperationContext,
134        from: &str,
135        to: &str,
136        args: OpRename,
137    ) -> Result<RpRename> {
138        self.inner.rename(ctx, from, to, args).await
139    }
140
141    #[async_backtrace::framed]
142    async fn restore(
143        &self,
144        ctx: &OperationContext,
145        path: &str,
146        args: OpRestore,
147    ) -> Result<RpRestore> {
148        self.inner.restore(ctx, path, args).await
149    }
150
151    #[async_backtrace::framed]
152    async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
153        self.inner.stat(ctx, path, args).await
154    }
155
156    fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter> {
157        self.inner.delete(ctx).map(AsyncBacktraceWrapper::new)
158    }
159
160    fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
161        self.inner
162            .list(ctx, path, args)
163            .map(AsyncBacktraceWrapper::new)
164    }
165
166    #[async_backtrace::framed]
167    async fn presign(
168        &self,
169        ctx: &OperationContext,
170        path: &str,
171        args: OpPresign,
172    ) -> Result<RpPresign> {
173        self.inner.presign(ctx, path, args).await
174    }
175}
176
177#[doc(hidden)]
178pub struct AsyncBacktraceWrapper<R> {
179    inner: R,
180}
181
182impl<R> AsyncBacktraceWrapper<R> {
183    fn new(inner: R) -> Self {
184        Self { inner }
185    }
186}
187
188impl<R: oio::ReadStream> oio::ReadStream for AsyncBacktraceWrapper<R> {
189    #[async_backtrace::framed]
190    async fn read(&mut self) -> Result<Buffer> {
191        self.inner.read().await
192    }
193}
194
195impl<R: oio::Read> oio::Read for AsyncBacktraceWrapper<R> {
196    #[async_backtrace::framed]
197    async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn oio::ReadStreamDyn>)> {
198        let (rp, stream) = self.inner.open(range).await?;
199        Ok((
200            rp,
201            Box::new(AsyncBacktraceWrapper::new(stream)) as Box<dyn oio::ReadStreamDyn>,
202        ))
203    }
204
205    #[async_backtrace::framed]
206    async fn read(&self, range: BytesRange) -> Result<(RpRead, Buffer)> {
207        self.inner.read(range).await
208    }
209}
210
211impl<R: oio::Write> oio::Write for AsyncBacktraceWrapper<R> {
212    #[async_backtrace::framed]
213    async fn write(&mut self, bs: Buffer) -> Result<()> {
214        self.inner.write(bs).await
215    }
216
217    #[async_backtrace::framed]
218    async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
219        self.inner.copy_from(path, args, range).await
220    }
221
222    #[async_backtrace::framed]
223    async fn close(&mut self) -> Result<Metadata> {
224        self.inner.close().await
225    }
226
227    #[async_backtrace::framed]
228    async fn abort(&mut self) -> Result<()> {
229        self.inner.abort().await
230    }
231}
232
233impl<R: oio::List> oio::List for AsyncBacktraceWrapper<R> {
234    #[async_backtrace::framed]
235    async fn next(&mut self) -> Result<Option<oio::Entry>> {
236        self.inner.next().await
237    }
238}
239
240impl<R: oio::Delete> oio::Delete for AsyncBacktraceWrapper<R> {
241    #[async_backtrace::framed]
242    async fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
243        self.inner.delete(path, args).await
244    }
245
246    #[async_backtrace::framed]
247    async fn close(&mut self) -> Result<()> {
248        self.inner.close().await
249    }
250}