soegaard2
2021-7-8 10:00:06

Good news - and bad news.

The documentation for Sketching now builds correctly via Github Actions using this command: xvfb-run -a raco scribble sketching-doc/sketching-doc/manual-sketching.scrbl However, the Racket build server still fails with the error: raco setup: rendering: <pkgs>/sketching-doc/sketching-doc/manual-sketching.scrbl cannot instantiate `racket/gui/base' a second time in the same process context...: body of "/home/root/racket/share/pkgs/gui-lib/mred/private/wx/common/once.rkt" body of "/home/root/racket/share/pkgs/gui-lib/mred/private/wx/platform.rkt" So … what to do?

Note that I have attempted to instantiate racket/gui only once using make-base-eval-factory.

https://github.com/soegaard/sketching/blob/main/sketching-doc/sketching-doc/manual-sketching.scrbl#L405


mflatt
2021-7-8 12:07:43

Compiling modules or running documentation should never instantiate racket/gui/base. It’s less a question of sandboxes and more about multiple namespaces (for different builds within the same Racket instance), multiple places (for concurrent builds within a Racket instance), and potentially building in an environment without a GUI context.


soegaard2
2021-7-8 12:14:08

It’s a bit tricky to avoid in the current setup.


soegaard2
2021-7-8 12:14:56

A #lang sketching always starts a frame with a canvas and displays an animation.


soegaard2
2021-7-8 12:16:35

A parameter stores the drawing context in a parameter dc so for the documentation, I have simply set the parameter dc to a drawing context for a bitmap. The frame and canvas are never shown while generating the documentation.


soegaard2
2021-7-8 12:19:03

I’ll need to think about a way around this. Maybe introducing a #lang sketching-doc similar to #lang sketching but without any setup of the frame and canvas.


greg
2021-7-8 13:05:18

Dumb question: If docs shouldn’t instantiate racket/gui/base, how does something like “Quick: An Introduction to Racket with Pictures” https://docs.racket-lang.org/quick/index.html work?


greg
2021-7-8 13:10:39

From looking at the source it seems to use https://docs.racket-lang.org/scriblib/gui-eval.html


greg
2021-7-8 13:19:56

I may need more coffee, but I think the idea here is that you would set an env var and run the doc build locally, where you do have the GUI, to generate image files? And then those image files are used when building docs elsewhere (on the build server, on user machines, etc.)? I think???


shu--hung
2021-7-8 13:36:04

pict and racket/draw, IIUC, specifically avoided GUI dependency


shu--hung
2021-7-8 13:42:26

Ah, I think you are right. I don’t see the output of mr-interaction-eval on the website.


greg
2021-7-8 15:03:07

No actually you’re right. racket/draw (and pict, which requires racket/draw) do not require racket/gui/base.

They do require racket/gui/dynamic, but that’s a different beast: It’s part of base not gui-lib, and it’s used to dynamically require things from racket/gui/base.


ben.knoble
2021-7-8 19:16:53

Is the location of info.rkt a reliable project-root for Racket projects? I know not every project is a package (case in point, my own slack archive viewer lacks such a file). I’m hoping to add racket-langserver support to ALE, but I have to give it a way to find the project-root. (I would probably fallback to pwd if no info.rkt is found, but if there are alternatives…)


mflatt
2021-7-8 19:25:55

Some collections have “info.rkt” files in subcollections, but it’s maybe not so common, and I think the information always could be lifted to a top-collection “info.rkt”. It’s fairly common for a project to have multiple collections and “info.rkt” files in the collections, though, and that information typically cannot be lifted to the package level. I guess it depends on what notion you need for “project”.


mflatt
2021-7-8 19:26:34

It might make sense to look for a specific “info.rkt” field to mean “this is the root of a project”.


ben.knoble
2021-7-8 19:28:16

To be completely honest, racket-langserver uses a lot of DrRacket under the hood, which seems to be pretty “individual files” right now, so I’m not terribly worried. I’m not sure I understand what impact the project root has, though it seems to be the location of where the lsp should start running. I’m thinking this will be a best approximation until something breaks :slightly_smiling_face:


kyp0717
2021-7-8 21:35:33

Please help me understand continuation. Trying to work through this example …https://danielfm.me/post/why-are-continuations-cool/ .


kyp0717
2021-7-8 21:36:15

The example that Daniel provided is … #lang racket/base ;; Object to keep the session-id across requests (struct session [id #:mutable]) (define (perform-request! session method params) ;; Performs the request (define headers (session-id-headers session)) (define response (http-request API-URL headers method params)) ;; Retries the request with the given Session-Id ;; if necessary (when (request-denied? response) (update-session-id! session response) (perform-request! session method params)) (parse-json response))


kyp0717
2021-7-8 21:37:00

As he had noted, this code works but it is “broken”. Here is his explanation … The recursive call is not made in tail position. So, when it happens, another stack frame is pushed to the call stack and even though the retried request succeeds, what gets returned to the caller is the response to that first unauthorized request.


kyp0717
2021-7-8 21:42:01

So I don’t quite understand why this code is not good? I am guessing that this is bad because the recursive call will create 2 stack frames and 2nd frame is what gets the updated session-id . The updated session-id is NOT propagated to it the parent stack frame. So that is why this code is broken. Am I correct?


claiborn
2021-7-8 22:19:19

The point is that the parse-json is getting called on the response from the failed session and that’s what’s getting returned to the caller, whereas the correct response is parsed in the upper frame, then discarded upon return from perform-request!.


claiborn
2021-7-8 22:20:01

There’s also the fact that the recursion is not in tail position, which means that you miss any tail recursion optimization, but for this specific case that doesn’t matter much.


claiborn
2021-7-8 22:22:04

The ideal situation is that the correct response is returned to the user and that the errored response is swallowed. Haven’t read the article, but I don’t think I’d reach for continuations to solve this specific problem.


kyp0717
2021-7-8 22:35:19

Thanks. This help me understand it now!


dan.ml.901
2021-7-8 22:38:16

Is there a bug in raco make where if you give it a large number of files and pass in -j <num> high enough it will encounter a race condition? We’re getting a case of raco make exiting with STATUS_HEAP_CORRUPTION intermittently.


dan.ml.901
2021-7-8 22:38:47

We give it about 138 files to precompile.


dan.ml.901
2021-7-8 22:39:13

Is there a more reliable way to precompile a large number of files?


dan.ml.901
2021-7-8 22:48:16

@ben.knoble are you working on the Racket LSP?


ben.knoble
2021-7-8 22:48:47

Not working on it so much as trying to integrate with a vim plugin (ALE). I opened a PR for it.


mflatt
2021-7-8 22:50:35

How large of a number do you supply with -j? Also 138?


dan.ml.901
2021-7-8 22:57:41

no, just 8


mflatt
2021-7-9 01:15:19

And this is v8.1 (CS)? It’s not a bug that I’ve seen, but if it’s something that I could try on my machine, I’m interested to investigate more.

Meanwhile, a possible workaround is to change “pkgs/compiler-lib/compiler/commands/make.rkt” to add use-places? #f as an argument to parallel-compile-files.