Fork me on GitHub
#beginners
<
2017-08-31
>
thott01:08:42

hey folks, could anyone point me at how to make lein repl start up with a particular version of clojure from a non-project directory? I think the place to set this may be ~/.lein/profiles.clj ... I know I can specify that a project use a particular version of clojure by setting :dependencies in its project.clj but I haven't found docs that tell me how to do this when running lein repl

donyorm01:08:27

@thott not sure myself, but if you don't get an answer here consider asking in #leiningen

Chris Bidler01:08:53

I haven’t done that with lein, but I know that for boot that is exactly the approach you take - you can set the Clojure version in boot.properties and the version of that file in ~/.boot is respected if there isn’t one in .

Chris Bidler01:08:58

you can probably also learn by experiment - throw [org.clojure/clojure "1.5.2"] in the :dependencies map of ~/.lein/profiles.clj and see what blows up! 😄

thott02:08:15

Thanks @donyorm @chris_johnson .. I've tried adding :dependencies [[org.clojre/clojure "1.9.0-alpha17"]] to both the :user and the top-level entry in my ~/.lein/profiles.clj. I'll ask the folks in #leiningen and report back !

juanjo.lenero02:08:33

How would I go about starting another process alongside my clojure api backend to constantly process another job?

juanjo.lenero02:08:16

Say I want another process that constantly reads messages out of an external queue and places them in the database

seancorfield02:08:53

Do you mean a background thread that runs while you main process is also running? (i.e., shuts down when your main process shuts down)

juanjo.lenero02:08:09

Not necessarily, they can be independent.

juanjo.lenero02:08:18

I guess that would mean I could just start two separate clojure programs?

juanjo.lenero02:08:42

But I would like to keep this worker in the same codebase for simplicity’s sake.

juanjo.lenero02:08:23

In elixir I would just start a separate gen-server alongside the main application if anyone’s familiar with that.

juanjo.lenero02:08:14

I understand that in a single core processor my worker thread will steal attention from the backend app.

juanjo.lenero02:08:32

I just need it to play nice, i.e. don’t hold the whole processor to itself

seancorfield02:08:50

You can start a -main in any namespace in your code so you can have multiple processes in one code base.

juanjo.lenero02:08:49

So I could just have another worker.clj file and somehow instruct lein to start it alongside core.clj?

seancorfield02:08:55

java -jar path/to/uberjar.jar -m my.main.namespace

seancorfield02:08:23

I don't use lein but I suspect you can tell it which namespace to run the -main in...

noisesmith02:08:46

you can also just put your worker in eg. a future, you just have to negotiate it exiting properly when you need to exit

seancorfield02:08:06

lein run -m my.main.namespace apparently 🙂

seancorfield02:08:38

you can even tell it to run a function that isn't -main: lein run -m my.main.namespace/different-function

juanjo.lenero02:08:04

Great, I’ll dig deeper with that lead, thanks!

juanjo.lenero02:08:37

@noisesmith I guess in this case, since its independent of the backend thread I would rather not launch it from a future in said backend app.

juanjo.lenero02:08:42

But I’ll keep that in mind

noisesmith02:08:58

I've never even thought to consider my clojure process as a single thread

noisesmith02:08:33

I don't see the advantage of loading up the memory and context switching overheads of two clojure jvms on one machine personally

noisesmith02:08:47

anyway, if the job needs to be scheduled, you can look at ScheduledThreadPoolExecutor or a wrapper on that like At-At

juanjo.lenero02:08:13

I hadn’t thought about that

juanjo.lenero02:08:35

It’s a toy project to familiarize myself with clojure and deploy something

juanjo.lenero02:08:54

I’ll have a worker that reads messages of a website and stores them in a pg database.

noisesmith02:08:04

or, I guess to be realistic, I see the stability benefit of a separate process (in the abstract) but in practice for me clojure is so stable I don't see that as worth the other tradeoffs

noisesmith02:08:14

I have clojure processes that stay running for months

juanjo.lenero02:08:15

An a web frontend/backend that allows you to receive notifications when a keyword appears in said messages.

juanjo.lenero02:08:24

i.e. A user will be able to specify keywords like lisp, clojure, racket and the backend will notify the user when a message with said keyword is found

