Can we use JavaScript FileSystemAPI from a Webworker? - javascript

Can we use the JavaScript FileSystemAPI from a webworker?
https://developer.mozilla.org/en-US/docs/Web/API/FileSystem
In their documentation they have not mentioned anything but while using it its throwing window not defined.
Thanks!

Not really...
There used to be a self.webkitRequestFileSystemSync() method accessible in Worker scopes, but it's been deprecated. And the FileSystem object you'd get from a drop event can't be serialized, and thus can't be posted to Worker from the main thread.
However, I suspect you don't really want to work with the FileSystem API, which is not really useful in web contexts, but instead you may want to prefer the File System Access API, which gives your page access to the user's file system (even though it's still only available in Chromium based browsers).
But to use this API from a Web Worker is not simple either.
To make the request to the File System Access API, we need to be handling an user-gesture. Web Workers don't have access to the UI and thus they don't either have access to UI events (yet).
So we must make the request from the UI thread.
However, contrary to FileSystem objects, FileSystemHandles are serializable and can be posted though postMessage(), so once you get the handle, you can post it to your worker and do your work from there.
In UI thread
btn.onclick = async (evt) => {
const dirHandle = await showDirectoryPicker();
worker.postMessage( dirHandle );
};
Then in the Worker thread you can receive that handle in the MesageEvent.data, and work with it as you'd do from the main thread.
Here is a live demo, and its source.

Webworkers global object name is global, not window.
And there is no FileSystem API

Related

How to share context between worker threads

I would like to create a worker thread in a node.js app and pass the current context to the new thread, so I would be able to access my variables and functions within the new thread, Is there is a library to support that? And if not can I a least pass an anonymous function between them?
There is no way to share a context with a worker thread. This isn't "an ideology of the Node.js team", instead it's a limitation of the JavaScript language, which doesn't allow concurrency (such as concurrent access to objects from a worker thread).
The one exception is that you can share numerical data between multiple threads by using a SharedArrayBuffer.
Aside from that, the way to send data to or receive it from a worker thread is to use postMessage. See also Node's full worker threads documentation.
For completeness: there is an early-stage proposal to add a new kind of cross-thread-shareable object to JavaScript. As with all early-stage proposals, there's no guarantee that it'll be finalized at all or how long that might take, but it does indicate that there's some interest in this space.

How to stop js web worker from within?

TLDR: What is an alternative to WorkerGlobalScope.close() which is not deprecated
I want to close/stop/terminate a Javascript web worker from the inside, after its job is done, since there is a setInterval() which keeps being active even after the main work is done.
Reading this SO question (JavaScript Web Worker - close() vs terminate()), it seems like self.close() is what I'm searching for. But apparently this is deprecated (stated here) without any mention of alternatives.
The only alternative I have come up with so far would be to send a message to the main thread which then invokes a worker.terminate() call, but that seems like overkill since I would then need to check every message that comes this way for a termination request.
Am I missing something? What should I use?
This notice is misleading .close() is not deprecated at all.
What happens here is that in the specs WorkerGlobalScope is an interface that is used by different worker types (DedicatedWorkers, ServiceWorkers, SharedWorkers, and maybe other Worklets in other specs).
All these types don't have a .close method (e.g ServiceWorkers don't), and thus this method has been moved to each specific types of worker global scope's definition.
For instance you can see that for the DedicatedWorkerGlobalScope, it's still here, and isn't scheduled to be deprecated any time soon.
And it's actually also there in MDN.

is it not good to use cacheStorage outside serviceWorker ?why?

