1

I am currently working with Web Workers and for some testing purposes it would be nice if it was possible to wait in the main thread until workers have finished what they're doing. So:

Main thread -> start workers

Main thread -> wait for workers to finish

workers -> do some work

Workers finish.

Main thread -> do some stuff.

I realize the most correct way of doing this is using a callback in the main thread that is called whenever a worker finishes but this will not work for practical reasons. I've made what is similar to a CyclicBarrier in Java but whenever I call barrier.enter() in the main thread I of course get an error. Hence what I want to know is if there's any setting or something similar I can set which temporarily allows me to block on the main thread. I'm running my program using Node btw.

This is purely for testing purposes, I would of course never use this in a production environment!

PNS
  • 750
  • 1
  • 5
  • 19
  • AFAIK the only ways to pause JS are `alert`, `confirm`, `prompt` and the deprecated `showModalDialog`. Or `while(true)`, but that freezes the browser and wastes CPU. – Oriol Mar 08 '16 at 19:03
  • Yeah, I've tried these but they won't work in my case. I need something that actually allows me to block I think. – PNS Mar 08 '16 at 19:05
  • 1
    Short answer: no. I've written code that does this sort of thing in javascript, and you basically need to keep an array where all the "workers" can mark themselves as "finished", with each obviously initialized to "not finished". When each worker marks itself you then have a piece of code that checks to see if everybody is finished and, if so, do whatever the continuation is (the next piece of code that would have been after your "wait until everybody is finished" code). Again, I've done this and never had problems with it. – Michael Chaney Mar 08 '16 at 19:08
  • Yeah, but I can't seem to get this to work alongside qunit which is what I'm using... – PNS Mar 08 '16 at 19:10
  • I haven't tried this, but it *might* be possible to efficiently block the main thread using a synchronous XHR request which is managed by a ServiceWorker, which could asynchronously communicate with your other WebWorkers to synchronize things. – Jeremy Mar 08 '16 at 20:33
  • I actually gave this a shot, but it doesn't seem to work: my ServiceWorker doesn't seem to get `fetch` events for sync requests, only async ones. I don't entirely understand the spec, but it looks like synchronous requests might result in a lot of logic being skipped (probably because they're deprecated and complicating). Makes sense, but unfortunate in this case. – Jeremy Mar 08 '16 at 21:48
  • Actually, it looks like it *is* possible to use a ServiceWorker to handle synchronous requests that block the main thread *in Firefox*! I've asked [a related question](http://stackoverflow.com/questions/35879844/can-service-workers-respond-to-synchronous-xhr-requests) to determine whether I'm missing something, or this is a Chrome bug, or what. – Jeremy Mar 08 '16 at 23:12
  • Cool Jeremy, I'll try and check that out. – PNS Mar 08 '16 at 23:20

1 Answers1

0

If you insist on not using events, you're putting yourself in a tricky situation. If you block the main thread, you make it impossible to process event that the worker sends once it's done. And there's no other communication channel between worker and main thread.

Or is there? You could possibly create a HTTP server that would relay all data from worker to the main thread. Main thread could create a synchronous HTTP request on that server. Synchronous AJAX requests do block main thread but do not eat the CPU.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Yeah I suppose that is an option although somewhat convoluted. I realize that blocking the main thread I will be unable to receive events, but the way I'm blocking it is by using a cyclicbarrier implemented using sharedmemory in firefox nightly. Thus whenever all workers have reached a certain point in their code the main thread will unblock without even receiving events! Thus if the main thread could be blocked it should still work. But as you say this does not even seem possible. – PNS Mar 08 '16 at 23:20