1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

feat(unstable): add Deno.fsyncSync and fsync (#6411)

This commit is contained in:
Casper Beyer 2020-06-21 21:29:44 +08:00 committed by GitHub
parent f24aab81c9
commit 40866d7cd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 0 deletions

View file

@ -4,6 +4,7 @@
export { umask } from "./ops/fs/umask.ts"; export { umask } from "./ops/fs/umask.ts";
export { linkSync, link } from "./ops/fs/link.ts"; export { linkSync, link } from "./ops/fs/link.ts";
export { fsyncSync, fsync } from "./ops/fs/sync.ts";
export { symlinkSync, symlink } from "./ops/fs/symlink.ts"; export { symlinkSync, symlink } from "./ops/fs/symlink.ts";
export { loadavg, osRelease, hostname } from "./ops/os.ts"; export { loadavg, osRelease, hostname } from "./ops/os.ts";
export { openPlugin } from "./ops/plugins.ts"; export { openPlugin } from "./ops/plugins.ts";

View file

@ -1118,4 +1118,28 @@ declare namespace Deno {
* ``` * ```
*/ */
export function ftruncate(rid: number, len?: number): Promise<void>; export function ftruncate(rid: number, len?: number): Promise<void>;
/** **UNSTABLE**: New API, yet to be vetted.
* Synchronously flushes any pending data and metadata operations of the given file stream to disk.
* ```ts
* const file = Deno.openSync("my_file.txt", { read: true, write: true, create: true });
* Deno.writeSync(file.rid, new TextEncoder().encode("Hello World"));
* Deno.ftruncateSync(file.rid, 1);
* Deno.fsyncSync(file.rid);
* console.log(new TextDecoder().decode(Deno.readFileSync("my_file.txt"))); // H
* ```
*/
export function fsyncSync(rid: number): void;
/** **UNSTABLE**: New API, yet to be vetted.
* Flushes any pending data and metadata operations of the given file stream to disk.
* ```ts
* const file = await Deno.open("my_file.txt", { read: true, write: true, create: true });
* await Deno.write(file.rid, new TextEncoder().encode("Hello World"));
* await Deno.ftruncate(file.rid, 1);
* await Deno.fsync(file.rid);
* console.log(new TextDecoder().decode(await Deno.readFile("my_file.txt"))); // H
* ```
*/
export function fsync(rid: number): Promise<void>;
} }

10
cli/js/ops/fs/sync.ts Normal file
View file

@ -0,0 +1,10 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { sendSync, sendAsync } from "../dispatch_json.ts";
export function fsyncSync(rid: number): void {
sendSync("op_fsync", { rid });
}
export async function fsync(rid: number): Promise<void> {
await sendAsync("op_fsync", { rid });
}

View file

@ -22,6 +22,7 @@ use rand::{thread_rng, Rng};
pub fn init(i: &mut CoreIsolate, s: &State) { pub fn init(i: &mut CoreIsolate, s: &State) {
i.register_op("op_open", s.stateful_json_op2(op_open)); i.register_op("op_open", s.stateful_json_op2(op_open));
i.register_op("op_seek", s.stateful_json_op2(op_seek)); i.register_op("op_seek", s.stateful_json_op2(op_seek));
i.register_op("op_fsync", s.stateful_json_op2(op_fsync));
i.register_op("op_umask", s.stateful_json_op(op_umask)); i.register_op("op_umask", s.stateful_json_op(op_umask));
i.register_op("op_chdir", s.stateful_json_op(op_chdir)); i.register_op("op_chdir", s.stateful_json_op(op_chdir));
i.register_op("op_mkdir", s.stateful_json_op(op_mkdir)); i.register_op("op_mkdir", s.stateful_json_op(op_mkdir));
@ -205,6 +206,50 @@ fn op_seek(
} }
} }
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct FsyncArgs {
promise_id: Option<u64>,
rid: i32,
}
fn op_fsync(
isolate_state: &mut CoreIsolateState,
state: &State,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
state.check_unstable("Deno.fsync");
let args: FsyncArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let resource_table = isolate_state.resource_table.clone();
let is_sync = args.promise_id.is_none();
if is_sync {
let mut resource_table = resource_table.borrow_mut();
std_file_resource(&mut resource_table, rid, |r| match r {
Ok(std_file) => std_file.sync_all().map_err(OpError::from),
Err(_) => Err(OpError::type_error(
"cannot sync this type of resource".to_string(),
)),
})?;
Ok(JsonOp::Sync(json!({})))
} else {
let fut = async move {
let mut resource_table = resource_table.borrow_mut();
std_file_resource(&mut resource_table, rid, |r| match r {
Ok(std_file) => std_file.sync_all().map_err(OpError::from),
Err(_) => Err(OpError::type_error(
"cannot sync this type of resource".to_string(),
)),
})?;
Ok(json!({}))
};
Ok(JsonOp::Async(fut.boxed_local()))
}
}
#[derive(Deserialize)] #[derive(Deserialize)]
struct UmaskArgs { struct UmaskArgs {
mask: Option<u32>, mask: Option<u32>,

View file

@ -0,0 +1,38 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { read: true, write: true } },
function fsyncSyncSuccess(): void {
const filename = Deno.makeTempDirSync() + "/test_fsyncSync.txt";
const file = Deno.openSync(filename, {
read: true,
write: true,
create: true,
});
const size = 64;
Deno.ftruncateSync(file.rid, size);
Deno.fsyncSync(file.rid);
assertEquals(Deno.statSync(filename).size, size);
Deno.close(file.rid);
Deno.removeSync(filename);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function fsyncSuccess(): Promise<void> {
const filename = (await Deno.makeTempDir()) + "/test_fsync.txt";
const file = await Deno.open(filename, {
read: true,
write: true,
create: true,
});
const size = 64;
await Deno.ftruncate(file.rid, size);
await Deno.fsync(file.rid);
assertEquals((await Deno.stat(filename)).size, size);
Deno.close(file.rid);
await Deno.remove(filename);
}
);

View file

@ -59,6 +59,7 @@ import "./streams_piping_test.ts";
import "./streams_transform_test.ts"; import "./streams_transform_test.ts";
import "./streams_writable_test.ts"; import "./streams_writable_test.ts";
import "./symlink_test.ts"; import "./symlink_test.ts";
import "./sync_test.ts";
import "./text_encoding_test.ts"; import "./text_encoding_test.ts";
import "./testing_test.ts"; import "./testing_test.ts";
import "./timers_test.ts"; import "./timers_test.ts";