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.

Initialstate gets corrupted/cached on server side for concurrent requests

See original GitHub issue

Describe the bug

The app requests multiple endpoints and uses an identifier to get the data. This identifier, catalog ID, is set in _app.js after looking at incoming request. Once the catalog ID is identified a store.dispatch is sent and catalog ID is set in an object named appConfigs server side store. All the components get catalog id from server side store and use this to different backend calls. This works perfectly fine when the apps is browsed one page at a time. As soon as more than 3 concurrent calls are sent, the catalog id on server side gets mixed up. This causes initialstate to be corrupted and subsequently client side hydration is also mixed up when client side store is hydrated with this corrupted data.

Here is how the store is being created and then used in _app.js

// store.js
/* eslint-disable no-underscore-dangle */
import { createStore, applyMiddleware } from "redux";
import logger from "redux-logger";
import createSagaMiddleware from "redux-saga";
import reducers from "../reducers/index";
import rootSaga from "../sagas/rootSaga";

const isDev = process.env.NODE_ENV === "development";
const isServer = typeof window === "undefined";

const sagaMiddleware = createSagaMiddleware();

const middleWares = [sagaMiddleware];
if (isDev && !isServer) {
  middleWares.push(logger);
}

let initialState = {};
if (!isServer && window.document && window.__NEXT_DATA__) {
  initialState = window.__NEXT_DATA__.props.initialState;
  delete window.__NEXT_DATA__;
}

const store = createStore(reducers, initialState, applyMiddleware(...middleWares));

sagaMiddleware.run(rootSaga);

export default store;

//_app.js only posting/pasting relevant code
import App from "next/app";
import React from "react";
import { Provider } from "react-redux";
import { createWrapper } from "next-redux-wrapper";
import store from "./store";

class BasePage extends App {
  static async getInitialProps({ Component, ctx }) {
/*
Logic to find following
 rootGeoId: country,
 catalogue,
 category,
*/
    ctx.store.dispatch({
      type: APP_CONSTANTS.SET_APP_CONFIGS,
      payload: {
        rootGeoId: country,
        catalogId: catalogue,
        category,
      },
    });
    const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
    return {
      country,
      configs,
      pageProps,
      path: ctx.asPath,
    };
  }
render() {
// logic for renderLayout 
    return (
      <ThemeProvider theme={theme}>
        <Provider store={store}>
          {renderLayout}
        </Provider>
      </ThemeProvider>
    );
}
}

const makeStore = () => store;
export default createWrapper(makeStore).withRedux(BasePage);

To Reproduce

You will need a way to click open multiple pages using mouse wheel click

  • Visit https://uat.fnp.com/red-roses
  • From Global menu, open “Women’s day” gift links using mouse wheel in new tabs.
  • Visit tabs and look in initialStore for these pages using Components under react dev tools
  • You will notice for some of the countries the catalogID in initialStore.appConfigs is not correct, for example, for UAE it can be UK.

Expected behavior

Every request should maintain its unique store. This is visible when you just browse the site/app one page at a time

Screenshots

Screenshot 2021-07-06 at 00 30 12

Desktop (please complete the following information):

  • OS: Any
  • Browser Any

Additional context

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:6
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

github_iconTop Results From Across the Web

How to structure multiple HTTP requests in a server-side ...
I have solved this previously by creating a Promise for each API call, and wait for all of them with axios.all() . The...
Read more >
Server-side cache without shared-state - Google Groups
Since once cannot have shared-state, how would one create a server-side ... I was assuming a web server environment that can handle concurrent...
Read more >
Server Rendering - Redux - JS.ORG
On the server side, rendering is synchronous and we only get one shot to render our view. We need to be able to...
Read more >
Authenticating server side requests to purecloud API
Is there a way to increase the number of valid concurrent tokens generated by a single client credentials (maybe to ~1000)?. If not,...
Read more >
Maximum concurrent requests per instance (services)
The specified concurrency value is a maximum and Cloud Run might not send as many requests to a given container instance if the...
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