Fork me on GitHub
#babashka
<
2023-12-06
>
agorgl07:12:46

Hello all! Its been a while since I worked on my last bb script, and I noticed that bb nrepl-server takes a while to start (about 7 seconds). Was it always so slow? I am pretty sure that in the past this started instantly

agorgl08:12:31

It seems that it was a DNS/hosts problem, as I was using bb nrepl-server localhost:4444 and for some reason it takes too long to resolve localhost (I did not have it in /etc/hosts)

πŸ‘ 1
borkdude11:12:24

this seems to be happening to more people lately. it is a new trend to not have localhost in /etc/hosts?

agorgl12:12:28

I really don't know, and the funny thing is that everything else that i tried to reproduce this (listening with netcat or smth) just fires up instantly

agorgl12:12:05

I would really want to know what bb uses to resolve localhost and is so slow

agorgl12:12:25

I seem to be able to reliably reproduce this in a container doing this:

# Run any simple container
podman run --name debian-stable -it --rm debian:bookworm
then
> apt update && apt install vim curl
> curl -L -O 
> tar xzvf babashka-1.3.186-linux-amd64-static.tar.gz
> ./bb nrepl-server localhost:4444 # Starts instantly
> edit /etc/hosts and comment out localhost entry
> edit /etc/resolv.conf and comment out nameservers
> bb nrepl-server localhost:4444 # Slow start

agorgl12:12:49

None of the other programs have problem resolving localhost though, even instantly Tried dig, nslookup, netcat

borkdude12:12:04

what other programs

borkdude12:12:25

I told you, it's (.InetAddress/getByName host)

πŸ‘ 1
agorgl12:12:55

I'll do some digging to see how java's InetAddress handles this below

agorgl12:12:04

