Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long-running process inside a Service Worker (or something similar)

I have a client-side JS app that uses IndexedDB to store its state. Works fine. However, it's kind of slow because I am frequently reading from and writing to IndexedDB so that the state does not become inconsistent when multiple tabs are open.

My idea was... put all DB access stuff inside a Service Worker, and then I can cache values there in memory without worrying that another tab might have altered the database.

That seems to work fine, except some parts of my application take a long time to run. I can communicate the status (like "X% done") from the Service Worker to my UI. But both Firefox and Chrome seem to kill the worker if it runs for more than 30 seconds, which is way too short for me.

Is there any way around this limitation? If not, any ideas for achieving something similar? A Shared Worker could do it I think, except browser support is poor and I don't anticipate that improving now with the momentum behind Service Workers.

like image 293
dumbmatter Avatar asked Dec 29 '16 03:12

dumbmatter


People also ask

What is an example of a service worker?

Examples of personal service positions include: medical assistants and other healthcare support positions, hairdressers, ushers, and transportation attendants. Examples of cleaning service positions include: cleaners, janitors, and porters.

What is the life cycle of a service worker?

The service worker lifecycle has 3 steps; Registration, Installation, and Activation.

What is service worker used for?

Service workers are specialized JavaScript assets that act as proxies between web browsers and web servers. They aim to improve reliability by providing offline access, as well as boost page performance.

How do service workers improve performance?

One of the biggest benefits of service workers is their ability to support offline experiences. In the past, the AppCache API could be used to provide limited offline support, but service workers have now made AppCache obsolete. Loading locally cached data always takes less time than retrieving data from the web.


2 Answers

The Google documentation on service workers tells us that using service workers as a memory cache is impossible:

It's terminated when not in use, and restarted when it's next needed, so you cannot rely on global state within a service worker's onfetch and onmessage handlers. If there is information that you need to persist and reuse across restarts, service workers do have access to the IndexedDB API.

My suggestion is to keep using service workers to persist data to the database, and use localStorage to create a shared cache between pages. The tab that is making the change is then responsible for both updating the cache in localStorage and persisting to IndexedDB through the service worker.

like image 121
Borre Mosch Avatar answered Oct 16 '22 16:10

Borre Mosch


I ended up using a Shared Worker. In browsers that don't support Shared Workers, such as Edge and Safari, I fall back to a Web Worker and some hacky code to only let you open the app in one tab at a time.

Since 90% of my users are on Firefox or Chrome anyway, I figure it's not a huge loss.

I also wrote a library to (amongst other things) normalize the APIs used in Shared Workers and Web Workers, so I have the exact same code running in both scenarios, the only difference is whether the worker is initialized with Worker or SharedWorker.

like image 44
dumbmatter Avatar answered Oct 16 '22 15:10

dumbmatter