laurent.orseau
2020-6-22 12:05:55

Is there a way to create a read-only text% ? (I thought I’d done this already, but I can’t seem to find out how.)


soegaard2
2020-6-22 12:36:02

Did you subclass text% and bind “edit” functions to do-nothing?


spdegabrielle
2020-6-22 12:42:47

Maybe this - though I have to admit I haven’t used it. > > 4.5 In-Source Documentation > The https://docs.racket-lang.org/scribble/srcdoc.html#%28mod-path._scribble%2Fsrcdoc%29\|scribble/srcdoc and https://docs.racket-lang.org/scribble/srcdoc.html#%28mod-path._scribble%2Fextract%29\|scribble/extract libraries support writing documentation within the documented code along with an export contract, similar to using JavaDoc. With this approach, a single contract specification is used both for the run-time contract and the documentation of an exported binding. https://docs.racket-lang.org/scribble/srcdoc.html


ryanc
2020-6-22 13:12:28

Use the lock method.


laurent.orseau
2020-6-22 13:30:25

Ah, there it is, thanks @ryanc!


mflatt
2020-6-22 14:35:04

You might be able to get local-expand plus parameterize to solve this problem. But I think it’s bad that a macro prints to stderr. Possible solutions include changing lexer to log at 'warning — or to log at 'error but also add a declaration to lexer to suppress the output.


sorawee
2020-6-22 14:47:18

Yep, there’s a PR that does exactly that: https://github.com/racket/parser-tools/pull/6


spdegabrielle
2020-6-22 15:06:23

Any windows user out there ? I think I have a way to extend the ‘Open terminal here’ function in quickscripts-extra library of scripts for DrRacket but I need help testing as I don’t have a windows machine. (code in thread)


spdegabrielle
2020-6-22 15:07:39

This is the code

```#lang racket/base
(require racket/system
         racket/path
         quickscript)

(script-help-string "Open a terminal in the current directory.")

(define-script open-terminal
  #:label "Open terminal"
  #:menu-path ("&Utils")
  #:os-types (unix macosx windows)
  #:output-to message-box

  (case (system-type 'os)
    [(unix) (λ (str #:file f)
              (define dir (path->string (path-only f)))
              (system (string-append "gnome-terminal"
                                     " --working-directory=\"" dir "\""
                                     " -t \"" dir "\""
                                     "&"))
              #f)]
    [(macosx) (λ (str #:file f)
                (define dir (path->string (path-only f)))
                (define osascriptdir (string-append
                                      (path->string (find-system-path 'pref-dir))
                                      "quickscript/user-scripts/"))
                (system (string-append "osascript -e 'tell app \"Terminal\" to do script \"cd \\\"" dir "\\\"\"'" ))
                #f)]
    [(windows) (system (string-append "cmd /c start cmd.exe /K \"cd " dir))]
    ))```

bedeke
2020-6-22 15:18:13

