1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! Implementing a layer.
//!
//! A [`Layer`] intercepts an operator's composed service, operation context,
//! or both. Use a layer for behavior that applies across services, such as
//! retry, timeout, tracing, metrics, or runtime resource replacement.
//!
//! # Two composition hooks
//!
//! [`Layer`] exposes two hooks:
//!
//! ```text
//! fn apply_service(&self, service: Servicer) -> Servicer;
//! fn apply_context(
//! &self,
//! service: Servicer,
//! context: OperationContext,
//! ) -> OperationContext;
//! ```
//!
//! `apply_service` wraps storage operations. `apply_context` wraps or replaces
//! runtime resources such as the HTTP transport and executor. Each hook
//! returns its input unchanged by default, so a layer implements only the
//! plane it owns.
//!
//! The operator first applies every service hook in insertion order. It then
//! applies every context hook in the same order, passing the final service
//! stack to each context hook. Adding a layer or replacing the base context
//! replays the complete layer list, producing a service stack and context from
//! the same ordering.
//!
//! # Operation layers
//!
//! An operation layer normally contains:
//!
//! - An `XxxLayer` that implements [`Layer::apply_service`].
//! - An `XxxService` that stores the inner [`Servicer`] and implements
//! [`Service`].
//!
//! The wrapper overrides only the operations it owns and forwards the rest to
//! the inner service. It must also return capabilities that describe the
//! behavior of the wrapped stack. The wrapper keeps its own operation body
//! types concrete until OpenDAL erases it back into a [`Servicer`].
//!
//! # Resource layers
//!
//! A resource-only layer implements [`Layer::apply_context`]. It should
//! preserve the previous resource when lower layers must remain effective. A
//! layer that wraps an HTTP transport or executor must decide explicitly
//! whether requests continue through the previous value or replace it
//! entirely.
//!
//! Layers that coordinate policy across operation and I/O phases can implement
//! both hooks. Shared mutable state requires interior mutability and must
//! remain `Send` and `Sync`, because cloned operators can run operations
//! concurrently.
//!
//! [`Layer`]: crate::raw::Layer
//! [`Layer::apply_service`]: crate::raw::Layer::apply_service
//! [`Layer::apply_context`]: crate::raw::Layer::apply_context
//! [`Service`]: crate::raw::Service
//! [`Servicer`]: crate::raw::Servicer