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
85    fn info(&self) -> ServiceInfo {
86        self.inner.info()
87    }
88
89    fn capability(&self) -> Capability {
90        self.inner.capability()
91    }
92
93    #[async_backtrace::framed]
94    async fn create_dir(
95        &self,
96        ctx: &OperationContext,
97        path: &str,
98        args: OpCreateDir,
99    ) -> Result<RpCreateDir> {
100        self.inner.create_dir(ctx, path, args).await
101    }
102
103    fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
104        self.inner
105            .read(ctx, path, args)
106            .map(AsyncBacktraceWrapper::new)
107    }
108
109    fn write(&self, ctx: &OperationContext, path: &str, args: OpWrite) -> Result<Self::Writer> {
110        self.inner
111            .write(ctx, path, args)
112            .map(AsyncBacktraceWrapper::new)
113    }
114
115    fn copy(
116        &self,
117        ctx: &OperationContext,
118        from: &str,
119        to: &str,
120        args: OpCopy,
121        opts: OpCopier,
122    ) -> Result<Self::Copier> {
123        self.inner.copy(ctx, from, to, args, opts)
124    }
125
126    #[async_backtrace::framed]
127    async fn rename(
128        &self,
129        ctx: &OperationContext,
130        from: &str,
131        to: &str,
132        args: OpRename,
133    ) -> Result<RpRename> {
134        self.inner.rename(ctx, from, to, args).await
135    }
136
137    #[async_backtrace::framed]
138    async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
139        self.inner.stat(ctx, path, args).await
140    }
141
142    fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter> {
143        self.inner.delete(ctx).map(AsyncBacktraceWrapper::new)
144    }
145
146    fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
147        self.inner
148            .list(ctx, path, args)
149            .map(AsyncBacktraceWrapper::new)
150    }
151
152    #[async_backtrace::framed]
153    async fn presign(
154        &self,
155        ctx: &OperationContext,
156        path: &str,
157        args: OpPresign,
158    ) -> Result<RpPresign> {
159        self.inner.presign(ctx, path, args).await
160    }
161}
162
163#[doc(hidden)]
164pub struct AsyncBacktraceWrapper<R> {
165    inner: R,
166}
167
168impl<R> AsyncBacktraceWrapper<R> {
169    fn new(inner: R) -> Self {
170        Self { inner }
171    }
172}
173
174impl<R: oio::ReadStream> oio::ReadStream for AsyncBacktraceWrapper<R> {
175    #[async_backtrace::framed]
176    async fn read(&mut self) -> Result<Buffer> {
177        self.inner.read().await
178    }
179}
180
181impl<R: oio::Read> oio::Read for AsyncBacktraceWrapper<R> {
182    #[async_backtrace::framed]
183    async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn oio::ReadStreamDyn>)> {
184        let (rp, stream) = self.inner.open(range).await?;
185        Ok((
186            rp,
187            Box::new(AsyncBacktraceWrapper::new(stream)) as Box<dyn oio::ReadStreamDyn>,
188        ))
189    }
190
191    #[async_backtrace::framed]
192    async fn read(&self, range: BytesRange) -> Result<(RpRead, Buffer)> {
193        self.inner.read(range).await
194    }
195}
196
197impl<R: oio::Write> oio::Write for AsyncBacktraceWrapper<R> {
198    #[async_backtrace::framed]
199    async fn write(&mut self, bs: Buffer) -> Result<()> {
200        self.inner.write(bs).await
201    }
202
203    #[async_backtrace::framed]
204    async fn close(&mut self) -> Result<Metadata> {
205        self.inner.close().await
206    }
207
208    #[async_backtrace::framed]
209    async fn abort(&mut self) -> Result<()> {
210        self.inner.abort().await
211    }
212}
213
214impl<R: oio::List> oio::List for AsyncBacktraceWrapper<R> {
215    #[async_backtrace::framed]
216    async fn next(&mut self) -> Result<Option<oio::Entry>> {
217        self.inner.next().await
218    }
219}
220
221impl<R: oio::Delete> oio::Delete for AsyncBacktraceWrapper<R> {
222    #[async_backtrace::framed]
223    async fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
224        self.inner.delete(path, args).await
225    }
226
227    #[async_backtrace::framed]
228    async fn close(&mut self) -> Result<()> {
229        self.inner.close().await
230    }
231}