In the https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage page, it tell us that:
The CacheStorage interface represents the storage for Cache objects. It provides a master directory of all the named caches that a ServiceWorker, other type of worker or window scope can access (you don't have to use it with service workers, even though that is the spec that defines it) and maintains a mapping of string names to corresponding Cache objects.
so, i want to know.Is it better to use cacheStorage in ServiceWorker than in Window scope? why?
As nobody answer that, i want to share what i think.
In my opinion, there are several advantages.
First of all, serviceWorker is handled by another thread, which make it more efficient.
The next one, serviceWorker can simply add to old website without changing code, while you have to rewrite the ajax code etc, when you plan to use it in window scope.
The last but not least, you can run this when your page has been shut down.For example, you can put sth into cache when you got the push.
However, it still make me confused. Why the browser allow the window scope to get the permission.Is it a convenient way for us to just write in the main thread? Or, that will bring us some security risk, because when our page has been xss, that hacker can get access to cache?
Why the browser allow the window scope to get the permission?
Service Workers do not have access to DOM elements.
So if I want to precache some urls that are found on the current page it is much easier to do from the window scope than from the service worker.

Create Parse sessions using Chrome storage not localstorage

I am building a Chrome Extension that requires Parse User sessions. Because localstorage is domain specific, I need to use chrome.storage so it can be accessed while on any site.
The current Parse Javascript SDK uses localstorage to store a user object and create sessions. How can I switch this so Parse uses chrome.storage?
Here's my current thinking atm:
on login
store sessiontoken in chrome.storage
Then when I visit a site:
if chrome.storage.sessiontoken
create parse session with chrome.storage.sessiontoken
I was wondering if anyone's come across a simpler way?
I would love to just do:
window.localstorage = chrome.storage
But imagine that will lead to problems. Anyone solved this?
Basically you need to write your own storage controller(with chrome api ofcourse) and then let parse to use it.
Since this thread is newer, here's the detailed solution:
By default, Parse javascript SDK use window.localStorage api to store data.
However, in Chrome app, localStorage is replaced by chrome.storage api, which offers better non-blocking storage solution.
Parse SDK is actually prepared for different type of storage(both sync and async), and let your set your own custom storage controller
As #andrewimm (from github) pointed out, you need to call Parse.CoreManager.setStorageController(YOUR_STORAGE_CONTROLLER) before you call Parse.initialize.
An example custom storage controlled is Parse React Native storage controller( which is also async), which could be found at: https://github.com/ParsePlatform/Parse-SDK-JS/blob/master/src/StorageController.react-native.js
A Sync controller object need to set its async property to 0, and have
getItem, setItem,removeItem, and clear function implemented
An Async controller object need to set async property to 1, and have getItemAsync, setItemAsync,removeItemAsync,clearimplemented
All you need to do is to follow the react native example and build yourself your own storage controller (with chrome storage api), and let Parse to use it instead of use localStorage
Original Github issue thread:https://github.com/ParsePlatform/Parse-SDK-JS/issues/72
You can't directly substitute localstorage with chrome.storage, because one is synchronous and one is not, not to mention different API methods.
You cannot anyhow wrap it in a way that it becomes fully synchronous. However, here are some ideas:
Work with storage in the background script. There, the domain for localStorage is fixed.
Make a local synchronous copy of the storage; something like
var localData = {};
chrome.storage.local.get(null, function(data) {
localData = data;
doSomethingElse(); // Mind that this is async
})
However, saving this cache is going to be a problem. You have to intercept writes and commit it to chrome.storage and likewise update it on onChanged event - but all that will be asynchronous, which may not work.
In short, if a library uses localStorage internally, you won't be able to replace it adequately without rewriting the library or keeping it to background.

multi-core programming using JavaScript?

So I have this seriously recursive function that I would like to use with my code. The issue is it doesn't really take advantage of dual core machines because js is single threaded. I have tried using webworkers but don't really know much about multicore programming. Would someone point me to some material that could explain how it is done. I googled to find this sample link but its not really much help without documentation! =/
I would be glad if someone could show me how this could be done without webworkers though! That would be just awesome! =)
I came across this link on whatwg. This is really weird because it explains how to use multicore programming in webworkers etc, but on executing on my chrome browser it throws errors. Same goes with other browsers.
Error: 9Uncaught ReferenceError: Worker is not defined in worker.js
UPDATE (2018-06-21): For people coming here in search of multi-core programming in JavaScript, not necessarily browser JavaScript (for that, the answer still applies as-is): Node.js now supports multi-threading behind a feature flag (--experimental-workers): release info, relevant issue.
Writing this off the top of my head, no guarantees for source code. Please go easy on me.
As far as I know, you cannot really program in threads with JavaScript. Webworkers are a form of multi-programming; yet JavaScript is by its nature single-threaded (based on an event loop).
A webworker is seperate thread of execution in the sense that it doesn't share anything with the script that started it; there is no reference to the script's global object (typically called "window" in the browser), and no reference to any of your main script's variables other than data you send to the thread.
Think as the web worker as a little "server" that gets asked a question and provides an answer. You can only send strings to that server, and it can only parse the string and send back what it has computed.
// in the main script, one starts a worker by passing the file name of the
// script containing the worker to the constructor.
var w = new Worker("myworker.js");
// you want to react to the "message" event, if your worker wants to inform
// you of a result. The function typically gets the event as an argument.
w.addEventListener("message",
function (evt) {
// process evt.data, which is the message from the
// worker thread
alert("The answer from the worker is " + evt.data);
});
You can then send a message (a String) to this thread using its postMessage()-Method:
w.postMessage("Hello, this is my message!");
A sample worker script (an "echo" server) can be:
// this is another script file, like "myworker.js"
self.addEventListener("message",
function (evt) {
var data = JSON.parse(evt.data);
/* as an echo server, we send this right back */
self.postMessage(JSON.stringify(data))
})
whatever you post to that thread will be decoded, re-encoded, and sent back. of course you can do whatever processing you would want to do in between. That worker will stay active; you can call terminate() on it (in your main script; that'd be w.terminate()) to end it or calling self.close() in your worker.
To summarize: what you can do is you zip up your function parameters into a JSON string which gets sent using postMessage, decoded, and processed "on the other side" (in the worker). The computation result gets sent back to your "main" script.
To explain why this is not easier: More interaction is not really possible, and that limitation is intentional. Because shared resources (an object visible to both the worker and the main script) would be subject to two threads interfering with them at the same time, you would need to manage access (i.e., locking) to that resource in order to prevent race conditions.
The message-passing, shared-nothing approach is not that well-known mainly because most other programming languages (C and Java for example) use threads that operate on the same address space (while others, like Erlang, for instance, don't). Consider this:
It is really hard to code a larger project with mutexes (a mutual exclusion mechanism) because of the associated deadlock/race condition complexities. This is stuff that can make grown men cry!
It is really easy in comparison to do message-passing, shared-nothing semantics. The code is isolated; you know exactly what goes into your worker and what comes out of your worker. Deadlocks and race conditions are impossible to achieve!
Just try it out; it is capable of doing interesting things, probably all you want. Bear in mind that it is still implementation defined whether it takes advantage of multicore as far as I know.
NB. I just got informed that at least some implementations will handle JSON encoding of messages for you.
So, to give an answer to your question (it's all above; tl;dr version): No, you cannot do this without web workers. But there is nothing really wrong about web workers aside from browser support, as is the case with HTML5 in general.
As far as I remember this is only possible with the new HTML5 standard. The keyword is "Web-Worker"
See also:
HTML5: JavaScript Web Workers
JavaScript Threading With HTML5 Web Workers
Web workers are the answer to the client side. For NodeJS there are many approaches. Most popular - spawn several processes with pm2 or similar tool. Run single process and spawn/fork child processes. You can google around these and will find a lot of samples and tactics.
Web workers are already well supported by all browsers. https://caniuse.com/#feat=webworkers
API & samples: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

Categories