pretext-cli
pretext-cli copied to clipboard
Codespace/codechat issue with 2.3.5+
I assume this has something to do with how static files are now handled. But in a Codespace using PreTeXt-CLI 2.3.5 or 2.3.6, CodeChat builds are taking a long, sometimes random amount of time. Downgrading to 2.3.4 alleviates the issue. (EDIT: or maybe not - now I'm having trouble with 2.3.4.)
As of today, new projects created with pretext-codespaces do not work with codechat preview.
Temporary workaround is still to pip install pretext==2.3.4
So I discovered during my faculty meeting demo of pretext <facepalm />. In fact, it seems like we now have the same issues with pretext view, even after fixing it previously.
Could I have reverted the 2.3.6 fix in 2.3.7???
Yeah, it also works fine in 2.3.6. I'm guessing there was a change in the static js files, since this uses a newer core commit. Infact, building with 2.3.8 and viewing with 2.3.6 does not work.
Also, we need to figure out a way to put this in our tests. Not understanding what the issue actually is, I'm not sure how to test for it.
I think the correct fix is to package these files in a JS bundler (esbuild is my favorite). Otherwise, we'll keep getting shut down by Microsoft's firewall, which thinks we're using CodeSpaces as a web server.
@siefkenj and of course Brad have lots of experience doing this. Is there any interest from the core team (@rbeezer, etc.) for doing this? If so, this should be done with Runestone in mind, since we already bundle JS using Runestone.
This isn't just a Codespaces thing for clarity, though that's the pain at hand today - we need to produce HTML that can be served even if the host rate limits the number of javascript files loaded.
Could someone clarify for me exactly what the problem is. (or point me to the discussion on -dev if it is already there.). I'm having a hard time figuring out how build times and rate limits on javascript loads are related...
Here is the -dev link: https://groups.google.com/g/pretext-dev/c/VABcbEle0R0
For what it's worth, I don't see the problem when using just a simple python -m http.server command and navigating to the output folder. I have never run into issues with a deployed book. As far as I know, it only shows up inside codespaces.
Thanks Oscar, I just found it myself.
Are you seeing a status code of 429 Too many requests in codespaces?
In looking at several pages from the sample book, built with 2.3.8 emacs only counts 22 css or js files that are loaded from _static That does not seem excessive to me. 🤷🏻
Github pages only rate limit is on the overall bandwidth used during the course of a month. A simple github page loads more than 40 js files!
Oscar, are you running the simple python based server in codespaces?
Maybe someone should look at the network panel in the browser when using CodeChat to get a sense for how much requesting is going on in the background....
CodeChat adds just a few more files that are loaded at startup, then not reloaded. However, it doesn't cache files so that any edits to a page get revealed immediately.
If a user is editing pretext and viewing the results in codechat they are not changing the javascript or css... So I'm not seeing the harm in caching the css/js files. Sorry if I'm still not understanding the problem well enough.
I guess I should take some time and try to set up one of my books under codespaces so I can see the user experience.
I'm wondering now if it is a permissions issue. Here is one of a bunch of errors I get from the console when a page finally loads:
Refused to execute script from 'https://glorious-space-guide-jgxwgv5rg63v9w-8128.app.github.dev/output/web/_static/pretext/js/pretext_search.js' because its MIME type ('') is not executable, and strict MIME type checking is enabled.
Also a lot of:
pretext_add_on.js:1 Failed to load resource: the server responded with a status of 504 ()
Another odd thing: when I test using the pretext-cli codespace for development, it works just fine. It is only on a pretext project in its own codespace that has issues. Checking permissions of the output folders seems to show no difference though.
Here is some output from the terminal:
127.0.0.1 - - [29/Feb/2024 20:04:26] "GET /output/web/_static/pretext/js/pretext.js HTTP/1.1" 304 -
127.0.0.1 - - [29/Feb/2024 20:04:26] "GET /output/web/_static/pretext/css/shell_default.css HTTP/1.1" 304 -
127.0.0.1 - - [29/Feb/2024 20:04:26] "GET /output/web/_static/pretext/css/pretext.css HTTP/1.1" 200 -
127.0.0.1 - - [29/Feb/2024 20:06:35] "GET /output/web/_static/pretext/css/colors_blue_red.css HTTP/1.1" 304 -
127.0.0.1 - - [29/Feb/2024 20:06:35] "GET /output/web/_static/pretext/css/knowls_default.css HTTP/1.1" 304 -
127.0.0.1 - - [29/Feb/2024 20:06:35] "GET /output/web/generated/latex-image/tikz-cone.svg HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 48400)
Traceback (most recent call last):
File "/usr/local/lib/python3.11/socketserver.py", line 317, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/local/lib/python3.11/socketserver.py", line 348, in process_request
self.finish_request(request, client_address)
File "/usr/local/lib/python3.11/socketserver.py", line 361, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/local/lib/python3.11/http/server.py", line 671, in __init__
super().__init__(*args, **kwargs)
File "/usr/local/lib/python3.11/socketserver.py", line 755, in __init__
self.handle()
File "/usr/local/lib/python3.11/http/server.py", line 436, in handle
self.handle_one_request()
File "/usr/local/lib/python3.11/http/server.py", line 424, in handle_one_request
method()
File "/usr/local/lib/python3.11/http/server.py", line 678, in do_GET
self.copyfile(f, self.wfile)
File "/usr/local/lib/python3.11/http/server.py", line 877, in copyfile
shutil.copyfileobj(source, outputfile)
File "/usr/local/lib/python3.11/shutil.py", line 200, in copyfileobj
fdst_write(buf)
File "/usr/local/lib/python3.11/socketserver.py", line 834, in write
self._sock.sendall(b)
BrokenPipeError: [Errno 32] Broken pipe
----------------------------------------
127.0.0.1 - - [29/Feb/2024 20:06:37] "GET /output/web/_static/pretext/js/user_preferences.js HTTP/1.1" 200 -
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 48430)
Traceback (most recent call last):
File "/usr/local/lib/python3.11/socketserver.py", line 317, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/local/lib/python3.11/socketserver.py", line 348, in process_request
self.finish_request(request, client_address)
File "/usr/local/lib/python3.11/socketserver.py", line 361, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/local/lib/python3.11/http/server.py", line 671, in __init__
super().__init__(*args, **kwargs)
File "/usr/local/lib/python3.11/socketserver.py", line 755, in __init__
self.handle()
File "/usr/local/lib/python3.11/http/server.py", line 436, in handle
self.handle_one_request()
File "/usr/local/lib/python3.11/http/server.py", line 424, in handle_one_request
method()
File "/usr/local/lib/python3.11/http/server.py", line 678, in do_GET
self.copyfile(f, self.wfile)
File "/usr/local/lib/python3.11/http/server.py", line 877, in copyfile
shutil.copyfileobj(source, outputfile)
File "/usr/local/lib/python3.11/shutil.py", line 200, in copyfileobj
fdst_write(buf)
File "/usr/local/lib/python3.11/socketserver.py", line 834, in write
self._sock.sendall(b)
BrokenPipeError: [Errno 32] Broken pipe
----------------------------------------
127.0.0.1 - - [29/Feb/2024 20:06:38] "GET /output/web/_static/pretext/css/pretext_search.css HTTP/1.1" 200 -
My guess: the broken pipe occurs because CodeSpaces permanently closed the port due to exceeding rate limits, not because of permissions.
If a user is editing pretext and viewing the results in codechat they are not changing the javascript or css... So I'm not seeing the harm in caching the css/js files. Sorry if I'm still not understanding the problem well enough.
Most of the time, the CSS/JS don't change, but if Pretext gets upgraded, it might. Perhaps we can cache these anyway and warn users they need to force a reload? Or do the CSS/JS files have some sort of version specifier to help with this?
This:
Refused to execute script from 'https://glorious-space-guide-jgxwgv5rg63v9w-8128.app.github.dev/output/web/_static/pretext/js/pretext_search.js' because its MIME type ('') is not executable, and strict MIME type checking is enabled.
Seems quite significant. Especially since the script tags to the _static assets do not have a type. I know it is supposed to default to javascript but if strict checking is enabled it seems it is refusing to serve it.
Again, using the Network tab might give more clues as far as response codes from the server.
In the just released 2.3.9, I found a workaround for now at least (but not for codechat): when the CLI notices that we are using codespaces, it will simply subprocess.run("pretext -m http.server"), which seems to work. I feel very silly calling a python subprocess from a python script, but no variation of the imported http.server module seemed to get me a working system.
@oscarlevin The command pretext -m http.server runs the http.server.py module as though __name__ == '__main__' is True To make it work without using subprocess you would need to grab the last 20 lines from server.py and drop them into your code.
This:
Refused to execute script from 'https://glorious-space-guide-jgxwgv5rg63v9w-8128.app.github.dev/output/web/_static/pretext/js/pretext_search.js' because its MIME type ('') is not executable, and strict MIME type checking is enabled.Seems quite significant. Especially since the script tags to the
_staticassets do not have a type. I know it is supposed to default to javascript but if strict checking is enabled it seems it is refusing to serve it.Again, using the Network tab might give more clues as far as response codes from the server.
I did some debug on CodeChat -- I only get this when the server doesn't respond to a request, so the client gets no/empty data and therefore sees an empty MIME time. When the server does respond, it sends the correct MIME type.
I spent a fair amount of time debugging this weekend. I haven't tracked down the root case. Observations:
- Throttling the server doesn't help, even slowing to 1 response per 5 seconds.
- The problem is intermittent. It usually doesn't work, but sometimes does work, with the same code.
- The client requests data from the server. The server responds to all client requests it receives. But, some requests seem to be dropped routing from the client back to the server.
- Using
python -m http.serveralways works, with no dropped requests. - Using the equivalent Bottle server doesn't work. (I use the bottle.py server for CodeChat.)
- Reverting to an older version of PreTeXt, in which there are fewer local files to load, always works.
- Outside the CodeSpaces environment, the server works without problems.
I filed https://github.com/bottlepy/bottle/issues/1442, hoping the Bottle team can track this down.
I tried switching back to Flask as a server, but that also failed.