Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions lore-aws/src/dynamodb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,6 @@ const QUERY_ROWS: [f64; 10] = [

pub const METRICS_ACCUMULATION_OPERATION_LATENCY_METRIC_NAME: &str =
"accumulation_operation_duration";

/// Temporary environment variable to allow enabling/disabling query pagination.
/// TODO(jcohen): Remove this when we're confident in the pagination support.
static ENABLE_QUERY_PAGINATION: LazyLock<bool> =
LazyLock::new(|| match std::env::var("LORE_ENABLE_QUERY_PAGINATION") {
Ok(v) => v.eq_ignore_ascii_case("true"),
Err(_) => true, // Default to enabled if the env var isn't present
});

pub trait DynamoDbQuery {
fn index_name(&self) -> Option<String> {
None
Expand Down Expand Up @@ -575,6 +566,10 @@ impl DynamoDbImpl {
where
T: DynamoDbQuery + 'static,
{
if matches!(query.select(), Some(Select::Count)) && query.limit().is_some() {
panic!("Combining Select::Count and a limit is disallowed for paginated queries to avoid fetching count one row at a time.");
}

let base_labels = {
let mut labels = self
.instruments
Expand Down Expand Up @@ -651,12 +646,7 @@ impl DynamoDbImpl {
// the desired number of rows, there's no need to continue fetching more
// rows.
// 3. *Unless* the query is also a count query (in which case we need to fetch
// until there's no more data to collect to ensure we get the correct count).
// TODO(jcohen): We should probably disallow the combination of `Select::Count`
// and a limit to avoid the degenerate case of fetching a full count one row at
// a time.
if *ENABLE_QUERY_PAGINATION
&& let Some(last_evaluated_key) = r.last_evaluated_key
if let Some(last_evaluated_key) = r.last_evaluated_key
&& !last_evaluated_key.is_empty()
&& (query.limit().is_none()
|| matches!(query.select(), Some(Select::Count))
Expand Down
56 changes: 24 additions & 32 deletions lore-capi/lore.h
Original file line number Diff line number Diff line change
Expand Up @@ -1459,22 +1459,18 @@ typedef struct lore_link_entry_event_data_t {
uint32_t flags;
} lore_link_entry_event_data_t;

// Data for an event that marks the start of a lock acquire report.
typedef struct lore_lock_file_acquire_begin_event_data_t {
// Number of acquire entries that follow.
uint64_t count;
// Whether this is a dry-run preview.
uint8_t dry_run;
// Whether the entries that follow were already owned.
uint8_t ignored;
} lore_lock_file_acquire_begin_event_data_t;

// Data for an event reporting a path whose lock is being acquired.
// Data for an event reporting a path whose lock was acquired.
typedef struct lore_lock_file_acquire_event_data_t {
// The path whose lock is being acquired.
// Path whose lock was acquired.
struct lore_string_t path;
} lore_lock_file_acquire_event_data_t;

// Data for an event reporting a path that was skipped because its lock was already held.
typedef struct lore_lock_file_acquire_ignore_event_data_t {
// Path that was skipped.
struct lore_string_t path;
} lore_lock_file_acquire_ignore_event_data_t;

// Data for an event that marks the start of a lock status report.
typedef struct lore_lock_file_status_begin_event_data_t {
// Number of status entries that follow.
Expand Down Expand Up @@ -1509,22 +1505,18 @@ typedef struct lore_lock_file_query_event_data_t {
uint64_t locked_at;
} lore_lock_file_query_event_data_t;

// Data for an event that marks the start of a lock release report.
typedef struct lore_lock_file_release_begin_event_data_t {
// Number of release entries that follow.
uint64_t count;
// Whether this is a dry-run preview.
uint8_t dry_run;
// Whether no matching lock was found to release.
uint8_t not_found;
} lore_lock_file_release_begin_event_data_t;

// Data for an event reporting a path whose lock is being released.
// Data for an event reporting a path whose lock was released.
typedef struct lore_lock_file_release_event_data_t {
// The path whose lock is being released.
// Path whose lock was released.
struct lore_string_t path;
} lore_lock_file_release_event_data_t;

// Data for an event reporting that no matching lock was found to release.
typedef struct lore_lock_file_release_not_found_event_data_t {
// Placeholder field; carries no meaningful value.
uint32_t _unused;
} lore_lock_file_release_not_found_event_data_t;

// Data for an event reporting that a file's metadata was cleared.
typedef struct lore_metadata_clear_file_event_data_t {
// Path of the file whose metadata was cleared.
Expand Down Expand Up @@ -2871,10 +2863,10 @@ enum lore_event_id_t {
LORE_EVENT_LINK_CHANGE,
// One entry in a link listing.
LORE_EVENT_LINK_ENTRY,
// The start of a file lock acquire report.
LORE_EVENT_LOCK_FILE_ACQUIRE_BEGIN,
// A file concerning the lock acquire report.
// A file lock was acquired.
LORE_EVENT_LOCK_FILE_ACQUIRE,
// A file lock acquisition was ignored.
LORE_EVENT_LOCK_FILE_ACQUIRE_IGNORE,
// The start of a file lock status report.
LORE_EVENT_LOCK_FILE_STATUS_BEGIN,
// One file lock status entry.
Expand All @@ -2883,10 +2875,10 @@ enum lore_event_id_t {
LORE_EVENT_LOCK_FILE_QUERY_BEGIN,
// One file lock query result.
LORE_EVENT_LOCK_FILE_QUERY,
// The start of a file lock release report.
LORE_EVENT_LOCK_FILE_RELEASE_BEGIN,
// A file concerning the lock release report.
// A file lock was released.
LORE_EVENT_LOCK_FILE_RELEASE,
// A file lock to release was not found.
LORE_EVENT_LOCK_FILE_RELEASE_NOT_FOUND,
// Metadata was cleared on a file.
LORE_EVENT_METADATA_CLEAR_FILE,
// Metadata was cleared on a revision.
Expand Down Expand Up @@ -3183,14 +3175,14 @@ typedef struct lore_event_t {
struct lore_layer_staged_entry_event_data_t layer_staged_entry;
struct lore_link_change_event_data_t link_change;
struct lore_link_entry_event_data_t link_entry;
struct lore_lock_file_acquire_begin_event_data_t lock_file_acquire_begin;
struct lore_lock_file_acquire_event_data_t lock_file_acquire;
struct lore_lock_file_acquire_ignore_event_data_t lock_file_acquire_ignore;
struct lore_lock_file_status_begin_event_data_t lock_file_status_begin;
struct lore_lock_file_status_event_data_t lock_file_status;
struct lore_lock_file_query_begin_event_data_t lock_file_query_begin;
struct lore_lock_file_query_event_data_t lock_file_query;
struct lore_lock_file_release_begin_event_data_t lock_file_release_begin;
struct lore_lock_file_release_event_data_t lock_file_release;
struct lore_lock_file_release_not_found_event_data_t lock_file_release_not_found;
struct lore_metadata_clear_file_event_data_t metadata_clear_file;
struct lore_metadata_clear_revision_event_data_t metadata_clear_revision;
struct lore_path_ignore_event_data_t path_ignore;
Expand Down
7 changes: 3 additions & 4 deletions lore-client/src/cli/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use crate::println;
use crate::styling::cli_styles;
use crate::util::get_repository_path;

// TODO(UCS-12558): Cleanup logging args
#[derive(Parser)]
#[command(name = "lore", styles = cli_styles())]
#[clap(about, long_about = None)]
Expand All @@ -31,15 +30,15 @@ pub struct LoreCli {
pub repository: Option<String>,

/// Set the logging level
#[clap(global = true, long = "log-level", value_name = "level")]
#[clap(global = true, long = "log-level", value_name = "level", conflicts_with_all = ["debug", "silent"])]
pub level: Option<String>,

/// Enable debug output
#[clap(global = true, long, short, action)]
#[clap(global = true, long, short, action, conflicts_with_all = ["level", "silent"])]
pub debug: bool,

/// Suppress all output
#[clap(global = true, hide = true, long, short, action)]
#[clap(global = true, hide = true, long, short, action, conflicts_with_all = ["level", "debug"])]
pub silent: bool,

/// Time execution of command
Expand Down
9 changes: 3 additions & 6 deletions lore-client/src/cli/commands/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,10 +839,7 @@ pub fn handle_file_diff(globals: LoreGlobalArgs, args: &FileDiffArgs) -> u8 {
LoreEvent::FileDiff(data) => {
// Always show unified diff patches for all actions
match data.action {
LoreFileAction::Keep
| LoreFileAction::Delete
| LoreFileAction::Add
| LoreFileAction::Move => {
LoreFileAction::Keep | LoreFileAction::Delete | LoreFileAction::Add => {
// Show patch content
println!();
println!(
Expand Down Expand Up @@ -871,8 +868,8 @@ pub fn handle_file_diff(globals: LoreGlobalArgs, args: &FileDiffArgs) -> u8 {
}
println!();
}
LoreFileAction::Copy => {
// Status format for Copy
_ => {
// Status format for Copy/Move
println!(
"{}{}{} {}",
FileActionStyle::from_action(data.action),
Expand Down
59 changes: 36 additions & 23 deletions lore-client/src/cli/commands/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: MIT
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;

use chrono::DateTime;
use clap::Args;
Expand Down Expand Up @@ -105,19 +107,30 @@ fn handle_lock_acquire(globals: LoreGlobalArgs, args: &FileLockAcquireArgs) -> u
branch: LoreString::from(&args.branch),
};

let first_lock_acquire: Arc<AtomicBool> = Arc::new(AtomicBool::new(true));
let first_lock_acquire_ignore: Arc<AtomicBool> = Arc::new(AtomicBool::new(true));
let callback = output_formatter().unwrap_or(Some(
(Box::new(move |event: &LoreEvent| match event {
LoreEvent::LockFileAcquireBegin(data) if data.count > 0 => {
let header = if data.ignored != 0 {
"Lock already owned on files:"
} else if data.dry_run != 0 {
"Lock would be acquired on files:"
} else {
"Lock acquired on files:"
};
println!("{}{}{}", CommonStyles::HEADERS, header, anstyle::Reset);
}
LoreEvent::LockFileAcquire(data) => {
if first_lock_acquire.load(Ordering::Relaxed) {
first_lock_acquire.store(false, Ordering::Relaxed);
println!(
"{}Lock acquired on files:{}",
CommonStyles::HEADERS,
anstyle::Reset
);
}
println!("{}", data.path.as_str());
}
LoreEvent::LockFileAcquireIgnore(data) => {
if first_lock_acquire_ignore.load(Ordering::Relaxed) {
first_lock_acquire_ignore.store(false, Ordering::Relaxed);
println!(
"{}Lock already owned on files:{}",
CommonStyles::HEADERS,
anstyle::Reset
);
}
println!("{}", data.path.as_str());
}
_ => {}
Expand Down Expand Up @@ -244,27 +257,27 @@ fn handle_lock_release(globals: LoreGlobalArgs, args: &FileLockReleaseArgs) -> u

let globals = globals.clone();

let first_event: Arc<AtomicBool> = Arc::new(AtomicBool::new(true));
let callback = output_formatter().unwrap_or(Some(
(Box::new(move |event: &LoreEvent| match event {
LoreEvent::LockFileReleaseBegin(data) => {
if data.not_found != 0 {
LoreEvent::LockFileRelease(data) => {
if first_event.load(Ordering::Relaxed) {
first_event.store(false, Ordering::Relaxed);
println!(
"{}Lock does not exist for requested files{}",
LogStyles::WARNING,
"{}Lock released on files:{}",
CommonStyles::HEADERS,
anstyle::Reset
);
} else if data.count > 0 {
let header = if data.dry_run != 0 {
"Lock would be released on files:"
} else {
"Lock released on files:"
};
println!("{}{}{}", CommonStyles::HEADERS, header, anstyle::Reset);
}
}
LoreEvent::LockFileRelease(data) => {
println!("{}", data.path.as_str());
}
LoreEvent::LockFileReleaseNotFound(_) => {
println!(
"{}Lock does not exist for requested files{}",
LogStyles::WARNING,
anstyle::Reset
);
}
_ => {}
}) as EventCallbackFn)
.with_defaults(),
Expand Down
17 changes: 3 additions & 14 deletions lore-client/src/cli/commands/revision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,6 @@ fn resolve_layer_messages(
}

pub fn handle_revision_commit(globals: LoreGlobalArgs, args: &RevisionCommitArgs) -> u8 {
let dry_run = globals.dry_run();
let mut fragment_stats = FragmentStats::default();
fragment_stats.size_count.resize(STATS_SIZE_BUCKETS, 0);

Expand Down Expand Up @@ -1241,11 +1240,7 @@ pub fn handle_revision_commit(globals: LoreGlobalArgs, args: &RevisionCommitArgs
let callback = output_formatter().unwrap_or(Some(
(Box::new(move |event: &LoreEvent| match event {
LoreEvent::RevisionCommitBegin(_data) => {
if dry_run {
println!("Previewing commit of staged changes");
} else {
println!("Committing staged changes");
}
println!("Committing staged changes");
}
LoreEvent::RevisionCommitProgress(data) => {
let estimate = if data.count.discovery_complete != 0 {
Expand Down Expand Up @@ -1292,8 +1287,7 @@ pub fn handle_revision_commit(globals: LoreGlobalArgs, args: &RevisionCommitArgs
String::new()
};
println!(
"{} {}/{} directories, {}/{} files{} ({} modified, {} deleted)",
if dry_run { "Would commit" } else { "Committed" },
"Committed {}/{} directories, {}/{} files{} ({} modified, {} deleted)",
data.count.directory_count,
data.count.directory_total,
data.count.file_count,
Expand Down Expand Up @@ -1340,13 +1334,8 @@ pub fn handle_revision_commit(globals: LoreGlobalArgs, args: &RevisionCommitArgs
for entry in describe_entry_data.iter() {
entry.print_description(Some(&auth_data));
println!(
"{}{}{}",
"{}Commit succeeded{}",
CommonStyles::SUCCESS,
if dry_run {
"Dry-run commit succeeded"
} else {
"Commit succeeded"
},
anstyle::Reset
);
println!();
Expand Down
Loading
Loading