Skip to content

Commit

Permalink
Feature/restart service (#1554)
Browse files Browse the repository at this point in the history
* add restart button to service show page and restart rpc api

* Feature/restart rpc (#1555)

* add restart rpc and status

* wire up rpc

* add restarting bool

Co-authored-by: Aiden McClelland <me@drbonez.dev>

* check if service is restarting

* filter package when restarting to avoid glitch

Co-authored-by: Aiden McClelland <me@drbonez.dev>
  • Loading branch information
elvece and dr-bonez committed Jun 18, 2022
1 parent 900540f commit bf2f488
Show file tree
Hide file tree
Showing 18 changed files with 212 additions and 64 deletions.
6 changes: 4 additions & 2 deletions backend/src/backup/backup_bulk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,11 @@ async fn perform_backup<Db: DbHandle>(

main_status_model.lock(&mut tx, LockType::Write).await?;
let (started, health) = match main_status_model.get(&mut tx, true).await?.into_owned() {
MainStatus::Starting => (Some(Utc::now()), Default::default()),
MainStatus::Starting { .. } => (Some(Utc::now()), Default::default()),
MainStatus::Running { started, health } => (Some(started), health.clone()),
MainStatus::Stopped | MainStatus::Stopping => (None, Default::default()),
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
(None, Default::default())
}
MainStatus::BackingUp { .. } => {
backup_report.insert(
package_id,
Expand Down
6 changes: 4 additions & 2 deletions backend/src/context/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,12 +335,14 @@ impl RpcContext {
let main = match status.main {
MainStatus::BackingUp { started, .. } => {
if let Some(_) = started {
MainStatus::Starting
MainStatus::Starting { restarting: false }
} else {
MainStatus::Stopped
}
}
MainStatus::Running { .. } => MainStatus::Starting,
MainStatus::Running { .. } => {
MainStatus::Starting { restarting: false }
}
a => a.clone(),
};
let new_package = PackageDataEntry::Installed {
Expand Down
35 changes: 34 additions & 1 deletion backend/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ pub async fn start(
let mut tx = db.begin().await?;
let receipts = StartReceipts::new(&mut tx, &id).await?;
let version = receipts.version.get(&mut tx).await?;
receipts.status.set(&mut tx, MainStatus::Starting).await?;
receipts
.status
.set(&mut tx, MainStatus::Starting { restarting: false })
.await?;
heal_all_dependents_transitive(&ctx, &mut tx, &id, &receipts.dependency_receipt).await?;

let revision = tx.commit(None).await?;
Expand Down Expand Up @@ -181,3 +184,33 @@ pub async fn stop_impl(ctx: RpcContext, id: PackageId) -> Result<WithRevision<()
response: (),
})
}

#[command(display(display_none))]
pub async fn restart(
#[context] ctx: RpcContext,
#[arg] id: PackageId,
) -> Result<WithRevision<()>, Error> {
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;

let mut status = crate::db::DatabaseModel::new()
.package_data()
.idx_model(&id)
.and_then(|pde| pde.installed())
.map(|i| i.status().main())
.get_mut(&mut tx)
.await?;
if !matches!(&*status, Some(MainStatus::Running { .. })) {
return Err(Error::new(
eyre!("{} is not running", id),
crate::ErrorKind::InvalidRequest,
));
}
*status = Some(MainStatus::Restarting);
status.save(&mut tx).await?;

Ok(WithRevision {
revision: tx.commit(None).await?,
response: (),
})
}
9 changes: 3 additions & 6 deletions backend/src/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,19 @@ use rpc_toolkit::command;
use serde::{Deserialize, Serialize};
use tracing::instrument;

use crate::config::action::{ConfigActions, ConfigRes};
use crate::config::spec::PackagePointerSpec;
use crate::config::{not_found, Config, ConfigReceipts, ConfigSpec};
use crate::context::RpcContext;
use crate::db::model::{CurrentDependencies, CurrentDependents, InstalledPackageDataEntry};
use crate::procedure::{NoOutput, PackageProcedure};
use crate::procedure::{NoOutput, PackageProcedure, ProcedureName};
use crate::s9pk::manifest::{Manifest, PackageId};
use crate::status::health_check::{HealthCheckId, HealthCheckResult};
use crate::status::{MainStatus, Status};
use crate::util::serde::display_serializable;
use crate::util::{display_none, Version};
use crate::volume::Volumes;
use crate::Error;
use crate::{
config::action::{ConfigActions, ConfigRes},
procedure::ProcedureName,
};

#[command(subcommands(configure))]
pub fn dependency() -> Result<(), Error> {
Expand Down Expand Up @@ -339,7 +336,7 @@ impl DependencyError {
.await?
}
}
MainStatus::Starting => {
MainStatus::Starting { .. } | MainStatus::Restarting => {
DependencyError::Transitive
.try_heal(
ctx,
Expand Down
1 change: 1 addition & 0 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub fn server() -> Result<(), RpcError> {
config::config,
control::start,
control::stop,
control::restart,
logs::logs,
properties::properties,
dependencies::dependency,
Expand Down
17 changes: 10 additions & 7 deletions backend/src/manager/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ async fn synchronize_once(shared: &ManagerSharedState) -> Result<Status, Error>
MainStatus::Stopping => {
*status = MainStatus::Stopped;
}
MainStatus::Starting => {
MainStatus::Restarting => {
*status = MainStatus::Starting { restarting: true };
}
MainStatus::Starting { .. } => {
start(shared).await?;
}
MainStatus::Running { started, .. } => {
Expand All @@ -41,19 +44,19 @@ async fn synchronize_once(shared: &ManagerSharedState) -> Result<Status, Error>
MainStatus::BackingUp { .. } => (),
},
Status::Starting => match *status {
MainStatus::Stopped | MainStatus::Stopping => {
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
stop(shared).await?;
}
MainStatus::Starting | MainStatus::Running { .. } => (),
MainStatus::Starting { .. } | MainStatus::Running { .. } => (),
MainStatus::BackingUp { .. } => {
pause(shared).await?;
}
},
Status::Running => match *status {
MainStatus::Stopped | MainStatus::Stopping => {
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
stop(shared).await?;
}
MainStatus::Starting => {
MainStatus::Starting { .. } => {
*status = MainStatus::Running {
started: Utc::now(),
health: BTreeMap::new(),
Expand All @@ -65,10 +68,10 @@ async fn synchronize_once(shared: &ManagerSharedState) -> Result<Status, Error>
}
},
Status::Paused => match *status {
MainStatus::Stopped | MainStatus::Stopping => {
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => {
stop(shared).await?;
}
MainStatus::Starting | MainStatus::Running { .. } => {
MainStatus::Starting { .. } | MainStatus::Running { .. } => {
resume(shared).await?;
}
MainStatus::BackingUp { .. } => (),
Expand Down
12 changes: 8 additions & 4 deletions backend/src/status/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ pub struct Status {
#[serde(rename_all = "kebab-case")]
pub enum MainStatus {
Stopped,
Restarting,
Stopping,
Starting,
Starting {
restarting: bool,
},
Running {
started: DateTime<Utc>,
health: BTreeMap<HealthCheckId, HealthCheckResult>,
Expand All @@ -38,25 +41,26 @@ pub enum MainStatus {
impl MainStatus {
pub fn running(&self) -> bool {
match self {
MainStatus::Starting
MainStatus::Starting { .. }
| MainStatus::Running { .. }
| MainStatus::BackingUp {
started: Some(_), ..
} => true,
MainStatus::Stopped
| MainStatus::Stopping
| MainStatus::Restarting
| MainStatus::BackingUp { started: None, .. } => false,
}
}
pub fn stop(&mut self) {
match self {
MainStatus::Starting | MainStatus::Running { .. } => {
MainStatus::Starting { .. } | MainStatus::Running { .. } => {
*self = MainStatus::Stopping;
}
MainStatus::BackingUp { started, .. } => {
*started = None;
}
MainStatus::Stopped | MainStatus::Stopping => (),
MainStatus::Stopped | MainStatus::Stopping | MainStatus::Restarting => (),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NavController } from '@ionic/angular'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import {
PackageDataEntry,
PackageMainStatus,
PackageState,
} from 'src/app/services/patch-db/data-model'
import {
Expand All @@ -13,7 +14,7 @@ import {
ConnectionFailure,
ConnectionService,
} from 'src/app/services/connection.service'
import { map, startWith } from 'rxjs/operators'
import { map, startWith, filter } from 'rxjs/operators'
import { ActivatedRoute } from '@angular/router'
import { getPkgId } from '@start9labs/shared'

Expand All @@ -32,6 +33,13 @@ export class AppShowPage {
private readonly pkgId = getPkgId(this.route)

readonly pkg$ = this.patch.watch$('package-data', this.pkgId).pipe(
filter(
(p: PackageDataEntry) =>
!(
p.installed?.status.main.status === PackageMainStatus.Starting &&
p.installed?.status.main.restarting
),
),
map(pkg => {
// if package disappears, navigate to list page
if (!pkg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
<ion-icon slot="start" name="stop-outline"></ion-icon>
Stop
</ion-button>
<ion-button
class="action-button"
color="warning"
(click)="tryRestart()"
>
<ion-icon slot="start" name="refresh"></ion-icon>
Restart
</ion-button>
</ng-container>

<ion-button
Expand Down Expand Up @@ -58,4 +66,4 @@
</ion-col>
</ion-row>
</ion-grid>
</ng-container>
</ng-container>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

.action-button {
margin: 20px 20px 10px 0;
margin: 12px 20px 10px 0;
min-height: 42px;
min-width: 140px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ export class AppShowStatusComponent {
}
}

<<<<<<< HEAD
=======
async tryRestart(): Promise<void> {
if (hasCurrentDeps(this.pkg)) {
const alert = await this.alertCtrl.create({
Expand All @@ -165,7 +163,28 @@ export class AppShowStatusComponent {
}
}

>>>>>>> 918a1907... Remove app wiz and dry calls (#1541)
async presentAlertRestart(): Promise<void> {
const alert = await this.alertCtrl.create({
header: 'Confirm',
message: 'Are you sure you want to restart this service?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
},
{
text: 'Restart',
handler: () => {
this.restart()
},
cssClass: 'enter-click',
},
],
})

await alert.present()
}

private async start(): Promise<void> {
const loader = await this.loadingCtrl.create({
message: `Starting...`,
Expand All @@ -181,8 +200,6 @@ export class AppShowStatusComponent {
}
}

<<<<<<< HEAD
=======
private async stop(): Promise<void> {
const loader = await this.loadingCtrl.create({
message: 'Stopping...',
Expand Down Expand Up @@ -212,8 +229,6 @@ export class AppShowStatusComponent {
loader.dismiss()
}
}

>>>>>>> 918a1907... Remove app wiz and dry calls (#1541)
private async presentAlertStart(message: string): Promise<boolean> {
return new Promise(async resolve => {
const alert = await this.alertCtrl.create({
Expand Down
3 changes: 3 additions & 0 deletions frontend/projects/ui/src/app/services/api/api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ export module RR {
export type StartPackageReq = WithExpire<{ id: string }> // package.start
export type StartPackageRes = WithRevision<null>

export type RestartPackageReq = WithExpire<{ id: string }> // package.restart
export type RestartPackageRes = WithRevision<null>

export type StopPackageReq = WithExpire<{ id: string }> // package.stop
export type StopPackageRes = WithRevision<null>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,12 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
startPackage = (params: RR.StartPackageReq) =>
this.syncResponse(() => this.startPackageRaw(params))()

protected abstract restartPackageRaw(
params: RR.RestartPackageReq,
): Promise<RR.RestartPackageRes>
restartPackage = (params: RR.RestartPackageReq) =>
this.syncResponse(() => this.restartPackageRaw(params))()

protected abstract stopPackageRaw(
params: RR.StopPackageReq,
): Promise<RR.StopPackageRes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,12 @@ export class LiveApiService extends ApiService {
return this.http.rpcRequest({ method: 'package.start', params })
}

async restartPackageRaw(
params: RR.RestartPackageReq,
): Promise<RR.RestartPackageRes> {
return this.http.rpcRequest({ method: 'package.restart', params })
}

async stopPackageRaw(params: RR.StopPackageReq): Promise<RR.StopPackageRes> {
return this.http.rpcRequest({ method: 'package.stop', params })
}
Expand Down
Loading

0 comments on commit bf2f488

Please sign in to comment.