I am currently on a big Javascript project with a lot of libraries.
I would like to have some part of this project to run on separate thread. There is already something inJavascript doing that : the web workers.
Though, the web workers can't access the window object, and a lot of the libraries use it. Is there a way to automatically change the call to the window object (in the libraries used for the web workers), into a message sent to the parent thread ?
Then, the parent thread would perform the action that the worker want and send back the result to the worker.
Is it possible to do that ? And id yes, do you have any idea how ?
Thank you !
I'm afraid there's no real solution to this. What you'd probably want is a special object in your worker, which, at every property access, passes the execution to the dispatching thread - which handles the request using the original window object.
To do this, you would need some sort of catch-all accessor method which would run whenever a property is referenced. Sadly, there's no such thing in Javascript, see this detailed discussion (especially T.J. Crowder's answer): Is it possible to implement dynamic getters/setters in JavaScript?
ECMAScript 6 introduces a new mechanism called Proxy (currently supported in FF and IE12 (go figure!)), which would enable you to do these dynamic property lookups, technically - but I feel there's a more fundamental problem with your idea: you're aiming to turn a local call into a message across the boundaries of single threaded environments.
Message passing from and to the worker threads must be asynchronous (as a javascript "thread" cannot be interrupted until it yields), which would mean that even if you do manage to set up a proxy like that, it'd be effectively turning a usually synchronous operation (ie. a property access) into an asynchronous one, which is a pretty big issue, especially if you're looking for a drop-in replacement in order to use some existing libraries.
I have a node server for loading certain scripts that can be written by anyone. I understand that when I fire up my Node server, modules load for the first time in the global scope. When one requests a page, it gets loaded by the "start server" callback; and I can use all the already loaded modules per request. But I haven't encountered a script where global variables get changed during request time and affects every single other instance in the process (maybe there is).
My question is, how safe is it, in terms of server crashing, to alter the global data? Also, suppose that that I have written a proper locking mechanism that will "pause" the server for all instances for a very short amount of time until the proper data is loaded.
Node.js is single threaded. So it's impossible for two separate requests to alter a global variable simultaneously. So in theory, it's safe.
However, if you're doing stuff like keep user A's data temporarily in a variable and then when user A later submits another request use that variable be aware that user B may make a request in between potentially altering user A's data.
For such cases keeping global values in arrays or objects is one way of separating user data. Another strategy is to use a closure which is a common practice in callback-intensive or event/promise oriented libraries such as socket.io.
When it comes to multithreading or multiprocessing, message passing style API like node's built-in cluster module has the same guarantees of not clobbering globals since each process have its own global. There are several multithreading modules that's implemented similarly - one node instance per thread. However, shared memory style APIs can't make such guarantees since each thread is now a real OS thread which may preempt each other and clobber each others memory. So if you ever decide to try out one of the multithreading modules, be aware of this issue.
It is possible to implement fake shared memory using message passing though - sort of like how we do it with ajax or socket.io. So I'd personally avoid shared memory style multithreading unless I really, really need to cooperatively work on a very large dataset that would bog down message passing architectures.
Then again, remember, the web is a giant message passing architecture with the messages being HTML and XML and json. So message passing scales to Google size.
In my previous question:
Securing javascript game timing
... it became clear that client-side timing in a Javascript/Canvas game simply won't be secure. I know the mantra about not trusting the client - that is what is causing my struggle in the first place. :-)
So, if I do move all timing to the server and just deal with it, here is a follow-up question. The game obviously needs to be completed before submitting it. As the game puzzle is all Javascript, this introduces the problem of manipulating the client-side code to fake the completion of the game.
I've created the game JS code in a separate class file. If I instantiate the game as such:
var game;
$document.ready(function(){
game = new Game();
});
... then, I can access the 'game' object and all of its methods and variables via the console.
However, if I do:
$document.ready(function(){
var game = new Game();
});
... then I cannot access the 'game' object through the console. This seems to help, but is there something I don't know - can this object still be accessed in some way I don't know about or is making it a private var in that function a little more secure?
Thanks!
Note: there are many other security considerations and attack vectors in such a system. This answer just seeks to answer the specific question that was asked here.
It depends on the browser and what its devtools provide. Most browsers' devtools provide functionality to:
pause execution of JavaScript at any point in time and use a debugger interface.
variables that are in-scope at the current point of execution where the debugger is paused can usually be accessed via devtools in various ways. Inparticular, via console, where anything one can do with that variable in the console is fair game: query its fields, call its methods, etc. If the variable binding isn't const, one can even reassign the variable to a new user-created instance of the object.
navigate JS files and set breakpoints in them.
this is a vector to the above bullet point.
you can make this less attractive by using JS minification (ie. obfuscation), but that's not going to stop someone who's determined.
String literals don't get minified and can usually help a lot in navigating and understanding minified code.
inspect event listeners on HTML elements and set breakpoints on them.
If a variable has a reference bound to it in a function closure that is known to be an event listener of a certain HTML element, or reachable (execution-wise) by such an event listener, this can be another vector to the first bullet point. This can be very common in web games. Just a keyboard event listener usually is an entry-point to reach functions that reference important game objects.
There are even tools to record the JS heap memory. It's a lot of data to sift through, but it's basically everything on the JS heap (readonly).
Given those browser features (and the fact that a user can use any browser they wish), it's impossible to "safeguard" anything 100% on the client-side. It's a losing battle. If you want to play it like a game, you can do your best.
Look into Object.freeze and friends.
freeze or seal anything that can be frozen or sealed, including class prototypes
make variables which can be const const
use assertions to assert in critical parts of the logic that the program state is consistent and try to detect tampering.
Don't care too much about the console. Yes, if there are global objects whose method can easily be fired to "win" the game, it's a nice possibility to cheat, but it can easily prevented as you demonstrated.
So, the hacker would just listen (look at the network pane) which requests are made to your server and fire them manually. If they were just some simple urls like /action=start and /action=end, he could very easily fire them manually without any timing. So you will need to prevent that (although you never can really make it safe), e.g. by adding additional credential tokens. Or you could embed some "secret"(s) into the game code, which are revealed during the gameplay, and need to be sent to the server to prove the rightfulness. Of course they could be read out of your code, but you have to make it too complicated for the hacker. It's a bit like security by obscurity…
In case you don't know what I'm talking about, please read John Resig - How JavaScript Timers Work and Is JavaScript guaranteed to be single-threaded?
There are several triggers that enqueue tasks in the JS engines' execution FiFo. This is not part of any standard, so I'm trying to find an exhausive list of those triggers. (I guess it all boils down to internal event handlers, like script load events or timer events, but I'd rather ignore the engine's internals and look at things from the user's point of view.)
So far I have identified
<script> elements in the initial document (including the ones added by document.write)*
<script> elements inserted by JS at runtime*
Event handlers
-- these include a wide variety of cases, such as user interaction, Error events, Web Worker messages or Ajax callbacks ...
window.setTimeout
window.setInterval
*) only in Browser/DOM environments
Any more? Any differences between JS engines?
"JavaScript" as a language name should not really be used it is too broad.
ECMAScript is what you are referring to. You can find information on ECMAScript at http://www.ecmascript.org/
The language standard is called ECMA-262 with the 5.1 Edition supported by most browsers.
setTimeout, setInterval, DOM events, and more are not part of the language. These are provided by the host environment as host objects. Writing ECMAScript for a wide range of host environment should take special care when using host objects.
ECMAScript code is executed within an execution context. This takes the form of a stack and will hold the state of the current execution context at the top.
There are 3 ways to push an execution context. Global code, eval, and function. This is the only way to start code. Host environments will use these methods to execute code.
The host environment can supply a call stack. This is used to stack function calls generated by host objects which may run in independent threads. Typically an event such as setTimeout will add a function to the call stack. The host environment will then wait until the execution context stack is empty then pop the function from the call stack, create a new execution context, execute the code until completed. It will repeat this until the call stack is empty.
Attempting to build a comprehensive list of host object execution context managers is futile.
To answer the questions.
Any more?
Yes there are many more. This is beyond the scope of this answer. Refer to the particular host environment you wish to use.
Any differences between JS engines? (ECMAScript Host environments).
Yes. Again this beyond the scope of this answer and dependent on the host
There are dozens of host environments, with new ones created all the time. What triggers the creation of a new execution context is highly dependent on the host environment.
I've been reading about web workers in HTML5, but I know JavaScript is single-threaded.
How are web workers doing multi-threaded work then? or how are they simulating it if it's not truly multi-threaded?
As several comments have already pointed out, Workers really are multi-threaded.
Some points which may help clarify your thinking:
JavaScript is a language, it doesn't define a threading model, it's not necessarily single threaded
Most browsers have historically been single threaded (though that is changing rapidly: IE, Chrome, Firefox), and most JavaScript implementations occur in browsers
Web Workers are not part of JavaScript, they are a browser feature which can be accessed through JavaScript
A bit late, but I just asked myself the same question and I came up with the following answer:
Javascript in browsers is always single-threaded, and a fundamental consequence is that "concurrent" access to variables (the principal headache of multithreaded programming) is actually not concurrent; this is true with the exception of webworkers, which are actually run in separate threads and concurrent access to variables must be dealt with in a somewhat explicit way.
I am not a JavaScript ninja, but I too was convinced that JavaScript in browser is provided as a single threaded process, without paying much attention to whether it was true or to the rationale behind this belief.
A simple fact that supports this assumption is that when programming in JavaScript you don't have to care about concurrent access to shared variables. Every developer, without even thinking of the problem, writes code as if every access to a variable is consistent.
In other words, you don't need to worry about the so called Memory model.
Actually there is no need of looking at WebWorkers to involve parallel processing in JavaScript. Think of an (asynchronous) AJAX request. And think how carelessly you would handle concurrent access to variables:
var counter = 0;
function asyncAddCounter() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
counter++;
}
};
xhttp.open("GET", "/a/remote/resource", true);
xhttp.send();
}
asyncAddCounter();
counter++;
What is the value of counter at the end of the process? It is 2.
It doesn't matter that it is read and written "concurrently", it will never result in a 1. This means that access to counter is always consistent.
If two threads where really accessing the value concurrently, they both could start off by reading 0 and both write 1 in the end.
In browsers, the actual data-fetching of a remote resource is hidden to the developer, and its inner workings are outside the scope of the JavaScript API (what the browser let's you control in terms of JavaScript instructions). As far as the developer is concerned, the result of the network request is processed by the main thread.
In short, the actual carrying out of the request is not visible, but the invocation of the callback (handling the result by custom JavaScript code) is executed by the main thread.
Possibly, if it wasn't for the webworkers, the term "multithreading" wouldn't ever enter the Javascript world.
The execution of the request and the asynchronous invocation of the callback is actually achieved by using event loops, not multithreading. This is true for several browsers and obviously for Node.js. The following are some references, in some cases a bit obsolete, but I guess that the main idea is still retained nowadays.
Firefox: Concurrency model and Event Loop - JavaScript | MDN
Chrome uses libevent in certain OS.
IE: Understanding the Event Model (Internet Explorer)
This fact is the reason why JavaScript is said to be Event-driven but not multithreaded.
Notice that JavaScript thus allows for asynchronous idioms, but not parallel execution of JavaScript code (outside webworkers). The term asynchronous just denotes the fact that the result of two instructions might be processed in scrambled order.
As for WebWorkers, they are JavaScript APIs that give a developer control over a multithreaded process.
As such, they provide explicit ways to handle concurrent access to shared memory (read and write values in different threads), and this is done, among the others, in the following ways:
you push data to a web worker (which means that the new thread reads data) by structured clone: The structured clone algorithm - Web APIs | MDN. Essentially there is no "shared" variable, instead the new thread is given a fresh copy of the object.
you push data to a web worker by transferring ownership of the value: Transferable - Web APIs | MDN. This means that the just one thread can read its value at any time.
as for the results returned by the web workers (how they "write"), the main thread access the results when prompted to do so (for instance with the instruction thisWorker.onmessage = function(e) {console.log('Message ' + e.data + ' received from worker');}). It must be by means of the usual Event Loop, I must suppose.
the main thread and the web worker access a truly shared memory, the SharedArrayBuffer, which is thread-safely accessed using the Atomic functions. I found this clearly exposed in this article: JavaScript: From Workers to Shared Memory
note: webworkers cannot access the DOM, which is truly shared!
You spawn a .js file as a "worker", and it runs processes in a separate thread. You can pass JSON data back and forth between it and the "main" thread. Workers don't have access to certain things like the DOM, though.
So if, say, you wanted to solve complicated math problems, you could let the user enter things into the browser, pass those variables off to the worker, let it do the computation in the background while in the main thread you let the user do other things, or show a progress bar or something, and then when the worker's done, it passes the answer back, and you print it to the page. You could even do multiple problems asynchronously and pass back the answers out of order as they finish. Pretty neat!
The browser kicks of a thread with the javascript you want to execute. So its a real thread, with this web workers thing, your js is no longer single-threaded.
The answer that claimed that "JavaScript is a language, it doesn't define a threading model, it's not necessarily single-threaded" is directly copy-pasted from a medium article... and it confuses without solving the doubt.
It's not necessarily single-threaded, like all other languages. YES... BUT
Javascript is a LANGUAGE meant for Single-threaded programming, and that is the beauty of it and makes it simple and easy to implement.
It is designed around a single Call stack.
Maybe in the future, with new implementations, it will become a Language for multi-threaded programming... but for now, Mehhhhhh.
The Node V8 is still single-threaded, yet it achieves multi-threaded capabilities by creating worker threads on LIBUV which is written in C++.
Same way, even though Javascript is not meant for Multithreading you can achieve limited multithreading by using Browser APIs.
Every time you open a TAB on a browser, it creates a new thread, and the process is the same with web workers.
It works internally BUT does not have access to any window objects.
Yes, People may call it Multithreaded if it makes em Happy,
But in 2021 the Answer is
"JS is meant for Single-threaded programming,(or a single-threaded language) but limited multi-threading can be achieved by using Browser APIs such as Web Workers"
Actually the main confusion, I think here, comes that people are finding clever ways to do things concurrently. If you think about it JavaScript is clearly not multithreaded and yet we have ways to do things in parallel, so what is going on?
Asking the right question is what will bring the answer here. Who is responsible for the threads? There is one answer above, saying that JS is just a language, not a threading model. Completely true!JavaScript has nothing to do with it. The responsibility falls on V8. Check this link for more information -> https://v8.dev/
So V8 is allowing a single thread per JS Context, which means, no matter how hard you try, spawning a new thread is simply impossible. Yet people spawn so-called workers and we get confused. For this to be answered, I ask you the following. Is it possible to maybe start 2 V8 and both of them to interpret some JS code? Precisely the solution to our problem. Workers communicate with messages because their context is different. They are other things that don't know anything about our context, therefore they need some information that comes in the form of a message.
As we are all aware, JavaScript is single-threaded: all code is queued and executed in a sequence.
Using Web Workers, we can run JavaScript processes concurrently (or at least, as close to concurrently as this language allows). The primary benefit of this approach is to handle the manipulation of data in background threads without interfering with the user-interface.
Using web worker:
Web Workers allow you to run JavaScript in parallel on a web page, without blocking the user interface.
Web workers executes in separate thread
Need to host all the worker code in separate file
They aren’t automatically garbage collected, So you need to control them.
To run worker use worker.postMessage(“”);
To stop worker there are two methods terminate() from caller code
and close() from Worker itself
Instantiating a worker will cost some memory.
Web Workers run in an isolated thread. As a result, the code that they execute needs to be contained in a separate file. But before we do that, the first thing to do is create a new Worker object in your main page. The constructor takes the name of the worker script:
var worker = new Worker('task.js');
If the specified file exists, the browser will spawn a new worker thread, which is downloaded asynchronously. The worker will not begin until the file has completely downloaded and executed. If the path to your worker returns an 404, the worker will fail silently.
After creating the worker, start it by calling the postMessage() method:
worker.postMessage(); // Start the worker.
Communicating with a Worker via Message Passing
Communication between a work and its parent page is done using an event model and the postMessage() method. Depending on your browser/version, postMessage() can accept either a string or JSON object as its single argument. The latest versions of the modern browsers support passing a JSON object.
Below is a example of using a string to pass 'Hello World' to a worker in doWork.js. The worker simply returns the message that is passed to it.
Main script:
var worker = new Worker('doWork.js');
worker.addEventListener('message', function(e) {
console.log('Worker said: ', e.data);
}, false);
worker.postMessage('Hello World'); // Send data to our worker.
doWork.js (the worker):
self.addEventListener('message', function(e) {
self.postMessage(e.data); // Send data back to main script
}, false);
When postMessage() is called from the main page, our worker handles that message by defining an onmessage handler for the message event. The message payload (in this case 'Hello World') is accessible in Event.data. This example demonstrates that postMessage() is also your means for passing data back to the main thread. Convenient!
References:
http://www.tothenew.com/blog/multi-threading-in-javascript-using-web-workers/
https://www.html5rocks.com/en/tutorials/workers/basics/
https://dzone.com/articles/easily-parallelize-jobs-using-0