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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*!
Experimental client built on the memcached
[meta protocol](https://github.com/memcached/memcached/blob/master/doc/protocol.txt).
Everything in this module is experimental and may change without notice.
The module is layered bottom-up:
- [`MetaCommand`] / [`MetaResponse`]: framing - request assembly and response
header parsing, including automatic base64 encoding of binary keys.
- `build_*` / `parse_*` and the `*Options` structs: a typed 1:1 mapping of the
protocol where every option field corresponds to exactly one protocol flag.
No serialization and no semantic interpretation happens at this level.
- Operations ([`Get`], [`Set`], [`Delete`], [`Arithmetic`]) and typed results
([`GetResult`], [`MutationResult`], [`ArithmeticResult`]): the semantic
layer, interpreting return codes and lease/stale flags. Each operation
implements [`Operation`] with a typed `Output`. Values are raw bytes.
- [`MetaClient`] (blocking) and [`AsyncMetaClient`] (tokio, behind the
`tokio` feature): single-server clients whose verbs return lazy
[`Request`] builders, executed with `send()`.
Several operations can run in one round trip: `run_batch` takes
heterogeneous [`Op`] values and returns [`OpResult`]s. Batched operations
execute independently and in order per server - a batch is not a
transaction.
Clients connected to several servers (`connect_multiple`) route each key by
a pluggable hash function and split batches per server, one round trip
each.
Clients are cheap to clone and shareable across threads or tasks; clones
share per-server pools of idle connections (capped by `with_max_idle`).
Checkout never blocks: a busy pool just dials another connection. A
connection that fails mid-exchange is dropped instead of reused.
Connections are dialed lazily; `with_connect_timeout` and
`with_io_timeout` bound dialing and I/O (1 second by default, `None`
removes the limit).
Transports are TCP only.
# Example
```no_run
use memcache::exp::MetaClient;
let mut client = MetaClient::connect("127.0.0.1:11211").unwrap();
client.set("foo", "bar").send().unwrap();
let result = client.get("foo").send().unwrap();
assert_eq!(result.value.as_deref(), Some(&b"bar"[..]));
// Options are chained before send():
client.set("foo", "bar").ttl(60).add().send().unwrap();
let counter = client.increment("hits").delta(2).initial(0, 60).send().unwrap();
// Values are encoded via ToValue and decoded by the requested type:
client.set("visits", 41u64).send().unwrap();
let visits: Option<u64> = client.get("visits").send().unwrap().decode().unwrap();
// Several operations in one round trip:
use memcache::exp::{Get, Set};
let results = client
.run_batch(vec![Set::new("a", "1").ttl(60).into(), Get::new("b").into()])
.unwrap();
```
The wire layer remains available for anything the clients do not cover:
```no_run
use memcache::exp::{build_get, parse_meta_result, GetOptions, MetaConnection};
let mut connection = MetaConnection::connect("127.0.0.1:11211").unwrap();
let command = build_get("foo", &GetOptions::default()).unwrap();
let response = connection.execute(&command).unwrap();
let result = parse_meta_result(response).unwrap();
if result.ok() {
println!("value: {:?}", result.value);
}
```
*/
pub use AsyncMetaClient;
pub use AsyncMetaConnection;
pub use MetaClient;
pub use MetaConnection;
pub use Operation;
pub use ;
pub use ;
pub use ;
pub use Request;
pub use ;
pub use ;