aligned-block-file
Advanced tools
Comparing version 1.2.1 to 1.2.2
58
file.js
@@ -5,2 +5,3 @@ var fs = require('fs') | ||
var path = require('path') | ||
const ReadWriteLock = require('rwlock'); | ||
@@ -17,46 +18,12 @@ module.exports = function (file, block_size, flags) { | ||
// | ||
// It's possible (likely?) that Node.js handles this deeper in the stack, | ||
// especially since it seems to use `pread()` and `pwrite()`. Removing this | ||
// queue system doesn't break any tests, but I'm not confident enough to | ||
// remove it until we confirm that Node.js handles concurrent positional | ||
// reads and writes without either of the concurrency problems above. | ||
// It's likely that Node.js is handling this deeper in the stack with libuv | ||
// operations like `pread()` and `pwrite()`, but they haven't explicitly | ||
// committed to this behavior: | ||
// | ||
// This async queue system is made of four parts: | ||
// https://github.com/nodejs/node/issues/18634#issuecomment-363981993 | ||
// | ||
// - `busy`: A boolean semaphore for positional reads and writes to `fd`. | ||
// - `queue`: An array of functions that want to access `fd`. | ||
// - `todo(fn)`: Used to run or queue `fn`, which must call `release()`. | ||
// - `release()`: Called by functions passed to `todo()` after using `fd`. | ||
// If `busy === true` then another function is accessing `fd`. | ||
// If `busy === false` then you're all clear to access. | ||
let busy = false | ||
// Each item should be a function that accepts no arguments. | ||
// `release()` should be called as soon as `fd` access is complete. | ||
// Items are processed FIFO even though `Array.shift()` is slow | ||
const queue = [] | ||
// A function passed to `todo` will have exclusive access to positional | ||
// operations on `fd`, although append operations may still occur. | ||
// > This is not safe on all platforms, no. | ||
// | ||
// Any function passed to `todo()` absolutely *must* call `release()` when | ||
// finished using `fd`, often as the first line in the `fs.foo()` callback. | ||
const todo = (fn) => { | ||
if (busy === true) { | ||
queue.push(fn) | ||
} else { | ||
busy = true | ||
fn() | ||
} | ||
} | ||
const release = () => { | ||
if (queue.length === 0) { | ||
busy = false | ||
} else { | ||
queue.shift()() | ||
} | ||
} | ||
const lock = new ReadWriteLock(); | ||
@@ -85,3 +52,3 @@ mkdirp(path.dirname(file), function () { | ||
offset.once(function (_offset) { | ||
function onReady () { | ||
lock.readLock((release) => { | ||
var max = ~~(_offset / block_size) | ||
@@ -110,4 +77,3 @@ if(i > max) | ||
}) | ||
} | ||
todo(onReady) | ||
}) | ||
}) | ||
@@ -148,3 +114,3 @@ }, | ||
function onReady () { | ||
lock.writeLock((release) => { | ||
fs.write(fd, buf, 0, buf.length, pos, (err, written) => { | ||
@@ -158,5 +124,3 @@ release() | ||
}) | ||
} | ||
todo(onReady) | ||
}) | ||
}) | ||
@@ -163,0 +127,0 @@ }, |
{ | ||
"name": "aligned-block-file", | ||
"description": "", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"homepage": "https://github.com/flumedb/aligned-block-file", | ||
@@ -15,2 +15,3 @@ "repository": { | ||
"obv": "^0.0.1", | ||
"rwlock": "^5.0.0", | ||
"uint48be": "^2.0.1" | ||
@@ -17,0 +18,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29073
6
802
+ Addedrwlock@^5.0.0
+ Addedrwlock@5.0.0(transitive)