1
+ use std:: collections:: HashMap ;
2
+ use std:: net:: SocketAddr ;
1
3
use std:: sync:: Arc ;
2
4
3
5
use bittorrent_http_tracker_core:: container:: HttpTrackerCoreContainer ;
@@ -65,6 +67,9 @@ pub struct AppContainer {
65
67
pub http_announce_service : Arc < bittorrent_http_tracker_core:: services:: announce:: AnnounceService > ,
66
68
pub http_scrape_service : Arc < bittorrent_http_tracker_core:: services:: scrape:: ScrapeService > ,
67
69
70
+ // HTTP Tracker Server Containers (one container per HTTP Tracker)
71
+ pub http_server_instance_containers : Arc < RwLock < HttpTrackerInstanceContainers > > ,
72
+
68
73
// UDP Tracker Server Services
69
74
pub udp_server_stats_event_sender : Arc < Option < Box < dyn torrust_udp_tracker_server:: event:: sender:: Sender > > > ,
70
75
pub udp_server_stats_repository : Arc < torrust_udp_tracker_server:: statistics:: repository:: Repository > ,
@@ -96,6 +101,9 @@ impl AppContainer {
96
101
http_stats_event_sender. clone ( ) ,
97
102
) ) ;
98
103
104
+ // HTTP Tracker Server Containers (one container per HTTP Tracker)
105
+ let http_server_instance_containers = Arc :: new ( RwLock :: new ( HttpTrackerInstanceContainers :: default ( ) ) ) ;
106
+
99
107
// UDP Tracker Core Services
100
108
let ( udp_core_stats_event_sender, udp_core_stats_repository) =
101
109
bittorrent_udp_tracker_core:: statistics:: setup:: factory ( configuration. core . tracker_usage_statistics ) ;
@@ -150,14 +158,37 @@ impl AppContainer {
150
158
http_announce_service,
151
159
http_scrape_service,
152
160
161
+ // HTTP Tracker Server Containers
162
+ http_server_instance_containers,
163
+
153
164
// UDP Tracker Server Services
154
165
udp_server_stats_event_sender,
155
166
udp_server_stats_repository,
156
167
}
157
168
}
158
169
159
170
#[ must_use]
160
- pub fn http_tracker_container ( & self , http_tracker_config : & Arc < HttpTracker > ) -> HttpTrackerCoreContainer {
171
+ pub async fn http_tracker_container ( & mut self , http_tracker_config : & Arc < HttpTracker > ) -> HttpTrackerCoreContainer {
172
+ let http_tracker_instance_container = if let Some ( http_tracker_instance_container) = self
173
+ . http_server_instance_containers
174
+ . read ( )
175
+ . await
176
+ . get ( & http_tracker_config. bind_address )
177
+ . await
178
+ {
179
+ http_tracker_instance_container
180
+ } else {
181
+ let http_server_instance_container = Arc :: new ( HttpTrackerInstanceContainer :: initialize ( http_tracker_config) ) ;
182
+
183
+ self . http_server_instance_containers
184
+ . write ( )
185
+ . await
186
+ . insert ( http_tracker_config, http_server_instance_container. clone ( ) )
187
+ . await ;
188
+
189
+ http_server_instance_container
190
+ } ;
191
+
161
192
HttpTrackerCoreContainer {
162
193
core_config : self . core_config . clone ( ) ,
163
194
announce_handler : self . announce_handler . clone ( ) ,
@@ -166,8 +197,8 @@ impl AppContainer {
166
197
authentication_service : self . authentication_service . clone ( ) ,
167
198
168
199
http_tracker_config : http_tracker_config. clone ( ) ,
169
- http_stats_event_sender : self . http_stats_event_sender . clone ( ) ,
170
- http_stats_repository : self . http_stats_repository . clone ( ) ,
200
+ http_stats_event_sender : http_tracker_instance_container . http_core_stats_event_sender . clone ( ) ,
201
+ http_stats_repository : http_tracker_instance_container . http_core_stats_repository . clone ( ) ,
171
202
announce_service : self . http_announce_service . clone ( ) ,
172
203
scrape_service : self . http_scrape_service . clone ( ) ,
173
204
}
@@ -214,3 +245,53 @@ impl AppContainer {
214
245
}
215
246
}
216
247
}
248
+
249
+ /// Container for each HTTP Tracker Server instance.
250
+ ///
251
+ /// Each instance runs on a different socket address. These services are not
252
+ /// shared between instances.
253
+ #[ derive( Default ) ]
254
+ pub struct HttpTrackerInstanceContainers {
255
+ instances : RwLock < HashMap < SocketAddr , Arc < HttpTrackerInstanceContainer > > > ,
256
+ }
257
+
258
+ impl HttpTrackerInstanceContainers {
259
+ pub async fn insert (
260
+ & mut self ,
261
+ http_tracker_config : & Arc < HttpTracker > ,
262
+ http_server_instance_container : Arc < HttpTrackerInstanceContainer > ,
263
+ ) {
264
+ self . instances
265
+ . write ( )
266
+ . await
267
+ . insert ( http_tracker_config. bind_address , http_server_instance_container) ;
268
+ }
269
+
270
+ #[ must_use]
271
+ pub async fn get ( & self , socket_addr : & SocketAddr ) -> Option < Arc < HttpTrackerInstanceContainer > > {
272
+ self . instances . read ( ) . await . get ( socket_addr) . cloned ( )
273
+ }
274
+ }
275
+
276
+ /// Container for HTTP Tracker Server instances.
277
+ #[ derive( Clone , Default ) ]
278
+ pub struct HttpTrackerInstanceContainer {
279
+ pub http_core_stats_event_sender : Arc < Option < Box < dyn bittorrent_http_tracker_core:: event:: sender:: Sender > > > ,
280
+ pub http_core_stats_repository : Arc < bittorrent_http_tracker_core:: statistics:: repository:: Repository > ,
281
+ }
282
+
283
+ impl HttpTrackerInstanceContainer {
284
+ #[ must_use]
285
+ pub fn initialize ( configuration : & HttpTracker ) -> Self {
286
+ let ( http_core_stats_event_sender, http_core_stats_repository) =
287
+ bittorrent_http_tracker_core:: statistics:: setup:: factory ( configuration. tracker_usage_statistics ) ;
288
+
289
+ let http_core_stats_event_sender = Arc :: new ( http_core_stats_event_sender) ;
290
+ let http_core_stats_repository = Arc :: new ( http_core_stats_repository) ;
291
+
292
+ Self {
293
+ http_core_stats_event_sender,
294
+ http_core_stats_repository,
295
+ }
296
+ }
297
+ }
0 commit comments