question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ability to explicitly terminate the store

See original GitHub issue

New Features

NOTE: This could also be considered a bug report because it’s causing a memory leak.

What is the new or updated feature that you are suggesting?

I’m wanting to add a store.terminate function to remove the Redux store entirely, close all listeners, and tell all middleware to run their own terminate functionality including the removal of that store from Redux-Devtools.

Why should this feature be included?

Already talked about a bit here: https://twitter.com/acemarke/status/1296514045789507585?s=20.

We need some way to kill of the Redux store without relying on Garbage Collection. In many cases, especially during development, the Redux store has no way of dying.

Why has no one requested this feature?

Typical use cases of a Redux store with React are it being included on a root element with the Provider component from react-redux. In many other applications that use Redux, there is a single store, and it’s never removed. Even in cases where there are multiple stores, the idea is that they stick around forever.

I’m building an application where Redux stores will be created and removed based on the page route. Because of this, I need some way to get rid of Redux.

It’s not entirely uncommon to want to load up and kill off Redux stores, especially when you have a component library that uses Redux, but you don’t want to have the parent application manage the Redux store. It shouldn’t matter what the component library uses internally, but if it does use Redux, it should clean up after itself.

Where does this show up?

There are 2 common practices with Redux which are problematic for this use case. The first is, Redux-Devtools, and the second is something like Redux-Observable or Redux-Saga or any custom middleware with event listeners.

In both cases, even doing store = null doesn’t fix the issue. Either the store is still being used by Redux-Devtools or event listeners are still active in middleware with no way of knowing we want garbage collection to remove the store.

Personally, I prefer being explicit in removing the store rather than relying on garbage collection. I understand this could cause problems if you have something call dispatch when the store no longer exists, but good code shouldn’t run into this situation. My code knows when it’s safe to terminate the Redux store, but there’s no way to notify Redux-Devtools or middleware so I keep creating new stores over and over.

Example code

https://codesandbox.io/s/redux-store-memory-leak-lg78o

Many stores created in Redux-Devtools

Redux-Devtools has no clue Redux needs to be terminated, so it listens forever and keeps those stores active in memory:

image

Multiple middlewares loaded

Two listeners responding to click events because Redux didn’t notify middleware the store’s been terminated:

image

What docs changes are needed to explain this?

Add .terminate to the docs on store explaining what this does and how middleware should interact with it. In the case of Redux-Observable, all it needs to do is unsubscribe from the root epic and all listeners will be removed automatically via RxJS.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:18 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
markeriksoncommented, Sep 3, 2020

My suggestion would be to first try implementing this as a store enhancer, and see how something like that works out.

2reactions
Sawtaytoescommented, Sep 3, 2020

This is what I’m proposing:

  1. A standard @@TERMINATE action that tells middleware to close any active listeners and callbacks.
    1. This gets dispatched directly from store.dispatch({ type: '@@TERMINATE' }).
    2. Gets dispatched from store.terminate().
  2. A store.terminate() function which loops through all store.onTerminate(callback) callbacks in middleware so they know when to close any active listeners and callbacks. This doesn’t just affect middleware. Anything like react-redux can also remove references to store if it’s still got them somewhere.

Consumers of Redux that have a store need to do store = null to get rid of the reference to it in their own apps. As soon as all references to store are removed, Redux (including its middleware) will be garbage collected.

That’s the goal of this whole issue. We need some way of removing Redux from memory using garbage collection. Normally this works fine, but since Redux allows for middleware, we need to also notify middleware that Redux has been terminated; thus, they should also stop any active addEventListener, setInterval, and setTimeout callbacks. Doing so will successfully allow Redux to garbage collect.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Termination for Convenience Under the Uniform Commercial ...
11 This section further states that when a contract is terminable at will (whether by operation of the code or explicit agreement of...
Read more >
Everything You Need to Know About the Early Termination of ...
Include your request for specific early termination rights within the initial Request for Proposal and Letter of Intent. Determine the minimum notice a...
Read more >
Using termination protection - Amazon EMR
When termination protection is enabled on a long-running cluster, you can still terminate the cluster, but you must explicitly remove termination protection ...
Read more >
SET XACT_ABORT (Transact-SQL) - Microsoft Learn
When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.
Read more >
How to Legally Fire an Employee - U.S. Chamber of Commerce
Terminating a worker can be a complicated process. ... their employer will have to follow its explicit terms when considering termination.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found