WordPress/wordpress-playground

Rate limiting on wasm.wordpress.net

Closed this issue · 2 comments

Loading the post editor with CONCATENATE_ASSETS=false triggers a heap of assets requests, some of which fail due to rate limiting.

Let’s restrict the service worker to n requests per second and also cache ja and css assets from WP core

Relevant code snippet from ChatGPT:

const CACHE_NAME = 'cache-v1';
const MAX_CONCURRENT_REQUESTS = 20;
const ONE_DAY = 24 * 60 * 60 * 1000; // 1 day in milliseconds
const resourcesToCache = /\.(css|js)$/;

class Semaphore {
  constructor(count) {
    this.count = count;
    this.queue = [];
  }

  async acquire() {
    if (this.count > 0) {
      this.count--;
    } else {
      await new Promise(resolve => this.queue.push(resolve));
    }
  }

  release() {
    if (this.queue.length > 0) {
      this.queue.shift()();
    } else {
      this.count++;
    }
  }
}

const requestSemaphore = new Semaphore(MAX_CONCURRENT_REQUESTS);

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
      console.log('Service Worker: Cache opened');
    })
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    (async () => {
      const url = new URL(event.request.url);

      if (resourcesToCache.test(url.pathname)) {
        const cache = await caches.open(CACHE_NAME);
        const cachedResponse = await cache.match(event.request);

        if (cachedResponse) {
          const now = Date.now();
          const cachedTime = new Date(cachedResponse.headers.get('date')).getTime();

          if (now - cachedTime < ONE_DAY) {
            console.log('Service Worker: Serving cached resource', event.request.url);
            return cachedResponse;
          }
        }
      }

      await requestSemaphore.acquire();

      try {
        const networkResponse = await fetch(event.request);

        if (resourcesToCache.test(url.pathname)) {
          const cache = await caches.open(CACHE_NAME);
          await cache.put(event.request, networkResponse.clone());
          console.log('Service Worker: Resource cached', event.request.url);
        }

        requestSemaphore.release();
        return networkResponse;
      } catch (error) {
        requestSemaphore.release();
        throw error;
      }
    })()
  );
});

The server-side rate limiting was adjusted, thus this issue is now solved. Let's track the client-side rate-limiting separately in #180