Fork me on GitHub
#babashka
<
2020-12-07
>
borkdude13:12:47

If anyone here is using babashka on the cloud / serverless, you might want to reply here: https://www.reddit.com/r/Clojure/comments/k8fc5s/askreddit_have_you_tried_to_run_babashka_on_a/

mozinator213:12:49

It definitely would be more easy to do than to convert your clojure web app to be graalvm compatible

Aleed16:12:32

with latest Babashka, using babashka.process/process , setting any :env options map is causing command to fail

warnings can be silenced by the --no-warnings (-n) option
Assertion failed: (str1!= NULL), function add3strings, file string_utils.c, line 103.
not sure if I’m doing anything wrong, but only way script is working is by commenting out the env options. even an empty map causes that error

borkdude17:12:12

that doesn't sound good, let me check

borkdude17:12:53

@alidcastano I can't repro that on my machine:

user=> (slurp (:out @(babashka.process/process ["ls"] {:env {"FOO" "BAR"}})))
what is your repro and which OS? latest = 0.2.4?

Aleed17:12:50

hm this works for me, so may be a mix of options I’m passing. testing that out now

borkdude17:12:21

a standalone minimal repro would be most helpful.

Aleed18:12:32

sorry it took a bit, was out for lunch

Aleed18:12:58

i’m on macos btw, bb version 0.2.4

borkdude18:12:55

I can repro now, thanks

borkdude18:12:58

I think it's related to rlwrap perhaps.

borkdude18:12:04

This works:

@(proc/process
 ["clj"]
 {:inherit true
  :env (merge (into {} (System/getenv)) {"FOO" "BAR"})
  :shutdown proc/destroy})

borkdude18:12:59

I can reproduce the problem with this code:

(let [pb
      (java.lang.ProcessBuilder.
       ["clj"])]
  (.clear (.environment pb))
  (.inheritIO pb)
  (let [p (.start pb)]
    (.waitFor p)))
It doesn't matter if you run this with bb or clojure, you get the same error, which I think is coming from rlwrap

borkdude18:12:02

Not sure why though.

borkdude19:12:45

@alidcastano I found out by experimentation that rlwrap apparently expects TERM, HOME and PATH to be set correctly

Aleed19:12:28

hm should those properties be auto-included in env by babashka.process? or you think it’s better for user to explicitly set them?

Aleed19:12:45

thanks for finding source of error, btw.

borkdude19:12:59

This isn't a bb or process specific problem. rlwrap could maybe give better errors when these env vars aren't set

✔️ 3
borkdude19:12:25

Why are you invoking clj and not clojure btw?

borkdude19:12:57

Seems like this should have been fixed with this: https://github.com/hanslub42/rlwrap/pull/80

Aleed19:12:51

> Why are you invoking `clj` and not `clojure` btw? bad habit, i tend to forget difference and end up using shorter version. but error does seem to happen for both commands

borkdude19:12:16

hmyeah, that needs at least PATH and HOME it seems. clojure is a bash script which needs that

borkdude19:12:27

Why not pass through all env vars?

Aleed19:12:50

before using babashka process I was setting env vars like this, btw, which was not causing this error

(defn- set-process-env-vars
  "Set env vars on process builder environment object."
  [pb env-map]
  (let [env-obj (.environment pb)]
   (doseq [[k v] env-map]
     (.put env-obj (-> k name str) v))
    pb))

Aleed19:12:18

> Why not pass through all env vars? did not consider it. was mainly just passing the ones i knew i needed in my program

borkdude19:12:41

ok, we could document this better. So the preferred way when adding things to the current env, would be this:

:env (assoc (into {} (System/getenv)) "FOO" "BAR")

Aleed19:12:28

yep doing something like that now - thanks for helping to track down issue!

borkdude21:12:17

@alidcastano btw, your shutdown hook should be something like proc/destroy or proc/destroy-tree since the hook will receive a map

Aleed23:12:21

ah ok, thanks for catching that

borkdude17:12:00

Also please specify which binary you have downloaded

Michaël Salihi21:12:58

Hi! To patrice, I converting this following bash script: https://gist.github.com/mg6/7321d66ac93d9550322afd8aeec2789a It's still a draft, I want to refactor a little bit. Is it doseq the best candidate for looping and print out in this case? The Babashka version: https://gist.github.com/PrestanceDesign/7d5b8b577932f17660cdaf5b902e409c

borkdude21:12:18

Looks good to me!

Michaël Salihi22:12:56

Ok great, thank you @borkdude ! I'll create a PR to add in BB's examples dir

borkdude22:12:05

Cool. Can you use [skip ci] in your commit message? Then CircleCI won't get triggered. This is good practice when adding docs/examples.

👍 3
borkdude22:12:03

You might also want to do some error handling because on my macOS system the script doesn't work as expected.

borkdude22:12:41

