superset icon indicating copy to clipboard operation
superset copied to clipboard

superset-frontend proxy is not working when superset backend decides to use zstd encoding

Open jakubjosef opened this issue 1 year ago • 4 comments

Bug description

Hi guys, my company is using Apache Superset and we just found weird situation. Our new developer were using superset-frontend and he saw weird characters being displayed instead of "normal page". After few hours of investigation we realised the problem was superset (python server) which served content using zstd encoding (instead of br encoding which other devs were using). zstd encoding is not supported by superset's node js proxy (see: https://github.com/apache/superset/blob/10c78960a7c5e5628aaceb584c206a81f7fd12c8/superset-frontend/webpack.proxy-config.js#L123) We managed to fix the problem using exactly same version of python packages from working machine, but it looks like some superset dependency was updated to serve using zstd by default. Unfortunately it looks like zstd is not supported in node.js yet, so we cannot just easily support zstd in webpack.proxy-config.js Does anyone know which exact package can cause this? I tried to grep superset and werkzeug code for zstd but found nothing. Thank you for your suggestions.

How to reproduce the bug

  1. Install latest superset
  2. Start superset backend
  3. Start superset frontend dev-server (npm run dev-server)
  4. Go to dev-server and you will see bunch of question marks and weird characters instead of expected markup

Screenshots/recordings

No response

Superset version

master / latest-dev

Python version

3.11

Node version

18 or greater

Browser

Chrome

Additional context

No response

Checklist

  • [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
  • [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
  • [X] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.

jakubjosef avatar May 07 '24 11:05 jakubjosef

The issue you're encountering with Apache Superset's frontend proxy not supporting zstd encoding likely stems from an indirect dependency update within Superset's Python environment. While the webpack.proxy-config.js is configured to handle gzip, br, and deflate encodings, it does not include support for zstd ^superset-frontend/webpack.proxy-config.js^. This absence means that when the backend serves content with zstd encoding, the proxy cannot decode it, leading to the display issues you've observed.

To identify the package that might have introduced zstd as a default encoding, you would need to review recent changes to the dependencies listed in Superset's pyproject.toml. Although zstd is not listed as a direct dependency, it could be introduced through other libraries, especially those related to data processing or compression. For instance, the pandas package, with its [performance] extra, includes optional dependencies that could utilize zstd compression, such as pyarrow ^pyproject.toml^.

Adding support for zstd in the Node.js proxy would require integrating a decompression mechanism into webpack.proxy-config.js, similar to how other encodings are handled. This integration would depend on the availability of a Node.js module capable of decompressing zstd encoded data. As of the last update, adding such support might involve using third-party modules like node-zstd, though direct support in Node.js for zstd is not yet standard.

For a more immediate solution, ensuring that all developers are using the same version of Python packages, as you've done, can prevent the issue from occurring by avoiding the introduction of zstd encoding. Additionally, investigating the specific versions of indirect dependencies related to compression could help pinpoint the source of the zstd encoding.

Details

Sources


About Dosu This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

To continue the conversation, mention @dosu.

dosubot[bot] avatar May 07 '24 12:05 dosubot[bot]

@jakubjosef so that would be on a fresh install from pypi as in pip install apache-superset ?

Doing a bit of guessing here, since all of our CI installs the pin packages in requirements/development.txt, maybe the unpinned version of Superset has this issue? If that's the case it points towards:

  • as a workaround, you leveraging docker images build on top of pinned deps, or using the pinned deps in your installation scripts
  • for us, we could run some CI tests against a vanilla pip install apache-superset, so at least we know when an open dependency breaks a build - which would inform pin-pointing the issue and changing the version range for that dep

mistercrunch avatar May 07 '24 21:05 mistercrunch

Yes, in our install script we are using pip install apache-superset==4.0.0rc1. I see 4.0.0 is now officially published, so we can try to use it, but I think we'll face the same issue eventually.

jakubjosef avatar May 22 '24 13:05 jakubjosef

but I think we'll face the same issue eventually

My suggestion would be either:

  • use the base docker, which installs the pinned deps ahead of installing the apache-superset package
  • fetch the requirements/base.txt from the repo (with the associated version tag you're trying to build as in git checkout 4.0.0) and pip install those pin deps ahead of installing the superset package (that has loose dependency ranges). At that point might as well pip install -e . to install from the repo as opposed to pypi, but should be same as pip install apache-superset==4.0.0

On our side, there's a question as to whether we should publish a more strict or "with depenencies pinned" version of the package to work around all this....

mistercrunch avatar May 23 '24 17:05 mistercrunch

Hi @jakubjosef thanks for reporting this, and for the research into the cause. I ran into the same issue and found that adding COMPRESS_REGISTER = False into my superset_config.py file fixes it for me when developing locally. We'll look into either documenting this somewhere or fixing it more longer-term.

eschutho avatar May 29 '24 00:05 eschutho

I also encountered the same problem. After modifying config.py =>COMPRESS_REGISTER = False, the page no longer had strange symbols, but there were many resources on the page that failed to load; May I ask how I can solve this problem? superset:3.1.3 python: 3.9.7 node: 16.20.2 npm: 8.19.4 supersetbug

Amylee520 avatar Jun 05 '24 10:06 Amylee520

@Amylee520 We basically took a list of exact versions from another working machine (IIRC the command was pip freeze) and use it as source of truth for pip on new device. Not an ideal solution but we were in bit time rush.

jakubjosef avatar Jun 05 '24 10:06 jakubjosef

For me the culprit package was Flask-Compress 1.15. Rolling back Flask-Compress to 1.14 and removing zstandard solved the problem.

You can pip install pipdeptree and then run pipdeptree -r -p zstandard to see what depends on zstandard.

tyrius02 avatar Jun 07 '24 22:06 tyrius02

@tyrius02 Thank you for identifying what exact package version is causing this problem, it can help others. We were not able to identify exact cause when we faced this problem.

jakubjosef avatar Jun 08 '24 08:06 jakubjosef

$ cd superset-frontend
$ npm i simple-zstd -D 

Edit superset-frontend/webpack.proxy-config.js add zstd support :

const {ZSTDDecompress} = require('simple-zstd');

...
function processHTML(proxyResponse, response) {
  ...

  } else if (responseEncoding === 'zstd') {
    uncompress = ZSTDDecompress();
  }
 ...
}

rebareba avatar Jul 31 '24 11:07 rebareba

@rebareba Great, thank you for providing this code!

jakubjosef avatar Jul 31 '24 11:07 jakubjosef

Sounds like we're discussing this bug... I'm excited to hear we're on the verge of a real fix here!

rusackas avatar Jul 31 '24 17:07 rusackas

Fixed by https://github.com/apache/superset/pull/30034 Thanks to all (especially @rebareba) for the help here!

rusackas avatar Aug 28 '24 18:08 rusackas