... [(windows) (λ (str #:file f) (define dir (path->string (path-only f))) (system (string-append "cmd /c start cmd.exe /K \"cd " dir)))]


spdegabrielle
2020-6-22 15:19:16

does that work?


bedeke
2020-6-22 15:19:57

I’m not sure yet. I seem to be in the racket program dir, not in the dir of the file


bedeke
2020-6-22 15:20:23

also, afterwards I’m left with an extra (unresponsive) command window


bedeke
2020-6-22 15:21:10

ok, at least it figures out the right directory for something else than the script itself


laurent.orseau
2020-6-22 15:24:33

Maybe use shell-execute for windows (only) instead.


bedeke
2020-6-22 15:30:34

(system (string-append "start cmd.exe /K \"cd " dir)) gives the same result (still the extra window…)


anything
2020-6-22 15:30:40

I’m a web server. I serve multiple clients. Each client is identified by an integer. Clients consume a database that changes once every hour. I want to save in memory the database I read off the disk. Each client has a different database, so I must memorize them all. (Few clients, though, and I know how many there are. The clients are not web users. The clients are Javascript-based web applications.)

I thought of keeping a hash table in memory where each pair is indexed by the client-id-integer. But I just read on the https://docs.racket-lang.org/reference/hashtables.html#%28elem._%28caveat._concurrency%29%29\|documentation that…

> if a thread is terminated while applying https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._hash-ref%29%29\|hash-refhttps://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._hash-ref-key%29%29\|hash-ref-keyhttps://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._hash-set%21%29%29\|hash-set!https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._hash-remove%21%29%29\|hash-remove!https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._hash-ref%21%29%29\|hash-ref!, or https://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28lib._racket%2Fprivate%2Fmore-scheme..rkt%29._hash-update%21%29%29\|hash-update! […, then] all current and future operations on the hash table may block indefinitely. Each web request is served by a different thread (as far as I know). (I’m using web-server/servlet.) So I think I can’t correctly use a hash table as a solution here. Then I have no idea what to do. How do you guys handle this?


samth
2020-6-22 15:32:11

@anything you shouldn’t have threads being terminated in that situation


samth
2020-6-22 15:33:59

threads are terminated with kill-thread — don’t use that and you should be ok


anything
2020-6-22 15:34:27

That’s excellent news! Thank you! (I suddenly feel much better.)


samth
2020-6-22 15:34:52

thread termination is an abrupt operation that is mostly not needed


bedeke
2020-6-22 15:35:48

yes, with shell-execute there is no extra window: [(windows) (λ (str #:file f) (define dir (path->string (path-only f))) ;(system (string-append "start cmd.exe /K \"cd " dir)) (shell-execute #f "cmd.exe" "" dir 'sw_shownormal))]


jaz
2020-6-22 15:36:10

I got the impression that the issue is not so much about threads being killed but rather about them running to completion and stopping normally.


laurent.orseau
2020-6-22 15:37:04

and it opens correctly in dir?


samth
2020-6-22 15:37:38

no, if that happens they will release the lock


bedeke
2020-6-22 15:37:47

yes


samth
2020-6-22 15:37:56

because they will have (by definition) finished doing hash-ref


jaz
2020-6-22 15:38:18

Right, but I got the impression that the cache was supposed to be independent of the request cycle altogether.


spdegabrielle
2020-6-22 15:38:24

cleaned up version


spdegabrielle
2020-6-22 15:38:32

#lang racket/base (require racket/system racket/path quickscript) (script-help-string "Open a terminal in the current directory (linux and macosx only).") (define-script open-terminal #:label "Open terminal here" #:menu-path ("&Utils") #:os-types (unix macosx) #:output-to message-box (case (system-type 'os) [(unix) (λ (str #:file f) (define dir (path->string (path-only f))) (system (string-append "gnome-terminal" " --working-directory=\"" dir "\"" " -t \"" dir "\"" "&")) #f)] [(macosx) (λ (str #:file f) (define dir (path->string (path-only f))) (system (string-append "osascript -e 'tell app \"Terminal\" to do script \"cd \\\"" dir "\\\"\"'" )) #f)] [(windows) (λ (str #:file f) (define dir (path->string (path-only f))) ;(system (string-append "start cmd.exe /K \"cd " dir)) (shell-execute #f "cmd.exe" "" dir 'sw_shownormal))]))


jaz
2020-6-22 15:38:53

I mean: if, for a period of say 10 minutes, there are no requests, that doesn’t mean you want to drop the cache on the floor, right @anything?


laurent.orseau
2020-6-22 15:39:20

(remove the dead code maybe, and update the help-string before submitting)


jaz
2020-6-22 15:39:22

(But maybe I misunderstood.)


spdegabrielle
2020-6-22 15:39:34

doing now


spdegabrielle
2020-6-22 15:39:46

thank you @bedeke


anything
2020-6-22 15:39:59

Yes, I will never drop the cache. (Though every hour I will update all buckets.)


jaz
2020-6-22 15:41:13

Right, so you don’t want its reachability to be based on any particular request.


anything
2020-6-22 15:41:34

What do you mean by “reachability”?


jaz
2020-6-22 15:41:58

In terms of garbage collection, I mean.


anything
2020-6-22 15:42:41

Yes, there should be no garbage collection. The hash table (that is, the cache) will be held in the web-server’s main thread to be consumed by all threads serving web users. (I plan to use a https://docs.racket-lang.org/reference/boxes.html\|box for that. That is, the hash table will be kept in a box in the web server’s main thread.)


jaz
2020-6-22 15:43:17

You know — I think I did misunderstand.


jaz
2020-6-22 15:43:49

I thought you were suggesting that the cache would be established (and kept reachable) by request threads, but that’s not what you’re proposing, so you’re good.


jaz
2020-6-22 15:43:51

:slightly_smiling_face:


anything
2020-6-22 15:44:59

Alright. I confess I did not quite see what you were seeing. (I’m a newbie here, so you might see a thousand things ahead of me.)


idel_martinez
2020-6-22 15:47:51

@idel_martinez has joined the channel


badkins
2020-6-22 15:53:32

@anything have you definitely found the cache is necessary? If it’s mainly just a copy of the database information, you may find the database handles the caching well enough.


badkins
2020-6-22 15:56:05

anything
2020-6-22 15:56:42

My database is sqlite and I think I can speed things up considerably by saving a JSON string and not compute jsexpr->string at every request. I will compare the times and be sure of the improvement when I’m done. (This is an experiment.) Each client consumes its entire set of records so that Javascript can let the web users do the filtering, paging et cetera. Each string ends up being around 721KiB.


anything
2020-6-22 15:57:30

On first look it seems memcached is what I’m going to implement here. :slightly_smiling_face:


badkins
2020-6-22 15:58:47

You could compute the JSON string once per hour when the data changes, and store the JSON string in a text column in the database. And advantage of this approach (or memcached) is the ability to have multiple web server processes, e.g. one per core, w/o duplicating all of the data in each process.


anything
2020-6-22 15:59:40

You know, you’re totally right! (That’s what I’ll do. Thanks for this great idea.) My “hash table” will just be another little table in the database and the whole thing is simplified. That’s perfect.


popa.bogdanp
2020-6-22 16:02:14

If you’re going for performance, two things to watch out for:

• the SQLite adapter is implemented using the FFI so calling an SQLite function will block Racket’s event loop (meaning that if you have a long-running query, no other requests will be served during that time); to get around this pass #:use-place #t to to have it run the SQLite functions in a separate place (OS thread) — this will slow down really fast queries, but it’ll have the effect that slow queries can’t affect the performance of the whole server • make sure you set content-length headers on your responses, otherwise the server will use chunked transfer encoding.


anything
2020-6-22 16:03:50

Very interesting information. I suppose the Racket web server (web-server/servlet) sets the content-length automatically? I will check this.


badkins
2020-6-22 16:04:00

Good to know @popa.bogdanp - I presume this is not the case for postgres, I think the db package uses native wire protocol for that, right?


popa.bogdanp
2020-6-22 16:04:26

@anything it does not. You have to set it yourself if you want to avoid chunked-transfer encoding.


popa.bogdanp
2020-6-22 16:04:38

@badkins yes, the postgres adapter is implemented in pure Racket so it doesn’t have this problem.


anything
2020-6-22 16:04:58

Thanks! This could in fact be the performance issue I’d like to optimize. I will check this first.


badkins
2020-6-22 16:07:36

@popa.bogdanp just out of curiosity, is chunked encoding necessarily a problem? Wouldn’t it allow the writing of the response to be done concurrently with the web server outputting it to the client?


badkins
2020-6-22 16:07:58

Particularly with large JSON strings as in Any’s case?


badkins
2020-6-22 16:08:26

I suppose it’s easy enough to just try it both ways.


popa.bogdanp
2020-6-22 16:08:41

For most applications it isn’t, and it’s definitely something I’d measure, but it is for sure slower because of all the extra buffering it entails.


popa.bogdanp
2020-6-22 16:11:04

When I was looking at the TechEmpower benchmarks throughput using chunked encoding was about half that of just writing the data to the client immediately. (in the JSON and plaintext benchmarks)


anything
2020-6-22 16:12:00

So that benchmark isn’t quite accurate for the Racket Web Server then? (I mean it seems about half-inaccurate.)


popa.bogdanp
2020-6-22 16:12:24

I’ve made some updates to it in the past few weeks so the next round will be more accurate.


anything
2020-6-22 16:12:40

Oh, are you the one doing that benchmark?


anything
2020-6-22 16:12:48

Cool.


popa.bogdanp
2020-6-22 16:13:14

Here’s a thread on racket-users about it and the current limitations: https://groups.google.com/g/racket-users/c/fHsM4kQb22c/m/rdF9cQJamNEJ


badkins
2020-6-22 19:20:47

Looks like Apple’s switch to ARM processors <https://www.theverge.com/2020/6/22/21295475/apple-mac-processors-arm-silicon-chips-wwdc–2020|is official>


badkins
2020-6-22 19:23:43

I recall some discussion recently, but I don’t recall any specific consequences of this for Racket. I remember running Racket on my Raspberry Pi just fine, but that’s a 32-bit ARM. Does Racket BC run on 64-bit ARM currently, but Chez Scheme still needs to be ported to ARM for Racket CS ?


samth
2020-6-22 19:24:36

I believe that’s correct


badkins
2020-6-22 19:26:14

Time to go out and get your 16" macbook pros before they switch :slightly_smiling_face: I’m fairly satisfied with mine from a hardware perspective, but MacOS Catalina has a fair number of issues :disappointed:


spdegabrielle
2020-6-22 20:29:51

Time to go out and get a top-of-the line raspberry pi4 (64 bit arm?)


mflatt
2020-6-22 21:26:44

Others have stepped up for an Arm 64 port, but my Pi 4 arrives in a couple of days. I expect the improved hardware will make it nicer to fill in the remaining piece for 32-bit Arm Racket CS (which is thread support to enable places + futures).