1
1
/// Example how to limit blob requests by hash and node id, and to add
2
- /// restrictions on limited content.
2
+ /// throttling or limiting the maximum number of connections.
3
+ ///
4
+ /// Limiting is done via a fn that returns an EventSender and internally
5
+ /// makes liberal use of spawn to spawn background tasks.
6
+ ///
7
+ /// This is fine, since the tasks will terminate as soon as the [BlobsProtocol]
8
+ /// instance holding the [EventSender] will be dropped. But for production
9
+ /// grade code you might nevertheless put the tasks into a [tokio::task::JoinSet] or
10
+ /// [n0_future::FuturesUnordered].
3
11
mod common;
4
12
use std:: {
5
13
collections:: { HashMap , HashSet } ,
@@ -31,33 +39,37 @@ use crate::common::get_or_generate_secret_key;
31
39
pub enum Args {
32
40
/// Limit requests by node id
33
41
ByNodeId {
34
- /// Path for files to add
42
+ /// Path for files to add.
35
43
paths : Vec < PathBuf > ,
36
44
#[ clap( long( "allow" ) ) ]
37
45
/// Nodes that are allowed to download content.
38
46
allowed_nodes : Vec < NodeId > ,
47
+ /// Number of secrets to generate for allowed node ids.
39
48
#[ clap( long, default_value_t = 1 ) ]
40
49
secrets : usize ,
41
50
} ,
42
51
/// Limit requests by hash, only first hash is allowed
43
52
ByHash {
44
- /// Path for files to add
53
+ /// Path for files to add.
45
54
paths : Vec < PathBuf > ,
46
55
} ,
47
56
/// Throttle requests
48
57
Throttle {
49
- /// Path for files to add
58
+ /// Path for files to add.
50
59
paths : Vec < PathBuf > ,
60
+ /// Delay in milliseconds after sending a chunk group of 16 KiB.
51
61
#[ clap( long, default_value = "100" ) ]
52
62
delay_ms : u64 ,
53
63
} ,
54
64
/// Limit maximum number of connections.
55
65
MaxConnections {
56
- /// Path for files to add
66
+ /// Path for files to add.
57
67
paths : Vec < PathBuf > ,
68
+ /// Maximum number of concurrent get requests.
58
69
#[ clap( long, default_value = "1" ) ]
59
70
max_connections : usize ,
60
71
} ,
72
+ /// Get a blob. Just for completeness sake.
61
73
Get {
62
74
/// Ticket for the blob to download
63
75
ticket : BlobTicket ,
@@ -84,6 +96,8 @@ fn limit_by_node_id(allowed_nodes: HashSet<NodeId>) -> EventSender {
84
96
EventSender :: new (
85
97
tx,
86
98
EventMask {
99
+ // We want a request for each incoming connection so we can accept
100
+ // or reject them. We don't need any other events.
87
101
connected : ConnectMode :: Request ,
88
102
..EventMask :: DEFAULT
89
103
} ,
@@ -112,6 +126,9 @@ fn limit_by_hash(allowed_hashes: HashSet<Hash>) -> EventSender {
112
126
EventSender :: new (
113
127
tx,
114
128
EventMask {
129
+ // We want to get a request for each get request that we can answer
130
+ // with OK or not OK depending on the hash. We do not want detailed
131
+ // events once it has been decided to handle a request.
115
132
get : RequestMode :: Request ,
116
133
..EventMask :: DEFAULT
117
134
} ,
@@ -128,6 +145,8 @@ fn throttle(delay_ms: u64) -> EventSender {
128
145
"Throttling {} {}, {}ms" ,
129
146
msg. connection_id, msg. request_id, delay_ms
130
147
) ;
148
+ // we could compute the delay from the size of the data to have a fixed rate.
149
+ // but the size is almost always 16 KiB (16 chunks).
131
150
tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( delay_ms) ) . await ;
132
151
msg. tx . send ( Ok ( ( ) ) ) . await . ok ( ) ;
133
152
} ) ;
@@ -137,6 +156,8 @@ fn throttle(delay_ms: u64) -> EventSender {
137
156
EventSender :: new (
138
157
tx,
139
158
EventMask {
159
+ // We want to get requests for each sent user data blob, so we can add a delay.
160
+ // Other than that, we don't need any events.
140
161
throttle : ThrottleMode :: Throttle ,
141
162
..EventMask :: DEFAULT
142
163
} ,
@@ -206,6 +227,10 @@ fn limit_max_connections(max_connections: usize) -> EventSender {
206
227
EventSender :: new (
207
228
tx,
208
229
EventMask {
230
+ // For each get request, we want to get a request so we can decide
231
+ // based on the current connection count if we want to accept or reject.
232
+ // We also want detailed logging of events for the get request, so we can
233
+ // detect when the request is finished one way or another.
209
234
get : RequestMode :: RequestLog ,
210
235
..EventMask :: DEFAULT
211
236
} ,
0 commit comments