r-wasm / webr

The statistical language R compiled to WebAssembly via Emscripten, for use in web browsers and Node.
https://docs.r-wasm.org/webr/latest/
Other
884 stars 69 forks source link

Webr freezes when opening .xlsx file with readxl package #213

Open JeremyPasco opened 1 year ago

JeremyPasco commented 1 year ago

Hi, I've trie the following javascript code without success. Webr was loaded from npm (v0.1.1).

webR = new WebR();
await webR.init();
await webR.evalR('webr::install("readxl")');
await webR.evalR('library(readxl)');

// Importing file here, then
await webR.FS.writeFile('data.xlsx', content)

await webR.evalR('data <- read_excel("data.xlsx")');

console.log('done')

Last promise (read_excel) never resolves nor fails. I can see some successful webr-fetch-request in Chrome devconsole after calling read_excel, then it freezes and CPU load rises.

I can confirm that the data.xlsx file has been successfully written in FS with a dir() command and that this behavior is consistent with other .xlsx files.

Listening to webR.read() returns nothing specific (libs are loaded, then a prompt. message type is returned with no data).

Am I missing something?

georgestagg commented 1 year ago

Hi, thanks for reporting this.

It looks like the bug is triggered when 'data.xlsx' is a zero length file, though I am not yet sure where in the ecosystem webR is getting stuck. Can you check the result of running,

file.info("data.xlsx")

and check that the size column is non-zero as expected? Probably the easiest way to do this is use webR.writeConsole rather than webR.evalR and check the result of webR.read() as you have been doing.

Can you tell me more about your code to import the file content? Is the type of your content object an ArrayBuffer? I noticed when I was investigating that you cannot pass a raw ArrayBuffer here but must pass a data view. For example, for me the bug goes away if I load the data with,

const buffer = await fetch('./diamonds.xlsx')
  .then(response => response.arrayBuffer())
  .catch(err => console.error(err));
await webR.FS.writeFile('data.xlsx', new Uint8Array(buffer));

When I just pass the raw buffer as the argument here, the bug is triggered. I consider this a separate bug to the lock-up, there should be a runtime check in webR.FS.writeFile and an error thrown.

JeremyPasco commented 1 year ago

Nice catch! I made a typo indeed by reusing the ArrayBuffer instead of my Uint8Array in webR.FR.writeFile(). Thanks. I'll try to propose a pull request+test about it.