Skip to content

Commit

Permalink
Merge pull request #212 from rage/huh
Browse files Browse the repository at this point in the history
Fix file locking
  • Loading branch information
Heliozoa authored Oct 29, 2024
2 parents d5fb905 + 275da72 commit b527659
Show file tree
Hide file tree
Showing 22 changed files with 944 additions and 620 deletions.
334 changes: 171 additions & 163 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ authors = [
edition = "2021"
license = "MIT OR Apache-2.0"
rust-version = "1.70.0"
version = "0.36.3"
version = "0.36.4"

[workspace.dependencies]
mooc-langs-api = { git = "https://github.com/rage/secret-project-331.git", rev = "9fb5f894c72932e77dafa6d0f00df7a8abdfa84c" }
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings/tmc-langs-node/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde::de::{
pub fn from_value<'j, C, T>(cx: &mut C, value: Handle<'j, JsValue>) -> LibResult<T>
where
C: Context<'j>,
T: DeserializeOwned + ?Sized,
T: DeserializeOwned,
{
let mut deserializer: Deserializer<C> = Deserializer::new(cx, value);
let t = T::deserialize(&mut deserializer)?;
Expand Down
4 changes: 2 additions & 2 deletions crates/bindings/tmc-langs-node/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ macro_rules! lock {
( $cx: ident, $( $path: expr ),+ ) => {
$(
let path_buf: PathBuf = (&$path).into();
let mut fl = $crate::file_util::FileLock::new(path_buf).map_err(|e| $crate::helpers::convert_err(&mut $cx, e))?;
let _lock = fl.lock().map_err(|e| $crate::helpers::convert_err(&mut $cx, e))?;
let mut lock = $crate::file_util::Lock::dir(path_buf, $crate::file_util::LockOptions::Write).map_err(|e| $crate::helpers::convert_err(&mut $cx, e))?;
let _guard = lock.lock().map_err(|e| $crate::helpers::convert_err(&mut $cx, e))?;
)*
};
}
Expand Down
11 changes: 7 additions & 4 deletions crates/bindings/tmc-langs-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,14 @@ fn extract_project(mut cx: FunctionContext) -> JsResult<JsValue> {
compression: Compression
);

let mut archive =
file_util::open_file_locked(archive_path).map_err(|e| convert_err(&mut cx, e))?;
let mut guard = archive.write().expect("failed to lock file");
let mut archive_lock = file_util::Lock::file(archive_path, file_util::LockOptions::Read)
.map_err(|e| convert_err(&mut cx, e))?;
let mut archive_guard = archive_lock.lock().map_err(|e| convert_err(&mut cx, e))?;
let mut data = vec![];
guard.read_to_end(&mut data).expect("failed to read data");
archive_guard
.get_file_mut()
.read_to_end(&mut data)
.expect("failed to read data");

let res =
tmc_langs::extract_project(Cursor::new(data), &output_path, compression, false, false);
Expand Down
276 changes: 222 additions & 54 deletions crates/bindings/tmc-langs-node/ts/generated.d.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions crates/plugins/make/src/check_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::collections::HashMap;
use tmc_langs_framework::{RunResult, RunStatus, TestResult};

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct CheckLog {
#[allow(dead_code)]
pub datetime: String,
Expand Down Expand Up @@ -52,6 +53,7 @@ impl CheckLog {
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct TestSuite {
#[allow(dead_code)]
pub title: String,
Expand All @@ -60,6 +62,7 @@ pub struct TestSuite {
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct Test {
pub result: String,
#[allow(dead_code)]
Expand Down
2 changes: 2 additions & 0 deletions crates/plugins/make/src/valgrind_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::{
use tmc_langs_util::{file_util, FileError};

#[derive(Debug)]
#[allow(dead_code)]
pub struct ValgrindLog {
#[allow(dead_code)]
pub header: (String, Vec<String>),
Expand Down Expand Up @@ -80,6 +81,7 @@ impl ValgrindLog {
}

#[derive(Debug)]
#[allow(dead_code)]
pub struct ValgrindResult {
#[allow(dead_code)]
pub pid: String,
Expand Down
119 changes: 80 additions & 39 deletions crates/tmc-langs-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ use serde_json::Value;
use std::{
collections::HashMap,
env,
fs::File,
io::{self, BufReader, Cursor, Read},
ops::Deref,
path::{Path, PathBuf},
};
use tmc_langs::{
file_util,
mooc::MoocClient,
tmc::{request::FeedbackAnswer, TestMyCodeClient, TestMyCodeClientError},
CommandError, Compression, Credentials, DownloadOrUpdateCourseExercisesResult, DownloadResult,
Language, StyleValidationResult, TmcConfig, UpdatedExercise,
};
use tmc_langs_util::deserialize;
use tmc_langs_util::{
deserialize,
file_util::{self, Lock, LockOptions},
};

pub enum ParsingResult {
Ok(Cli),
Expand Down Expand Up @@ -180,14 +180,18 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
locale: Locale(locale),
output_path,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let check_result =
run_checkstyle_write_results(&exercise_path, output_path.as_deref(), locale)?;
CliOutput::finished_with_data("ran checkstyle", check_result.map(DataKind::Validation))
}

Command::Clean { exercise_path } => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Write)?;
let _guard = lock.lock()?;

tmc_langs::clean(&exercise_path)?;
CliOutput::finished(format!("cleaned exercise at {}", exercise_path.display()))
}
Expand All @@ -199,7 +203,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
deterministic,
naive,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let hash = tmc_langs::compress_project_to(
&exercise_path,
&output_path,
Expand Down Expand Up @@ -227,11 +233,11 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
compression,
naive,
} => {
let mut archive = file_util::open_file_locked(&archive_path)?;
let mut guard = archive.write()?;
let mut archive_lock = Lock::file(&archive_path, LockOptions::Read)?;
let mut archive_guard = archive_lock.lock()?;

let mut data = vec![];
guard.read_to_end(&mut data)?;
archive_guard.get_file_mut().read_to_end(&mut data)?;

tmc_langs::extract_project(Cursor::new(data), &output_path, compression, true, naive)?;

Expand All @@ -243,7 +249,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
}

Command::FastAvailablePoints { exercise_path } => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let points = tmc_langs::get_available_points(&exercise_path)?;
CliOutput::finished_with_data(
format!("found {} available points", points.len()),
Expand All @@ -255,7 +263,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
search_path,
output_path,
} => {
file_util::lock!(search_path);
let mut lock = Lock::dir(&search_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let exercises =
tmc_langs::find_exercise_directories(&search_path).with_context(|| {
format!(
Expand All @@ -276,7 +286,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
exercise_path,
output_path,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let config = tmc_langs::get_exercise_packaging_configuration(&exercise_path)
.with_context(|| {
format!(
Expand Down Expand Up @@ -313,7 +325,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
exercise_path,
output_path,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

tmc_langs::prepare_solution(&exercise_path, &output_path).with_context(|| {
format!(
"Failed to prepare solutions for exercise at {}",
Expand All @@ -331,7 +345,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
exercise_path,
output_path,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

tmc_langs::prepare_stub(&exercise_path, &output_path).with_context(|| {
format!(
"Failed to prepare stubs for exercise at {}",
Expand All @@ -357,6 +373,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
tmc_param,
no_archive_prefix,
} => {
let mut clone_lock = Lock::dir(&clone_path, file_util::LockOptions::Read)?;
let _clone_guard = clone_lock.lock()?;

// will contain for each key all the values with that key in a list
let mut tmc_params_grouped = HashMap::new();
for value in &tmc_param {
Expand Down Expand Up @@ -439,7 +458,8 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
output_path,
wait_for_secret,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let secret = if wait_for_secret {
let mut s = String::new();
Expand Down Expand Up @@ -496,7 +516,8 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
exercise_path,
output_path,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let exercise_name = exercise_path.file_name().with_context(|| {
format!(
Expand Down Expand Up @@ -584,6 +605,9 @@ fn run_tmc_inner(
exercise_id,
target,
} => {
let mut output_lock = Lock::dir(&target, file_util::LockOptions::WriteTruncate)?;
let _output_guard = output_lock.lock()?;

client
.download_model_solution(exercise_id, &target)
.context("Failed to download model solution")?;
Expand All @@ -596,6 +620,9 @@ fn run_tmc_inner(
exercise_id,
output_path,
} => {
let mut output_lock = Lock::dir(&output_path, file_util::LockOptions::Write)?;
let _output_guard = output_lock.lock()?;

tmc_langs::download_old_submission(
client,
exercise_id,
Expand Down Expand Up @@ -837,7 +864,9 @@ fn run_tmc_inner(
paste_message,
submission_path,
} => {
file_util::lock!(submission_path);
let mut lock = Lock::dir(&submission_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let locale = locale.map(|l| l.0);
let new_submission = client
.paste(exercise_id, &submission_path, paste_message, locale)
Expand All @@ -851,7 +880,9 @@ fn run_tmc_inner(
message_for_reviewer,
submission_path,
} => {
file_util::lock!(submission_path);
let mut lock = Lock::dir(&submission_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let new_submission = client
.request_code_review(
exercise_id,
Expand All @@ -871,7 +902,9 @@ fn run_tmc_inner(
save_old_state,
exercise_path,
} => {
file_util::lock!(exercise_path);
let mut lock = Lock::dir(&exercise_path, LockOptions::Write)?;
let _guard = lock.lock()?;

if save_old_state {
// submit current state
client.submit(exercise_id, &exercise_path, None)?;
Expand Down Expand Up @@ -923,7 +956,9 @@ fn run_tmc_inner(
submission_path,
exercise_id,
} => {
file_util::lock!(submission_path);
let mut lock = Lock::dir(&submission_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let locale = locale.map(|l| l.0);
let new_submission = client
.submit(exercise_id, &submission_path, locale)
Expand Down Expand Up @@ -1040,7 +1075,9 @@ fn run_mooc_inner(mooc: Mooc, client: &mut MoocClient) -> Result<CliOutput> {
task_id,
submission_path,
} => {
file_util::lock!(submission_path);
let mut lock = Lock::dir(&submission_path, LockOptions::Read)?;
let _guard = lock.lock()?;

let temp = file_util::named_temp_file()?;
tmc_langs::compress_project_to(
&submission_path,
Expand Down Expand Up @@ -1128,27 +1165,28 @@ fn write_result_to_file_as_json<T: Serialize>(
pretty: bool,
secret: Option<String>,
) -> Result<()> {
let mut output_file = file_util::create_file_locked(output_path).with_context(|| {
format!(
"Failed to create results JSON file at {}",
output_path.display()
)
})?;
let guard = output_file.write()?;
let mut output_lock =
Lock::file(output_path, LockOptions::WriteTruncate).with_context(|| {
format!(
"Failed to create results JSON file at {}",
output_path.display()
)
})?;
let mut output_guard = output_lock.lock()?;

if let Some(secret) = secret {
let token = tmc_langs::sign_with_jwt(result, secret.as_bytes())?;
file_util::write_to_writer(token, guard.deref())
file_util::write_to_writer(token, output_guard.get_file_mut())
.with_context(|| format!("Failed to write result to {}", output_path.display()))?;
} else if pretty {
serde_json::to_writer_pretty(guard.deref(), result).with_context(|| {
serde_json::to_writer_pretty(output_guard.get_file_mut(), result).with_context(|| {
format!(
"Failed to write result as JSON to {}",
output_path.display()
)
})?;
} else {
serde_json::to_writer(guard.deref(), result).with_context(|| {
serde_json::to_writer(output_guard.get_file_mut(), result).with_context(|| {
format!(
"Failed to write result as JSON to {}",
output_path.display()
Expand All @@ -1172,13 +1210,16 @@ fn run_checkstyle_write_results(
)
})?;
if let Some(output_path) = output_path {
let output_file = File::create(output_path).with_context(|| {
format!(
"Failed to create code style check results file at {}",
output_path.display()
)
})?;
serde_json::to_writer(output_file, &check_result).with_context(|| {
let mut output_lock =
Lock::file(output_path, LockOptions::WriteTruncate).with_context(|| {
format!(
"Failed to create code style check results file at {}",
output_path.display()
)
})?;
let mut output_guard = output_lock.lock()?;

serde_json::to_writer(output_guard.get_file_mut(), &check_result).with_context(|| {
format!(
"Failed to write code style check results as JSON to {}",
output_path.display()
Expand Down
2 changes: 1 addition & 1 deletion crates/tmc-langs-framework/src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ fn walk_dir_for_compression(
.sort_by_file_name()
.into_iter()
// filter windows lock files
.filter_entry(|e| e.file_name() != ".tmc.lock")
.filter_entry(|e| e.file_name() != file_util::LOCK_FILE_NAME)
{
let entry = entry?;
let stripped = entry
Expand Down
Loading

0 comments on commit b527659

Please sign in to comment.