noisesmith02:08:33

so a small pub/sub

noisesmith02:08:42

cool - check out sente for websockets

noisesmith02:08:53

you can do all of that in one server, no need to explicitly manage a separate thread

noisesmith02:08:09

just send messages to the socket connection objects that care about them, when they are relevant

noisesmith02:08:09

under the hood the web server will use a thread pool and maybe an async dispatch model on top of that, you shouldn't need to worry about managing those threads by hand at a scale below hundreds of clients

noisesmith02:08:00

so one way to do it is sente, upgrade connections to websocket, then use sente's collection of open sockets plus some in memory tracking to figure out where to send messages as they show up

noisesmith02:08:08

but there are other options of course

juanjo.lenero02:08:39

That sounds great, I think I’ll do that for a second iteration, to get familiar with websockets.

noisesmith02:08:30

even without the sockets, the http server should be able to manage all the threads you need for that on its own without you needing to do much

juanjo.lenero02:08:35

For now though, I just want to store a couple days worth of messages from a website in the database, run a cron job that queries said messages for the keywords and stores matches for the user

juanjo.lenero02:08:55

so then the user can log in and see a summary of the matches for his interests

noisesmith02:08:26

ScheduledThreadPoolExecutor is very easy to set up for that (at first I thought you meant the messages would also come in via the same webserver maybe from other clients)

juanjo.lenero02:08:39

I’m pulling messages constantly from hacker news api so I thought that would interfere with the webserver

juanjo.lenero02:08:47

I come from nodejs 😅

noisesmith02:08:59

no, clojure uses actual real threads

noisesmith02:08:08

