Skip to content

Commit 844b681

Browse files
committed
Refactor/service-framework: start_wrapped and stop_wrapped (#32)
Refactor service start_wrapped and stop_wrapped have been removed from the Service trait and the logic has been implemented in the Service Manager.
1 parent fcb62cd commit 844b681

File tree

1 file changed

+92
-74
lines changed

1 file changed

+92
-74
lines changed

src/service.rs

Lines changed: 92 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -151,67 +151,6 @@ pub trait Service: DowncastSync {
151151
fn start(&mut self, service_manager: Arc<ServiceManager>) -> PinnedBoxedFutureResult<'_, ()>;
152152
fn stop(&mut self) -> PinnedBoxedFutureResult<'_, ()>;
153153

154-
// Used for downcasting in get_service method of ServiceManager
155-
//fn as_any_arc(&self) -> Arc<dyn Any + Send + Sync>;
156-
157-
fn wrapped_start(&mut self, service_manager: Arc<ServiceManager>) -> PinnedBoxedFuture<()> {
158-
Box::pin(async move {
159-
let mut status = self.info().status.write().await;
160-
161-
if !matches!(&*status, Status::Stopped) {
162-
warn!(
163-
"Tried to start service {} while it was in state {}. Ignoring start request.",
164-
self.info().name,
165-
status
166-
);
167-
return;
168-
}
169-
170-
*status = Status::Starting;
171-
drop(status);
172-
173-
match self.start(service_manager).await {
174-
Ok(()) => {
175-
info!("Started service: {}", self.info().name);
176-
self.info().set_status(Status::Started).await;
177-
}
178-
Err(error) => {
179-
error!("Failed to start service {}: {}", self.info().name, error);
180-
self.info().set_status(Status::FailedToStart(error)).await;
181-
}
182-
}
183-
})
184-
}
185-
186-
fn wrapped_stop(&mut self) -> PinnedBoxedFuture<'_, ()> {
187-
Box::pin(async move {
188-
let mut status = self.info().status.write().await;
189-
190-
if !matches!(&*status, Status::Started) {
191-
warn!(
192-
"Tried to stop service {} while it was in state {}. Ignoring stop request.",
193-
self.info().name,
194-
status
195-
);
196-
return;
197-
}
198-
199-
*status = Status::Stopping;
200-
drop(status);
201-
202-
match self.stop().await {
203-
Ok(()) => {
204-
info!("Stopped service: {}", self.info().name);
205-
self.info().set_status(Status::Stopped).await;
206-
}
207-
Err(error) => {
208-
error!("Failed to stop service {}: {}", self.info().name, error);
209-
self.info().set_status(Status::FailedToStop(error)).await;
210-
}
211-
}
212-
})
213-
}
214-
215154
fn is_available(&self) -> PinnedBoxedFuture<'_, bool> {
216155
Box::pin(async move { matches!(&*(self.info().status.read().await), Status::Started) })
217156
}
@@ -316,23 +255,102 @@ impl ServiceManager {
316255
ServiceManagerBuilder::new()
317256
}
318257

319-
pub fn start_services(&self) -> PinnedBoxedFuture<'_, ()> {
320-
Box::pin(async move {
321-
for service in &self.services {
322-
let mut service = service.write().await;
323-
let service_manager = Arc::clone(self.arc.read().await.unwrap());
324-
service.wrapped_start(service_manager).await;
258+
pub async fn manages_service(&self, service: &Arc<RwLock<dyn Service>>) -> bool {
259+
for registered_service in self.services.iter() {
260+
if registered_service.read().await.info().id == service.read().await.info().id {
261+
return true;
325262
}
326-
})
263+
}
264+
265+
false
327266
}
328267

329-
pub fn stop_services(&self) -> PinnedBoxedFuture<'_, ()> {
330-
Box::pin(async move {
331-
for service in &self.services {
332-
let mut service = service.write().await;
333-
service.wrapped_stop().await;
268+
pub async fn start_service(&self, service: Arc<RwLock<dyn Service>>) {
269+
if !self.manages_service(&service).await {
270+
warn!(
271+
"Tried to start service {} ({}), but it's not managed by this Service Manager. Ignoring start request.",
272+
service.read().await.info().name,
273+
service.read().await.info().id
274+
);
275+
return;
276+
}
277+
278+
let mut service = service.write().await;
279+
280+
let mut status = service.info().status.write().await;
281+
if !matches!(&*status, Status::Stopped) {
282+
warn!(
283+
"Tried to start service {} while it was in state {}. Ignoring start request.",
284+
service.info().name,
285+
status
286+
);
287+
return;
288+
}
289+
*status = Status::Starting;
290+
drop(status);
291+
292+
let service_manager = Arc::clone(self.arc.read().await.unwrap());
293+
match service.start(service_manager).await {
294+
Ok(()) => {
295+
info!("Started service: {}", service.info().name);
296+
service.info().set_status(Status::Started).await;
334297
}
335-
})
298+
Err(error) => {
299+
error!("Failed to start service {}: {}", service.info().name, error);
300+
service
301+
.info()
302+
.set_status(Status::FailedToStart(error))
303+
.await;
304+
}
305+
}
306+
}
307+
308+
pub async fn stop_service(&self, service: Arc<RwLock<dyn Service>>) {
309+
if !self.manages_service(&service).await {
310+
warn!(
311+
"Tried to stop service {} ({}), but it's not managed by this Service Manager. Ignoring stop request.",
312+
service.read().await.info().name,
313+
service.read().await.info().id
314+
);
315+
return;
316+
}
317+
318+
let mut service = service.write().await;
319+
320+
let mut status = service.info().status.write().await;
321+
if !matches!(&*status, Status::Started) {
322+
warn!(
323+
"Tried to stop service {} while it was in state {}. Ignoring stop request.",
324+
service.info().name,
325+
status
326+
);
327+
return;
328+
}
329+
*status = Status::Stopping;
330+
drop(status);
331+
332+
match service.stop().await {
333+
Ok(()) => {
334+
info!("Stopped service: {}", service.info().name);
335+
service.info().set_status(Status::Stopped).await;
336+
}
337+
Err(error) => {
338+
error!("Failed to stop service {}: {}", service.info().name, error);
339+
service.info().set_status(Status::FailedToStop(error)).await;
340+
}
341+
}
342+
}
343+
344+
pub async fn start_services(&self) {
345+
for service in &self.services {
346+
self.start_service(Arc::clone(service)).await;
347+
}
348+
}
349+
350+
pub async fn stop_services(&self) {
351+
for service in &self.services {
352+
self.stop_service(Arc::clone(service)).await;
353+
}
336354
}
337355

338356
pub async fn get_service<T>(&self) -> Option<Arc<RwLock<T>>>

0 commit comments

Comments
 (0)