sergiodxa / remix-utils

A set of utility functions and types to use with Remix.run
https://sergiodxa.github.io/remix-utils/
MIT License
2.02k stars 113 forks source link

eventStream cleanup function is not being called in vite dev mode #317

Open unbiased-dev opened 4 months ago

unbiased-dev commented 4 months ago

Describe the bug

When running vite:dev the eventStream return value which is the cleanup callback is not being triggered, probably because of HMR?..

It works fine as soon as you build and run your app that way.

Your Example Website or App

https://stackblitz.com/edit/remix-run-remix-fd7jtu?file=app%2Froutes%2F_index.tsx

Steps to Reproduce the Bug or Issue

Go to https://stackblitz.com/edit/remix-run-remix-fd7jtu?file=app%2Froutes%2F_index.tsx Refresh the inpage web browser. Note the user count going up instead of staying at 1. Check terminal. Note 'add called' being logged but not 'remove called'.

Expected behavior

Cleanup function to work in dev mode aswell, as it's kinda important.

Screenshots or Videos

No response

Platform

Additional context

No response

philhradecs commented 4 months ago

Thanks for creating the issue, I see the same problem after migrating to Vite. My setup involves an event queue and since the cleanup is never called, it causes my event listeners to pile up.

Remix: v2.8.0 Utils: v7.5.0 Vite: v5.1.4

matt-aitken commented 4 months ago

We're also experiencing this issue during development.

We are running Remix 2.1.0 not with Vite. We're using Express with a custom server with manual mode.

"dev": "cross-env PORT=3030 remix dev -c \"node ./build/server.js\"",

Our server file: https://github.com/triggerdotdev/trigger.dev/blob/main/apps/webapp/server.ts

vidjuheffex commented 1 month ago

Also experiencing this issue

sergiodxa commented 1 month ago

This is a problem with Vite dev server, it's not aborting the AbortSignal attached to the request so your event stream cleanup function will never run.

It has to be fixed on their said or you have to use a custom dev server that does it, the eventStream function can only rely on request.signal to be aborted

vidjuheffex commented 1 month ago

I got it!

import { EventEmitter } from "events";

let emitter;

if (process.env.NODE_ENV === "production") {
  emitter = new EventEmitter();
  emitter.setMaxListeners(100);
} else {
  if (!global.__emitter) {
    global.__emitter = new EventEmitter();
    global.__emitter.setMaxListeners(100);
  }
  emitter = global.__emitter;
}

export { emitter };

exporting my emitter like this did the trick! (this is from the jokes example app)