Skip to content

Commit

Permalink
Merge pull request #4810 from wasmerio/issue-4795-cli-app-cache-purge
Browse files Browse the repository at this point in the history
feat(cli): Add "app purge-cache" command
  • Loading branch information
syrusakbary authored Jun 5, 2024
2 parents cac4312 + 4170a09 commit dd8c3a3
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 28 deletions.
3 changes: 3 additions & 0 deletions benches/import_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub fn run_import_inner(store: &mut Store, n_fn: u32, compiler_name: &str, c: &m
}

fn run_import_functions_benchmarks_small(_c: &mut Criterion) {
#[allow(unused_variables)]
let size = 10;

#[cfg(feature = "llvm")]
Expand All @@ -78,6 +79,7 @@ fn run_import_functions_benchmarks_small(_c: &mut Criterion) {
}

fn run_import_functions_benchmarks_medium(_c: &mut Criterion) {
#[allow(unused_variables)]
let size = 100;

#[cfg(feature = "llvm")]
Expand All @@ -100,6 +102,7 @@ fn run_import_functions_benchmarks_medium(_c: &mut Criterion) {
}

fn run_import_functions_benchmarks_large(_c: &mut Criterion) {
#[allow(unused_variables)]
let size = 1000;
#[cfg(feature = "llvm")]
{
Expand Down
78 changes: 54 additions & 24 deletions lib/backend-api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type User implements Node & PackageOwner & Owner {
bio: String
location: String
websiteUrl: String
wasmerInternal: Boolean!

"""The ID of the object"""
id: ID!
Expand Down Expand Up @@ -199,6 +200,7 @@ type Namespace implements Node & PackageOwner & Owner {
websiteUrl: String
createdAt: DateTime!
updatedAt: DateTime!
wasmerInternal: Boolean!
maintainerInvites(offset: Int, before: String, after: String, first: Int, last: Int): NamespaceCollaboratorInviteConnection!
userSet(offset: Int, before: String, after: String, first: Int, last: Int): UserConnection!
globalName: String!
Expand Down Expand Up @@ -446,6 +448,7 @@ type PackageVersion implements Node & PackageReleaseInterface & PackageInstance
bindingsState: RegistryPackageVersionBindingsStateChoices!
nativeExecutablesState: RegistryPackageVersionNativeExecutablesStateChoices!
deployappversionSet(offset: Int, before: String, after: String, first: Int, last: Int): DeployAppVersionConnection!
packagewebcSet(offset: Int, before: String, after: String, first: Int, last: Int): PackageWebcConnection!
lastversionPackage(offset: Int, before: String, after: String, first: Int, last: Int): PackageConnection!
commands: [Command!]!
nativeexecutableSet(offset: Int, before: String, after: String, first: Int, last: Int): NativeExecutableConnection!
Expand Down Expand Up @@ -504,7 +507,9 @@ scalar JSONString
type WebcImage implements Node {
"""The ID of the object"""
id: ID!
version: WebcVersion

"""The version of the webc image, defaults to v2."""
version: WebcVersion!

""""""
fileSize: BigInt!
Expand Down Expand Up @@ -835,6 +840,26 @@ type AppVersionVolumeMountPath {
subpath: String!
}

type PackageWebcConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!

"""Contains the nodes in this connection."""
edges: [PackageWebcEdge]!

"""Total number of items in the connection."""
totalCount: Int
}

"""A Relay edge containing a `PackageWebc` and its cursor."""
type PackageWebcEdge {
"""The item at the end of the edge"""
node: PackageWebc

"""A cursor for use in pagination"""
cursor: String!
}

type Command {
command: String!
packageVersion: PackageVersion!
Expand Down Expand Up @@ -1227,26 +1252,6 @@ type AppTemplateCategory implements Node {
appTemplates(offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection!
}

type PackageWebcConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!

"""Contains the nodes in this connection."""
edges: [PackageWebcEdge]!

"""Total number of items in the connection."""
totalCount: Int
}

"""A Relay edge containing a `PackageWebc` and its cursor."""
type PackageWebcEdge {
"""The item at the end of the edge"""
node: PackageWebc

"""A cursor for use in pagination"""
cursor: String!
}

type Collection {
slug: String!
displayName: String!
Expand Down Expand Up @@ -2088,6 +2093,9 @@ type Log {

"""Log stream"""
stream: LogStream

"""ID of instance from which the log was generated"""
instanceId: String!
}

"""This is for backwards compatibility with the old PackageInstance type."""
Expand Down Expand Up @@ -2249,7 +2257,7 @@ type Query {
getAppByGlobalAlias(alias: String!): DeployApp
getDeployApps(sortBy: DeployAppsSortBy, updatedAfter: DateTime, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppConnection!
getAppVersions(sortBy: DeployAppVersionsSortBy, updatedAfter: DateTime, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppVersionConnection!
getAppTemplates(categorySlug: String, offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection
getAppTemplates(categorySlug: String, sortBy: AppTemplatesSortBy, offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection
getAppTemplate(slug: String!): AppTemplate
getAppTemplateCategories(offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateCategoryConnection
viewer: User
Expand Down Expand Up @@ -2348,6 +2356,12 @@ enum DNSRecordsSortBy {
OLDEST
}

enum AppTemplatesSortBy {
NEWEST
OLDEST
POPULAR
}

type AppTemplateCategoryConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!
Expand Down Expand Up @@ -2788,6 +2802,9 @@ type Mutation {
generateDeployConfigToken(input: GenerateDeployConfigTokenInput!): GenerateDeployConfigTokenPayload
renameApp(input: RenameAppInput!): RenameAppPayload
renameAppAlias(input: RenameAppAliasInput!): RenameAppAliasPayload

"""Purges all cache for this app version"""
purgeCacheForAppVersion(input: PurgeCacheForAppVersionInput!): PurgeCacheForAppVersionPayload
requestAppTransfer(input: RequestAppTransferInput!): RequestAppTransferPayload
acceptAppTransferRequest(input: AcceptAppTransferRequestInput!): AcceptAppTransferRequestPayload
removeAppTransferRequest(input: RemoveAppTransferRequestInput!): RemoveAppTransferRequestPayload
Expand Down Expand Up @@ -3026,6 +3043,18 @@ input RenameAppAliasInput {
clientMutationId: String
}

"""Purges all cache for this app version"""
type PurgeCacheForAppVersionPayload {
appVersion: DeployAppVersion!
clientMutationId: String
}

input PurgeCacheForAppVersionInput {
"""ID of the app version to purge cache for."""
id: ID!
clientMutationId: String
}

type RequestAppTransferPayload {
appTransferRequest: AppTransferRequest
wasInstantlyTransferred: Boolean!
Expand Down Expand Up @@ -3086,6 +3115,7 @@ input CreateRepoForAppTemplateInput {
name: String!
namespace: String!
private: Boolean = false
domains: [String] = null
clientMutationId: String
}

Expand Down Expand Up @@ -3606,9 +3636,9 @@ type TagPackageReleasePayload {

input TagPackageReleaseInput {
packageReleaseId: ID!
name: String!
version: String!
manifest: String!
name: String
manifest: String
namespace: String
description: String
license: String
Expand Down
14 changes: 14 additions & 0 deletions lib/backend-api/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,20 @@ pub fn get_all_dns_records_stream(
)
}

pub async fn purge_cache_for_app_version(
client: &WasmerClient,
vars: types::PurgeCacheForAppVersionVars,
) -> Result<(), anyhow::Error> {
client
.run_graphql_strict(types::PurgeCacheForAppVersion::build(vars))
.await
.map_err(anyhow::Error::from)
.map(|x| x.purge_cache_for_app_version)
.context("backend did not return data")?;

Ok(())
}

/// Convert a [`OffsetDateTime`] to a unix timestamp that the WAPM backend
/// understands.
fn unix_timestamp(ts: OffsetDateTime) -> f64 {
Expand Down
17 changes: 17 additions & 0 deletions lib/backend-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,23 @@ mod queries {
pub records: Option<Vec<Option<DnsRecord>>>,
}

#[derive(cynic::QueryVariables, Debug)]
pub struct PurgeCacheForAppVersionVars {
pub id: cynic::Id,
}

#[derive(cynic::QueryFragment, Debug)]
pub struct PurgeCacheForAppVersionPayload {
pub app_version: DeployAppVersion,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Mutation", variables = "PurgeCacheForAppVersionVars")]
pub struct PurgeCacheForAppVersion {
#[arguments(input: {id: $id})]
pub purge_cache_for_app_version: Option<PurgeCacheForAppVersionPayload>,
}

#[derive(cynic::Scalar, Debug, Clone)]
pub struct BigInt(pub i64);

Expand Down
7 changes: 5 additions & 2 deletions lib/cli/src/commands/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod get;
pub mod info;
pub mod list;
pub mod logs;
pub mod purge_cache;
pub mod version;

mod util;
Expand All @@ -16,15 +17,16 @@ use crate::commands::AsyncCliCommand;
/// Manage Wasmer Deploy apps.
#[derive(clap::Subcommand, Debug)]
pub enum CmdApp {
Deploy(deploy::CmdAppDeploy),
Create(create::CmdAppCreate),
Get(get::CmdAppGet),
Info(info::CmdAppInfo),
List(list::CmdAppList),
Logs(logs::CmdAppLogs),
Create(create::CmdAppCreate),
PurgeCache(purge_cache::CmdAppPurgeCache),
Delete(delete::CmdAppDelete),
#[clap(subcommand)]
Version(version::CmdAppVersion),
Deploy(deploy::CmdAppDeploy),
}

#[async_trait::async_trait]
Expand All @@ -50,6 +52,7 @@ impl AsyncCliCommand for CmdApp {
Self::Delete(cmd) => cmd.run_async().await,
Self::Version(cmd) => cmd.run_async().await,
Self::Deploy(cmd) => cmd.run_async().await,
Self::PurgeCache(cmd) => cmd.run_async().await,
}
}
}
54 changes: 54 additions & 0 deletions lib/cli/src/commands/app/purge_cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Get information about an edge app.
use super::util::AppIdentOpts;
use crate::{
commands::AsyncCliCommand,
opts::{ApiOpts, ItemFormatOpts},
};

/// Purge caches for applications.
///
/// Cache scopes that can be cleared:
/// * InstaBoot startup snapshots
/// Will delete all existing snapshots.
/// New snapshots will be created automatically.
#[derive(clap::Parser, Debug)]
pub struct CmdAppPurgeCache {
#[clap(flatten)]
#[allow(missing_docs)]
pub api: ApiOpts,
#[clap(flatten)]
#[allow(missing_docs)]
pub fmt: ItemFormatOpts,

#[clap(flatten)]
#[allow(missing_docs)]
pub ident: AppIdentOpts,
}

#[async_trait::async_trait]
impl AsyncCliCommand for CmdAppPurgeCache {
type Output = ();

async fn run_async(self) -> Result<(), anyhow::Error> {
let client = self.api.client()?;
let (_ident, app) = self.ident.load_app(&client).await?;

let version_id = app.active_version.id;

let name = format!("{} ({})", app.name, app.owner.global_name);

println!(
"Purging caches for {}, app version {}...",
name,
version_id.inner()
);

let vars = wasmer_api::types::PurgeCacheForAppVersionVars { id: version_id };
wasmer_api::query::purge_cache_for_app_version(&client, vars).await?;

println!("🚽 swirl! All caches have been purged!");

Ok(())
}
}
7 changes: 5 additions & 2 deletions lib/cli/src/commands/app/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ pub fn get_app_config_from_current_dir() -> Result<(AppConfigV1, std::path::Path
///
/// Provides convenience methods for resolving an app identifier or loading it
/// from a local app.yaml.
///
/// NOTE: this is a separate struct to prevent the need for copy-pasting the
/// field docs
#[derive(clap::Parser, Debug)]
pub struct AppIdentOpts {
/// Identifier of the application.
Expand All @@ -123,7 +126,7 @@ pub struct AppIdentOpts {
/// - namespace/app-name
/// - app-alias
/// - App ID
pub app_ident: Option<AppIdent>,
pub app: Option<AppIdent>,
}

// Allowing because this is not performance-critical at all.
Expand All @@ -148,7 +151,7 @@ impl ResolvedAppIdent {

impl AppIdentOpts {
pub fn resolve_static(&self) -> Result<ResolvedAppIdent, anyhow::Error> {
if let Some(id) = &self.app_ident {
if let Some(id) = &self.app {
return Ok(ResolvedAppIdent::Ident(id.clone()));
}

Expand Down

0 comments on commit dd8c3a3

Please sign in to comment.