I kinda found out the cause, commenting in case anybody searches for the solution: If on a linux system where the localhost entry in /etc/hosts is missing (It really shouldn't) and you are using systemd-networkd that adds a search . option in /etc/resolv.conf then resolving localhost is gonna be slow for java, I really don't know how java handles the search option

borkdude12:12:41

maybe check the openjdk implementation

agorgl12:12:30

although bb compiles from graalvm, is this openjdk behind the scenes?

borkdude12:12:50

graalvm is based on openjdk, they don't re-implement everything

borkdude12:12:14

although some things could be different / overriden for native-image. you can also check graalvm itself, it's open source

borkdude12:12:34

can you also try (http://java.net.InetAddress/getLocalHost)`

agorgl12:12:09

Nice poc! I'm reproducing the slowness using

❯ bb -e '(java.net.InetAddress/getByName "localhost")'
#object[java.net.Inet4Address 0x2a35a328 "localhost/127.0.0.1"]
and for some reason (.InetAddress/getLocalHost) tries to resolve my computer name?

agorgl12:12:47

In any way this is not babashka related, no need to respond to these anymore, it just triggered my curiosity

Nundrum19:12:48

πŸ˜„ 2
😜 1
johanmynhardt17:12:05

Hello's again! I have another weird behaviour. But I admit the problem could be between the keyboard and the chair. This is still with my MySQL migration "adventure" where I'm playing whack-a-mole, and I don't know if it's a babashka issue or not. Summary is that I'm threading a collection of name-spaced maps and at the particular spot I'm having an issue, I'm using partial application. Code coming in the thread, please hold:

βœ… 1
johanmynhardt17:12:26

The function below is the one getting partially applied. The problem is with :TRIGGERS/trigger-ddl. When I attempt to destructure using {:TRIGGERS/keys [... trigger-ddl]} or {trigger-ddl :TRIGGERS/trigger-ddl :as trigger} the pre-condition in (assert trigger-ddl) fails, however, if I retrieve using (:TRIGGERS/trigger-ddl trigger) it's all happy.

(defn trigger-attach-redef
  "Attaches redefinition statement to trigger metadata."
  [execution-id
   {:TRIGGERS/keys [TRIGGER_SCHEMA TRIGGER_NAME trigger-ddl]
    :as trigger}]
  {:pre [(assert trigger-ddl)]}
  (let [tool-ns (str *ns*)]
    (assoc trigger :migration/redef
           (->> ["/* {{tool-ns}}: TRIGGER Redef: {{TRIGGER_SCHEMA}}.{{TRIGGER_NAME}} */"
                 "DROP TRIGGER IF EXISTS `{{TRIGGER_SCHEMA}}`.`{{TRIGGER_NAME}}`;"
                 "DELIMITER $$"
                 "$$"
                 "{{trigger-ddl|safe}}"
                 "$$"
                 "DELIMITER ;"
                 ""
                 ""]
                (str/join \newline)
                <<))))
At the call site it's relative use/location is:
(->> {fetching collection of maps}
     ,,, ;; populating data used later, sorted map, s
     ,,, ;; fixing string content in a map value
     (map (partial trigger-attach-redef execution-id)) ;; <-- here
     (vec))
I figure it's too generic, and I can move along because I know it works using (:TRIGGERS/trigger-ddl trigger) but I was just curious why I'm observing this. I'm literally doing similar things elsewhere, but not using this same keyword namespace.

mmer17:12:50

just taking a punt - :TRIGGERS/keys [TRIGGER_SCHEMA TRIGGER_NAME trigger-ddl] is what you have - what would happen if you did keys [:TRIGGERS/TRIGGER_SCHEMA :TRIGGERS/TRIGGER_NAME :TRIGGERS/trigger-ddl]`

johanmynhardt17:12:29

😯 One can do that? I've never tried that way before. Let me try. The interesting thing is that I tried it in a clojure repl, same result, so it's really confusing. Will give feedback on this other style in a bit, thank you!

johanmynhardt17:12:36

Negative. I'm dumbfounded. In this following code, I've added a println , the pre-condition check now doesn't have meaning. The code runs and prints out the expected values.

(defn trigger-attach-redef
  "Attaches redefinition statement to trigger metadata."
  [execution-id
   {:keys [:TRIGGERS/TRIGGER_SCHEMA :TRIGGERS/TRIGGER_NAME :TRIGGERS/ddl] :as trigger}]
  (println :execution-id execution-id :trigger-ddl ddl)
  {:pre [(assert ddl)]}
  (let [tool-ns (str *ns*)]
    (assoc trigger :migration/redef
           (->> ["/* {{tool-ns}}: TRIGGER Redef: {{TRIGGER_SCHEMA}}.{{TRIGGER_NAME}} */"
                 "DROP TRIGGER IF EXISTS `{{TRIGGER_SCHEMA}}`.`{{TRIGGER_NAME}}`;"
                 "DELIMITER $$"
                 "$$" "{{ddl|safe}}" "$$"
                 "DELIMITER ;" "" ""]
                (str/join \newline)
                <<))))

(comment

  (->> [{:TRIGGERS/TRIGGER_NAME "foo"
         :TRIGGERS/TRIGGER_SCHEMA "xyz"
         :TRIGGERS/ddl "<<<<<DDL-HERE>>>>>"}]
       (map (partial trigger-attach-redef 123))
       (map pprint)
       (doall))

  (clojure.pprint/pprint
   (trigger-attach-redef
    2345
    {:TRIGGERS/TRIGGER_NAME "foo"
     :TRIGGERS/TRIGGER_SCHEMA "xyz"
     :TRIGGERS/ddl "<<<<<DDL-HERE>>>>>"}))

  #_())

johanmynhardt17:12:28

=>
:execution-id 2345 :trigger-ddl <<<<>>>>
{:TRIGGERS/TRIGGER_NAME "foo",
 :TRIGGERS/TRIGGER_SCHEMA "xyz",
 :TRIGGERS/ddl "<<<<>>>>",
 :migration/redef
 "/* mysql-migration.explore: TRIGGER Redef: xyz.foo * ....
:man-shrugging: Maybe it's telling me I'm working too hard today πŸ˜†

johanmynhardt17:12:06

Thanks for showing me something new today @U4C3ZU6KX πŸ™‡ I couldn't find such an example in the Clojure docs. Unless it's this part:

(let [person {::p/name "Franklin", ::p/age 25}
      {:keys [::p/name ::p/age]} person]
  (println name "is" age))

johanmynhardt18:12:21

This will serve the same purpose and is good enough for my needs.

(defn trigger-attach-redef
  "Attaches redefinition statement to trigger metadata."
  [execution-id
   {:TRIGGERS/keys [TRIGGER_SCHEMA TRIGGER_NAME ddl] :as trigger}]
  (assert ddl)
  (let [tool-ns (str *ns*)]
    (assoc trigger :migration/redef
           (->> ["/* {{tool-ns}}: TRIGGER Redef: {{TRIGGER_SCHEMA}}.{{TRIGGER_NAME}} */"
                 "DROP TRIGGER IF EXISTS `{{TRIGGER_SCHEMA}}`.`{{TRIGGER_NAME}}`;"
                 "DELIMITER $$"
                 "$$" "{{ddl|safe}}" "$$"
                 "DELIMITER ;" "" ""]
                (str/join \newline)
                <<))))

johanmynhardt19:12:09

Think my issue was {:pre [(assert ddl)]}, with {:pre [ddl]} it's πŸ‘Œ

staypufd03:12:47

@U1M0BC7S7 That would make a good example. Maybe you could add a simplified version, for others who may haven’t seen it this way either.