Also a description what the script is for would be nice, since it isn't entirely clear to me who and why this is for

Michaël Salihi22:12:59

Yes, of course. In two words, the script allows you to define which DigitalOcean cloud datacenter (region) had best ping latency to take a server (droplet) on. Little bit, a cli version of this page: https://cloudpingtest.com/digital_ocean

borkdude22:12:31

nice! you could include that in the README

dominicm22:12:54

@borkdude curious what the error is on your machine?

borkdude22:12:24

If you look at the error message returned from clojure shell:

p\nApple specific options (to be specified before mcast-group or host like all options)\n            -b boundif           # bind the socket to the interface\n            -k traffic_class     # set traffic class socket option\n            -K net_service_type  # set traffic class socket options\n            -apple-connect       # call connect(2) in the socket\n            -apple-time          # display current time\n"
" => ms"

dominicm22:12:39

One minor mistake I notice is that it should be (shell/sh "ping" "-c" "5" "-w3" endpoint)

👍 3
dominicm22:12:47

Sounds like maybe -w is a gnuism?

borkdude22:12:55

That doesn't fix it for me:

(defn ping-result [endpoint]
  (let [{:keys [out err]} (shell/sh "ping" "-c" "5" "-w3" endpoint)]
    (prn err)
    (prn (str endpoint " => " (get-average out) "ms"))))

dominicm22:12:42

Right, that's a separate "it's wrong", but the impl of some pings may be lenient to it. (gnu's is)

dominicm22:12:13

@borkdude BSD uses -t instead of -w. See if that works?

dominicm22:12:59

bb ping, cross-platform ping? :P

borkdude22:12:52

#!/usr/bin/env bb

;; explicit requires
(require '[babashka.curl :as curl]
         '[babashka.process :as p]
         '[clojure.string :as str])

(def url "")

(def get-endpoints
  (let [{:keys [body]} (curl/get url)]
    (re-seq #"speedtest\-.+." body)))

(defn get-average [result]
  (-> result
      str/split-lines
      last
      (str/split #"/")
      (get 4)))

(def mac?
  (str/starts-with? (System/getProperty "os.name") "Mac"))

;; TODO: test on Windows
(def timeout-arg (if mac? "-t3" "-w3"))

(defn ping-result [endpoint]
  (let [out (-> (p/process ["ping" "-c" "5" timeout-arg endpoint]
                           {:out :string})
                p/check ;; crash on non-zero exit code with error output
                :out)
        msg (str endpoint " => " (get-average out) "ms")]
    (println msg)))

(doseq [endpoint get-endpoints]
  (ping-result endpoint))

Michaël Salihi09:12:01

Hi @borkdude! I have a question. I saw in your script version that you required explictily babashka.curl and clojure.string. I thought that alias are already present in some of last bb versions, right? Do you recommanded to always manually required?

borkdude09:12:45

Are you using clj-kondo?

borkdude09:12:10

Clj-kondo will give warnings if you use a namespace alias without a prior require.

borkdude09:12:39

This is why I advice to always use explicit requires. I think it is also more readable. The built-in aliases are for command line one-liners. See https://book.babashka.org/#style

Michaël Salihi09:12:58

Yes I use clj-kindo with Flycheck in my Spacemacs conf

borkdude09:12:23

Right, so when adding explicit requires these warnings go away

borkdude09:12:49

The script will work either way, it's just a style thing

Michaël Salihi09:12:26

OK, I understand, thanks! I also prefer when my linting is clean so now I go for the explicit requires 👍

borkdude22:12:10

I can test this on Windows too, but not tonight :)

Michaël Salihi22:12:01

I just tested your updated version (with process) and I had this error

----- Error --------------------------------------------------------------------
Type:     clojure.lang.ExceptionInfo
Message:  
Location: /home/mike/Lab/Clojure/Babashka/digitalocean-ping.clj:25:13

----- Locals -------------------------------------------------------------------
endpoint: ""

borkdude22:12:52

I have removed :err :inherit from the above example, did you copy that?

Michaël Salihi22:12:14

Yes. Same error with the modified version.

borkdude22:12:07

What's the return code of ping when you execute ping from the command line?

borkdude22:12:54

Feel free to change back to clojure shell, this is just a way to trigger an error when there's something suspicious

Michaël Salihi22:12:42

OK I understand. 👍 FYI, the return code is 1

Michaël Salihi22:12:20

I'm on Linux Unbuntu.

borkdude22:12:08

If ping does not receive any reply packets at all it will exit with code 1. If a packet count and deadline are both specified, and fewer than count packets are received by the time the deadline has arrived, it will also exit with code 1. ... Otherwise it exits with code 0.
Maybe that's the case?

Michaël Salihi22:12:21

Thank you for everything and your availability! I'll continue tomorrow.

borkdude22:12:38

Same here. Goodnight.

Michaël Salihi22:12:55

Thx, goodnight. 🙂