as long as the threads are in the hundreds to thousands, not thousands to tens of thousands, you are not going to need to worry too much about the mechanics of thread usage (unless you opt into an async model like core.async, but that's optional)

juanjo.lenero02:08:33

Alright, good to know

juanjo.lenero02:08:38

Thanks I’ll get coding

maja14:08:40

Hi all! Does anyone have a good way to ‘mock’ out a http function in a clojurescript test? I tried using with-redefs, but it doesn’t seem to work inside an async go macro.. I just want to replace the http response with a map containing test values. Am I going at this the wrong way?

donaldball14:08:08

I try to put my side-effecty fns behind a protocol and use a different impl for isolated tests

maja14:08:16

@donaldball thanks, I'll look into that 😊

deg22:08:37

I'm failing to deploy a project to Heroku that runs fine locally. I've got too many moving pieces, and I'm not sure how to tackle debugging. It's not actually a Heroku problem. I can see problems even with a local lein run. I'm pretty sure that the problem is in project.clj. Or, in reality, in one of my project.clj files. The project includes two new libraries of mine too. The most obvious first error is that I get:

$ lein uberjar
Picked up _JAVA_OPTIONS: -Xmx2g
Compiling ClojureScript...
WARNING: no :cljsbuild entry found in project definition.
--------------------------------------------------------------------------------
WARNING: your :cljsbuild configuration is in a deprecated format.  It has been
automatically converted it to the new format, which will be printed below.
It is recommended that you update your :cljsbuild configuration ASAP.
--------------------------------------------------------------------------------
:cljsbuild
{:builds []}
--------------------------------------------------------------------------------
I don't know what this is trying to tell me. The main project is https://github.com/deg/trilystro/blob/master/project.clj, and sure seems to have a cljsbuild. The two suspicious library projects are sodium and re-frame-firebase. Or, though less likely, re-frame-storage-fx. Less likely, because I've used that in other deployed projects. Links: https://github.com/deg/sodium/blob/master/project.clj, https://github.com/deg/re-frame-firebase/blob/master/project.clj, and https://github.com/deg/re-frame-storage-fx I'm truly sorry to be dumping this mess on the channel, but I'm tired and frustrated. Any help much appreciated.

eggsyntax22:08:21

@deg IIRC, those warnings don’t necessarily mean that there’s any sort of blocking problem with your project. Does seem like it would be a good call to fix those first, though. This page has a description and some good examples of what your :cljsbuild should look like: https://github.com/emezeske/lein-cljsbuild

eggsyntax22:08:02

It wouldn’t shock me if Heroku was being stricter than lein is locally, and insisting on a valid :cljsbuild.

eggsyntax22:08:27

Oh, I see the link to yours now, I’ll see if anything jumps out at me, although it’s been a while since I’ve written one.

deg22:08:59

Thanks, I know that page. My project does work under dev/figwheel/etc. The error is not being caused by Heroku. I also get it locally, with a simple lein run. It looks like it is not including my clojurescript code. I started each of the libraries with different templates (mies and re-frame-template) and I don't even know where my problem is. (and it is nearly 2am here; not helping my mood much. 😞 )

eggsyntax22:08:59

Right, I get that the error isn’t caused by Heroku — just thinking that while lein locally is autoconverting the invalid data, Heroku might be being stricter & refusing to autoconvert, & hence not deploying.

eggsyntax22:08:21

Caveat: I’ve never deployed a clj/s project to Heroku, so that’s pure guesswork.

deg22:08:01

Nope, I had hoped that, which is why I tried the local test. But the local fails.... it does start the server, but when I load the web page, my main namespace is not found.

Chris Bidler22:08:14

So I haven’t used lein cljsbuild in anger, and therefore this might be garbage, but when I compare your project.clj and the one here: https://github.com/emezeske/lein-cljsbuild/blob/1.1.7/example-projects/advanced/project.clj

deg22:08:16

And, no other errors or warnings.

Chris Bidler22:08:29

I notice that yours is shaped like this:

Chris Bidler22:08:16

:builds { [ {:id "an id" ...} ... ] }

Chris Bidler22:08:49

and the example is shaped differently: :builds { :id { ... } }

Chris Bidler22:08:36

and that difference might be causative of the project compiler complaining about “legacy format” and “here make this empty map instead”

Chris Bidler22:08:15

but the example could be out of date too, like I said, I haven’t used lein cljsbuild, just trying to help apply more eyes

deg22:08:26

Hmm, you are right. I'll try changing that. But, I think this may be a red herring. Mine was generated by the re-frame-template template.

deg22:08:36

Oh, actually, almost certainly a red herring. I forgot to mention one key clue: I tried running an early commit of my project, and it did work. It already had the the template-generated project.clj, but did not have my dependencies.

eggsyntax22:08:16

I also notice that neither re-frame-firebase nor re-frame-storage-fx has a :cljsbuild in its project.clj. I’m not entirely certain that you cause problems, but it might be worth checking. Possibly you started those with clj-only templates?

deg22:08:36

So, I think the problem lies in one of my libraries. Each of them has its own wonkiness --- one comes from Mies, which is beautiful and simple, but uses Dave Nolen's hand-crafted tools that don't use cljsbuild.

deg22:08:18

The other (Sodium) has cljsbuild, but seems to be missing the production build. I forget which template that came from.... one sec....

eggsyntax22:08:19

My 1st instinct would be to start by making a trivial new project & try adding deps for one of those libs & requiring & using it, and then for the other, and at each step verify that you can still build & deploy.

eggsyntax22:08:47

(ie still build/deploy the trivial containing project)

deg22:08:15

But, I'm going to wait until after a night's sleep. I'm running on fumes now, which is the major reason I vented here.

eggsyntax22:08:41

I hear that. Good for you recognizing it; I always have a really hard time stopping when I’m frustrated/exhausted 🙂

deg22:08:58

Hmm, just tired enough to chuckle hysterically at the mixed metaphor of fumes and venting. I better get some sleep.

deg22:08:02

Thanks for your help!

eggsyntax22:08:11

LOL. Take care 🙂

Chris Bidler22:08:16

You’ll wake up and the answer will leap off the screen and bite you when you sit down to code again.

Chris Bidler22:08:25

that’s how it usually is for me

deg22:08:37

Yeah, I hope so. And it usually is so.

deg23:08:09

The underlying problem here is that I've not found a good template for creating cljs library projects

deg23:08:02

That is: projects that are only intended to be included in other cljs projects, yet still have some real complexity like macros and .cljc.

deg23:08:34

And, of course, the usual dreadfulness of Clojure error messages.

deg23:08:50

anyway, good night and thanks