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///
36/// # fn main() -> Result<()> {
37/// let _ = Operator::new(services::Memory::default())?
38///     .layer(AsyncBacktraceLayer::default())
39///     .finish();
40/// Ok(())
41/// # }
42/// ```
43#[derive(Clone, Default)]
44pub struct AsyncBacktraceLayer;
45
46impl<A: Access> Layer<A> for AsyncBacktraceLayer {
47    type LayeredAccess = AsyncBacktraceAccessor<A>;
48
49    fn layer(&self, accessor: A) -> Self::LayeredAccess {
50        AsyncBacktraceAccessor { inner: accessor }
51    }
52}
53
54#[derive(Debug, Clone)]
55pub struct AsyncBacktraceAccessor<A: Access> {
56    inner: A,
57}
58
59impl<A: Access> LayeredAccess for AsyncBacktraceAccessor<A> {
60    type Inner = A;
61    type Reader = AsyncBacktraceWrapper<A::Reader>;
62    type Writer = AsyncBacktraceWrapper<A::Writer>;
63    type Lister = AsyncBacktraceWrapper<A::Lister>;
64    type Deleter = AsyncBacktraceWrapper<A::Deleter>;
65
66    fn inner(&self) -> &Self::Inner {
67        &self.inner
68    }
69
70    #[async_backtrace::framed]
71    async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
72        self.inner
73            .read(path, args)
74            .await
75            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
76    }
77
78    #[async_backtrace::framed]
79    async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)> {
80        self.inner
81            .write(path, args)
82            .await
83            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
84    }
85
86    #[async_backtrace::framed]
87    async fn copy(&self, from: &str, to: &str, args: OpCopy) -> Result<RpCopy> {
88        self.inner.copy(from, to, args).await
89    }
90
91    #[async_backtrace::framed]
92    async fn rename(&self, from: &str, to: &str, args: OpRename) -> Result<RpRename> {
93        self.inner.rename(from, to, args).await
94    }
95
96    #[async_backtrace::framed]
97    async fn stat(&self, path: &str, args: OpStat) -> Result<RpStat> {
98        self.inner.stat(path, args).await
99    }
100
101    #[async_backtrace::framed]
102    async fn delete(&self) -> Result<(RpDelete, Self::Deleter)> {
103        self.inner
104            .delete()
105            .await
106            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
107    }
108
109    #[async_backtrace::framed]
110    async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Lister)> {
111        self.inner
112            .list(path, args)
113            .await
114            .map(|(rp, r)| (rp, AsyncBacktraceWrapper::new(r)))
115    }
116
117    #[async_backtrace::framed]
118    async fn presign(&self, path: &str, args: OpPresign) -> Result<RpPresign> {
119        self.inner.presign(path, args).await
120    }
121}
122
123pub struct AsyncBacktraceWrapper<R> {
124    inner: R,
125}
126
127impl<R> AsyncBacktraceWrapper<R> {
128    fn new(inner: R) -> Self {
129        Self { inner }
130    }
131}
132
133impl<R: oio::Read> oio::Read for AsyncBacktraceWrapper<R> {
134    #[async_backtrace::framed]
135    async fn read(&mut self) -> Result<Buffer> {
136        self.inner.read().await
137    }
138}
139
140impl<R: oio::Write> oio::Write for AsyncBacktraceWrapper<R> {
141    #[async_backtrace::framed]
142    async fn write(&mut self, bs: Buffer) -> Result<()> {
143        self.inner.write(bs).await
144    }
145
146    #[async_backtrace::framed]
147    async fn close(&mut self) -> Result<Metadata> {
148        self.inner.close().await
149    }
150
151    #[async_backtrace::framed]
152    async fn abort(&mut self) -> Result<()> {
153        self.inner.abort().await
154    }
155}
156
157impl<R: oio::List> oio::List for AsyncBacktraceWrapper<R> {
158    #[async_backtrace::framed]
159    async fn next(&mut self) -> Result<Option<oio::Entry>> {
160        self.inner.next().await
161    }
162}
163
164impl<R: oio::Delete> oio::Delete for AsyncBacktraceWrapper<R> {
165    fn delete(&mut self, path: &str, args: OpDelete) -> Result<()> {
166        self.inner.delete(path, args)
167    }
168
169    #[async_backtrace::framed]
170    async fn flush(&mut self) -> Result<usize> {
171        self.inner.flush().await
172    }
173}