@david.uhlir/files-scope v1.0.3
Files scope for node.js applications
Basic about
Files scope is util to handle complex work with content of files with mutexes. For example in some cases, you nead to read content, process it somehow, and than save it. During this operation, somebody can change content of this file, that's why you should wait until one opration is done, before starting next one. This is where files scope is helpfull, you can open scope, with defining what will be sources, you will need inside. All other scopes, that will access files same way in same time will need to wait, until scope will be finished.
Usage
This example will try to access file1.json and file2.json, parse them as json, merge its content and write it to file3. On the other hand, second scope will try to write content to file1, so these scopes will never be opened together. Keep in mind, mutex prefix have to be provided with some string, to keep scopes connected together.
await Scope.open('ROOT', {
a: Scope.readAccess('dir/dirA/file1.json'),
b: Scope.readAccess('dir/dirA/file2.json'),
c: Scope.writeAccess('dir/file3.json'),
}, async (dependecies) => {
const contentA = await dependencies.a.read()
const contentB = await dependencies.b.read()
const jsonA = JSON.parse(contentA)
const jsonB = JSON.parse(contentA)
const newContent = {
...jsonA,
...jsonB,
}
await dependecies.c.write(JSON.stringify(newContent))
})
await Scope.open('ROOT', {
a: Scope.writeAccess('dir/dirA/file1.json'),
}, async (dependecies) => {
await dependecies.c.write(JSON.stringify({
hello: 'World from file A',
}))
})
Using dependecies
Dependencies received in first parameter in handler is the same object provided as dependencies when opening scope. FsDependency (created by calling Scope.readAccess
and Scope.writeAccess
) providing few shortcut fuctions, as read/write, unlink, etc... to keep your code shorter. If you need to use some other functions, you can get path by calling dependencies.a.getFullPath()
. We realy recommending to use dependecies access to simple fs oprations, as we can't change behaviour of fs itself, it will not provides you any safety about access type. In case you will try to write with read access only, it will throw error.
Combining with mutexes
It's internaly using @david.uhlir/mutex to handle it, so it will works in cluster too. You can also lock your scopes as usual using SharedMutex.lockSingleAccess
or SharedMutex.lockMultiAccess
. Key of these mutexes in scope will be generated by this pattern prefix/shortest common path
. Shortest common path means, it will find the lowest folder, which is common for all posible paths. If paths is starting on different point, it will be nested as another lock inside of scope.
Performance
As mutexes are using IPC to synchronize scopes, it can affect performance of your app easily - so it's better, if it's posible, to open less scopes with bigger operations, than a lot of small scopes with easy operations. Still IPC is pretty fast, and in case of application in single process, it will use vent emitter, which is even faster.