Fork me on GitHub

i'm running into a weird issue where the google-cloud-pubsub library works in a standalone application, but when i include the same code in my luminus web application, the program hangs on waiting for the publish request to happen


here's the relevant code (which works fine on its own):


(ns pubsub-test.core
  (:require [ :as log]
            [mount.core :refer [defstate] :as mount])
  (:import ( ServiceOptions)
           ( ProjectTopicName PubsubMessage)
           ( Publisher)
           ( ByteString))

(defn- connect! [{:keys [topic-id]}]
  (-> (ServiceOptions/getDefaultProjectId)
      (ProjectTopicName/of topic-id)

(defstate publisher
  :start (connect! {:topic-id "my-topic"})
  :stop (.shutdown publisher))

(defn publish! [message]
  (let [data (ByteString/copyFromUtf8 message)
        pubsubMessage (-> (PubsubMessage/newBuilder)
                          (.setData data)
    (.publish publisher pubsubMessage)))

(defn -main [& _args]
    (let [message-id (-> (publish! "Hello, World!")
      (log/info "Message ID: " message-id))))


at this point i'm guessing that some executor is failing to run the publish request, but i don't have any hypotheses as to why this would only be an issue in the luminus application


in case anyone is interested i figured out the issue. luminus includes google closure to support clojurescript. both and depend on protobuf-java. unfortunately, they depend on different, incompatible versions

👍 4

You could try overriding the Luminus one.

👍 4

Hi! is there an alternative to core.match that I can use to store patterns to be matched as data and not have to rely on the match macro? To clarify, what I'd like is to have something like this:

(def patterns
  '[[_ 1 2]
    [a b c]
    [a b]
    [_ & tail]])

(let [my-data [0 1 2]]
  (doseq [pattern patterns]
    (println (matches? pattern))))

;; => {:match true :bindings {}}
;; => {:match true :bindings {:a 0 :b 1 :c 2}}
;; => {:match false}
;; => {:match true :bindings {:tail [1 2]}}


store it as code and eval?


you could do it with clojure.spec conform


but difficult to say if it's a good idea or not with the info you give


I have a namespace with a :gen-class (I need to subclass and to be accessible from Java): When I compile this I get 60 .class files, i.e. the gen-class class, a dozen classes corresponding to vars in that namespace, and the rest from clojure.specs.alpha (see gist) what's the right way to distribute this? The generated class relies on some of those vars. can I just distribute the single class file + the clj file?

Alex Miller (Clojure team)14:11:48

no, you need all of those classes

Alex Miller (Clojure team)14:11:16

the ones from that namespace that is

Alex Miller (Clojure team)14:11:56

you don't need the core.specs.alpha ones (those were transitively compiled)


thanks, I'll try that

Alex Miller (Clojure team)14:11:16

the clj file won't be used


I'm getting a bit of a puzzling error. I'm referencing this in logback.xml, and when the process boots I get this

2019-11-14 15:35:08.689 INFO  org.eclipse.jetty.util.log - Logging initialized @62847ms to org.eclipse.jetty.util.log.Slf4jLog
Syntax error (ClassNotFoundException) compiling new at (ring/adapter/jetty.clj:31:3).
When I take it out of logback.xml, start the process, then put it back in and wait for logback to rescan its config, then it works


Compiling namespace with -Dclojure.spec.skip-macros=true does not produce spec classes

Eric Ihli16:11:30

I notice what seems to me to be a disproportionate number of UK/EU to US jobs being posted in #remote-jobs. Anyone have an idea about the reason for that? Does Clojure have a bigger market share, compared to other languages, outside of the U.S.?

Alex Miller (Clojure team)16:11:44

I don't think that's either true or that you can draw that conclusion from posting occurrence


I'm getting back a method for this:

(.getMethod String "contains" (into-array [CharSequence]))
I want to write my own method invocator that looks like:
(defn invokeMethod [^Object obj method args]
  (let [class (.getClass obj)
        method (.getMethod class method (into-array (map #(.getClass ^Object %) args)))]
    (.invoke method obj (into-array args))))
so it just gets all the classes from the args and then tries to find the matching method and invokes it. This doesn't go well with for example: (invokeMethod "foo" "contains" ["o"]) because then it tries to:
(.getMethod String "contains" (into-array [String]))
which doesn't return a method... How to solve this?


(.getClass %) on an argument may return a concrete class more specific than in the signature of the target method


tldr: you can't guess the right method to call in one shot if all you have is arguments


need to enumerate and filter


ok, that's useful information, thanks

Alex Miller (Clojure team)17:11:36

feel free to use the public Reflector methods if you're doing stuff like this

Alex Miller (Clojure team)17:11:25

because calls to that class get embedded in compiled reflective Clojure code, we generally try hard to only grow not break that class so it should be pretty stable

Alex Miller (Clojure team)17:11:45

but I would not consider it "official" public API


nice, that saves me a lot of work 🙂


Does anyone know of any clojure libraries that wrap the java.nio.file.FileSystem stuff? Datoteka claims to have a file storage abstraction; but AFAICT it’s not the java one and doesn’t seem anywhere near as useful or complete.


I'm getting a reflection warning for this:

(defn invoke-static-method #?(:clj [_ctx [[^Class class method-name] & args]]
                              :cljs [_ctx & _args])
     (Reflector/invokeStaticMethod class (str method-name) (into-array args))
     :cljs (throw (js/Error. "Not imlemented yet."))))
Reflection warning, sci/impl/interop.cljc:20:6 - call to static method invokeStaticMethod on clojure.lang.Reflector can't be resolved (argument types: java.lang.Class, java.lang.String, unknown).


^objects (into-array args)


what type hint should be added for the args?


Just a guess: (object-array args)


probably a good guess




Interestingly enough that will work for any object array, so typehinting (into-array String ["1" "2"]) as an object array is legal.


the magic of inheretance


Has anyone tried using the alpha java fiber api with clojure?


they have some methods on fibers that are overloaded to take either a callable or a runnable


so it feels like it will be prudent for std. lib / core.async support


just like with (thread ...)


oh wow, they are doing continuations


it is exciting isn't it


if what they make is meaningfully a continuation, yeah, that seems like a big deal


I think it is technically a delimited continuation, and I am not sure what the exposed api will be, but it sounds like blocking operations in fibers will transparently turn into a callback thing with the current continuation , which is neat


Ron said they'll likely not expose the continuation api at first, but will do in the following releases


it's a full fledged multi-prompt delimited continuation system


it'll be great if it doesn't take 10 years to land


an overview I saw just now mentioned coroutines, which means you could potentially have a core.async rewrite using yield for channel writes and resume for channel reads maybe?


I think I saw @ghadi Had posted a Gist with some Clojure code interacting with fibers?


the degree to which core.async would need a rewrite depends on how transparently they handle it, if the fiber support in the jvm automatically turns blocking things like taking locks in to callbacks with continuations, then core.async doesn't really need rewriting, just use the "blocking" api in fibers and it will come out right


the benefit I imagined is being able to use yield / resume in place of a state machine rewrite while still getting the right semantics, but maybe that's far fetched


if the continuation usage in fibers is entirely transparent, you can get rid of the go macro all together, >!! will behave like >! in fibers and continue to behave as does now outside of fibers


yeah, it would potentially allow eliminating a lot of complexity


@emccue ☝️:skin-tone-2:


Yeah see part of the issue is that type hint won't work


In the preview image


He marks it as ^Runnable, but their API will always use the Callable methods if they are available


So it's a bit of a nightmare


Dep. on your views of API design


that isn't correct


the real issue is you can't type hint fns like that


the executor api has the same thing happen


if you bind the fn to a name and type hint the name everything is fine