opendal/layers/
async_backtrace.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
18use crate::raw::*;
19use crate::*;
20
21/// Add Efficient, logical 'stack' traces of async functions for the underlying services.
22///
23/// # Async Backtrace
24///
25/// async-backtrace allows developers to get a stack trace of the async functions.
26/// Read more about [async-backtrace](https://docs.rs/async-backtrace/latest/async_backtrace/)
27///
28/// # Examples
29///
30/// ```no_run
31/// # use opendal::layers::AsyncBacktraceLayer;
32/// # use opendal::services;
33/// # use opendal::Operator;
34/// # use opendal::Result;
35/// # use opendal::Scheme;
36///
37/// # fn main() -> Result<()> {
38/// let _ = Operator::new(services::Memory::default())?
39///     .layer(AsyncBacktraceLayer::default())
40///     .finish();
41/// Ok(())
42/// # }
43/// ```
44#[derive(Clone, Default)]
45pub struct AsyncBacktraceLayer;
46
47impl<A: Access> Layer<A> for AsyncBacktraceLayer {
48    type LayeredAccess = AsyncBacktraceAccessor<A>;
49
50    fn layer(&self, accessor: A) -> Self::LayeredAccess {
51        AsyncBacktraceAccessor { inner: accessor }
52    }
53}
54
55#[derive(Debug, Clone)]
56pub struct AsyncBacktraceAccessor<A: Access> {
57    inner: A,
58}
59
60impl<A: Access> LayeredAccess for AsyncBacktraceAccessor<A> {
61    type Inner = A;
62    type Reader = AsyncBacktraceWrapper<A::Reader>;
63    type BlockingReader = AsyncBacktraceWrapper<A::BlockingReader>;
64    type Writer = AsyncBacktraceWrapper<A::Writer>;
65    type BlockingWriter = AsyncBacktraceWrapper<A::BlockingWriter>;
66    type Lister = AsyncBacktraceWrapper<A::Lister>;
67    type BlockingLister = AsyncBacktraceWrapper<A::BlockingLister>;
68    type Deleter = AsyncBacktraceWrapper<A::Deleter>;
69    type BlockingDeleter = AsyncBacktraceWrapper<A::BlockingDeleter>;
70
71    fn inner(&self) -> &Self::Inner {
72        &self.inner
73    }
74
75    #[async_backtrace::framed]
76    async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
77        self.inner
78            .read(path, args)
79            .await
80            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
81    }
82
83    #[async_backtrace::framed]
84    async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)> {
85        self.inner
86            .write(path, args)
87            .await
88            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
89    }
90
91    #[async_backtrace::framed]
92    async fn copy(&self, from: &str, to: &str, args: OpCopy) -> Result<RpCopy> {
93        self.inner.copy(from, to, args).await
94    }
95
96    #[async_backtrace::framed]
97    async fn rename(&self, from: &str, to: &str, args: OpRename) -> Result<RpRename> {
98        self.inner.rename(from, to, args).await
99    }
100
101    #[async_backtrace::framed]
102    async fn stat(&self, path: &str, args: OpStat) -> Result<RpStat> {
103        self.inner.stat(path, args).await
104    }
105
106    #[async_backtrace::framed]
107    async fn delete(&self) -> Result<(RpDelete, Self::Deleter)> {
108        self.inner
109            .delete()
110            .await
111            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
112    }
113
114    #[async_backtrace::framed]
115    async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Lister)> {
116        self.inner
117            .list(path, args)
118            .await
119            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
120    }
121
122    #[async_backtrace::framed]
123    async fn presign(&self, path: &str, args: OpPresign) -> Result<RpPresign> {
124        self.inner.presign(path, args).await
125    }
126
127    fn blocking_read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::BlockingReader)> {
128        self.inner
129            .blocking_read(path, args)
130            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
131    }
132
133    fn blocking_write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::BlockingWriter)> {
134        self.inner
135            .blocking_write(path, args)
136            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
137    }
138
139    fn blocking_list(&self, path: &str, args: OpList) -> Result<(RpList, Self::BlockingLister)> {
140        self.inner
141            .blocking_list(path, args)
142            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
143    }
144
145    fn blocking_delete(&self) -> Result<(RpDelete, Self::BlockingDeleter)> {
146        self.inner
147            .blocking_delete()
148            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
149    }
150}
151
152pub struct AsyncBacktraceWrapper<R> {
153    inner: R,
154}
155
156impl<R> AsyncBacktraceWrapper<R> {
157    fn new(inner: R) -> Self {
158        Self { inner }
159    }
160}
161
162impl<R: oio::Read> oio::Read for AsyncBacktraceWrapper<R> {
163    #[async_backtrace::framed]
164    async fn read(&mut self) -> Result<Buffer> {
165        self.inner.read().await
166    }
167}
168
169impl<R: oio::BlockingRead> oio::BlockingRead for AsyncBacktraceWrapper<R> {
170    fn read(&mut self) -> Result<Buffer> {
171        self.inner.read()
172    }
173}
174
175impl<R: oio::Write> oio::Write for AsyncBacktraceWrapper<R> {
176    #[async_backtrace::framed]
177    async fn write(&mut self, bs: Buffer) -> Result<()> {
178        self.inner.write(bs).await
179    }
180
181    #[async_backtrace::framed]
182    async fn close(&mut self) -> Result<Metadata> {
183        self.inner.close().await
184    }
185
186    #[async_backtrace::framed]
187    async fn abort(&mut self) -> Result<()> {
188        self.inner.abort().await
189    }
190}
191
192impl<R: oio::BlockingWrite> oio::BlockingWrite for AsyncBacktraceWrapper<R> {
193    fn write(&mut self, bs: Buffer) -> Result<()> {
194        self.inner.write(bs)
195    }
196
197    fn close(&mut self) -> Result<Metadata> {
198        self.inner.close()
199    }
200}
201
202impl<R: oio::List> oio::List for AsyncBacktraceWrapper<R> {
203    #[async_backtrace::framed]
204    async fn next(&mut self) -> Result<Option<oio::Entry>> {
205        self.inner.next().await
206    }
207}
208
209impl<R: oio::BlockingList> oio::BlockingList for AsyncBacktraceWrapper<R> {
210    fn next(&mut self) -> Result<Option<oio::Entry>> {
211        self.inner.next()
212    }
213}
214
215impl<R: oio::Delete> oio::Delete for AsyncBacktraceWrapper<R> {
216    fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
217        self.inner.delete(path, args)
218    }
219
220    #[async_backtrace::framed]
221    async fn flush(&mut self) -> Result<usize> {
222        self.inner.flush().await
223    }
224}
225
226impl<R: oio::BlockingDelete> oio::BlockingDelete for AsyncBacktraceWrapper<R> {
227    fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
228        self.inner.delete(path, args)
229    }
230
231    fn flush(&mut self) -> Result<usize> {
232        self.inner.flush()
233    }
234}