2015-10-11
| 03:59 | Seylerius | I'm trying to use org-babel with clojure, and nrepl is returning (when I example *nrepl messages*) "namespace not found" with each attempt to execute something. |
| 04:47 | noncom|2 | why specifying explicit ObjectId in monger upon a document creation is "recommended" ? |
| 04:47 | noncom|2 | (ctrl+f "(recommended)" here http://clojuremongodb.info/articles/getting_started.html ) |
| 04:48 | noncom|2 | ddellacosta: hi! ever worked with monger ? |
| 04:54 | Seylerius | Okay, clj-barcode (a clojure port of barbecue) seems to crash my repl regularly. |
| 06:15 | crocket | Is (go) similar to go's concurrency model? |
| 06:15 | crocket | go-lang |
| 06:26 | Empperi | yes, the basic idea of channels etc was taken from Go as far as I remember |
| 06:31 | crocket | coroutine? |
| 06:31 | crocket | Empperi, ^^ |
| 06:54 | hellofunk | crocket: both go and core.async are implementations of much much older ideas in CSP |
| 07:00 | crocket | hellofunk, What do you mean by go? |
| 07:00 | crocket | There is core.async/go |
| 07:06 | hellofunk | crocket: the go language |
| 07:09 | crocket | I'm not sure if core.async/go is a coroutine. |
| 08:54 | ane | no, but it's CSP |
| 08:55 | ane | just like go channels are CSP |
| 08:58 | sobel | what's the salient diff between csp and coroutines? |
| 09:09 | ane | they're completely different ideas |
| 09:10 | ane | csp is about channels, sharing by communication, coroutines are more or less python's 'yield' keyword |
| 09:10 | jsabeaudry | For people hosting their apps on heroku, where do you host your datomic db? |
| 09:11 | ane | (Go's goroutine's aren't coroutines) |
| 10:42 | luxbock | Pulsar (https://github.com/puniverse/pulsar/) provides coroutines for Clojure |
| 10:43 | luxbock | it uses this: http://www.matthiasmann.de/content/view/24/26/ under the hoods |
| 12:09 | vise890 | hi all. i'm trying to make a small proxy with compojure. when the host i'm redirecting traffic to puts the header "Transfer-encoding=chunked", the browser consuming the proxy hangs. This is what I have: https://github.com/vise890/dropwiki/blob/add_backend_proxy_to_figwheel/frontend/src/frontend/server.clj#L20 |
| 13:49 | ben99 | hello |
| 13:50 | ben99 | I have a ring webapp. running it with lein run works fine, but with the uberjar I get |
| 13:50 | ben99 | Error: A JNI error has occurred, please check your installation and try again |
| 13:50 | ben99 | Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/IFn |
| 13:50 | ben99 | ...Caused by: java.lang.ClassNotFoundException: clojure.lang.IFn |
| 13:51 | rhg135 | is clojure actually on the classpath? |
| 13:52 | ben99 | thx, checking.. does lein find the cp itself? |
| 13:52 | rhg135 | actually... this sounds like the wrong order |
| 13:52 | rhg135 | it does. hmm |
| 13:53 | ben99 | can I use something like trampoline ? |
| 13:53 | ben99 | I basically just want to run the lein project as a daemon, e..g through upstart |
| 13:53 | rhg135 | seems a native dep is getting loaded before clojure |
| 13:53 | ben99 | instead of worrying about jars and cp's |
| 13:54 | ben99 | i.e. I have the git repo on a server and want to run that |
| 13:54 | rhg135 | you'll still have to |
| 13:55 | rhg135 | I'd make an uberjar, and just run that |
| 13:55 | ben99 | yes, that's what I'm trying.. I haven't see this error before |
| 13:56 | rhg135 | neither have I |
| 13:57 | ben99 | perhaps some of the depenencies have JNI |
| 13:57 | ben99 | thx for the help |
| 13:57 | rhg135 | np |
| 14:01 | ben99 | any idea to avoid making jars? |
| 14:01 | ben99 | seems very time consuming |
| 14:04 | rhg135 | It's rather complex, but you can get the classpath from `lein cp` and pass it manually |
| 14:05 | ben99 | ok. because I saw an upstart script which just does exec lein |
| 14:05 | ben99 | not sure whether that's a good idea |
| 14:06 | rhg135 | if it is lein trampoline sure |
| 14:34 | LuckWins | hey |
| 15:55 | Seylerius | So, clj-barcode seems to crash my repl on the regular. |
| 15:55 | Seylerius | I've tried it in Gorilla-REPL, I've tried it in org-babel through nrepl, but it crashes. |
| 15:56 | justin_smith | Seylerius: is it using native code or something? |
| 15:56 | Seylerius | Don't think so. It's a thin wrapper around Barbecue. |
| 15:57 | justin_smith | Seylerius: does "crashes" mean the jvm exits, or just that you get a stack trace and your program is interrupted? |
| 15:59 | justin_smith | ben99 is gone now, but that specific error means he is not using the right jar - when you use the uberjar it creates two jars, one that is only your project, one that is actually uber, and running the one that is just your project gets that error ( rhg135 FYI ) |
| 15:59 | Seylerius | JVM itself goes down. |
| 16:00 | rhg135 | ah, thanks |
| 16:00 | justin_smith | Seylerius: that means either a jvm bug or native code, usually |
| 16:02 | Seylerius | justin_smith: I'll investigate Apache Barbecue, then, because that must be where the native code, if any, lives. |
| 16:06 | justin_smith | Seylerius: here's the pom file for barbecue 1.5-beta1 if that helps - I don't see anything suspicious in the deps list |
| 16:06 | justin_smith | http://central.maven.org/maven2/net/sourceforge/barbecue/barbecue/1.5-beta1/barbecue-1.5-beta1.pom |
| 17:29 | justin_smith | is there a cheaper way to detect if the string created from a given object would be over a certain size? |
| 17:30 | justin_smith | I don't actually care what the string is (the object is in fact being encoded by another library), but if it is above a certain size, I want it to be split and encoded in parts. |
| 17:31 | justin_smith | by "cheaper" I of course mean "cheaper than just generating the (perhaps huge) string" |
| 17:45 | justin_smith | hmm... maybe a walk/post-walk which cumulatively counts the size of leaves as strings returning early if some threshold is crossed... |
| 17:54 | justin_smith | ,(defn small-enough? [limit input] (reduce (fn [total el] (if (> total limit) (reduced false) (+ total (count (str el))))) 0 (remove coll? (tree-seq coll? seq input)))) ; bingo! |
| 17:54 | clojurebot | #'sandbox/small-enough? |
| 17:54 | justin_smith | ,(small-enough? 12 "HELLO, WORLD!") |
| 17:54 | clojurebot | 13 |
| 17:54 | justin_smith | hrm... |
| 17:56 | justin_smith | ,(defn small-enough? [limit input] (reduce (fn [total el] (let [result (+ total (count (pr-str el)))] (if (> result limit) (reduced false) result))) 0 (remove coll? (tree-seq coll? seq input)))) |
| 17:56 | clojurebot | #'sandbox/small-enough? |
| 17:57 | justin_smith | ,(small-enough? 12 "HELLO, WORLD!") |
| 17:57 | clojurebot | false |
| 17:57 | justin_smith | ,(small-enough 12 "HELLO WORLD") |
| 17:57 | clojurebot | #error {\n :cause "Unable to resolve symbol: small-enough in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: small-enough in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol:... |
| 17:57 | justin_smith | ergh |
| 17:57 | justin_smith | ,(small-enough? 12 "HELLO WORLD") |
| 17:57 | clojurebot | false |
| 17:57 | justin_smith | ,(small-enough? 13 "HELLO WORLD") |
| 17:57 | clojurebot | 13 |
| 17:58 | justin_smith | ,(small-enough? 10 {:a 0 :b 1 :c 2 :d 3}) |
| 17:58 | clojurebot | false |
| 17:58 | justin_smith | ,(small-enough? 13 {:a 0 :b 1 :c 2 :d 3}) |
| 17:58 | clojurebot | 12 |
| 18:22 | n3vtelen | I'm new to clojure |
| 18:23 | n3vtelen | I wanna use enlive library |
| 18:23 | n3vtelen | is there a convention how to use it? |
| 18:23 | n3vtelen | I mean clojure libraries |
| 18:24 | ianhedoesit | just add the dependency to lein or boot and use it. is that what you mean? |
| 18:24 | jplur | Anyone know how to config a repl to allow reader conditionals? |
| 18:24 | jplur | as in (read-string {:read-cond :allow} "#?(:clj :foo))") |
| 18:24 | justin_smith | n3vtelen: sure - use a build tool like leiningen or boot to add the dep to your project, then use require to make it accessible in a namespace |
| 18:24 | n3vtelen | thanks |
| 18:25 | justin_smith | jplur: your repl will allow reader conditionals if your clojure is recent enough that they are present - I don't know about that extra hash-map arg, but reader-conditionals in forms for clj / cljs work for me in a 1.7 repl |
| 18:26 | justin_smith | n3vtelen: other conventions for using libraries are to use :require in the ns form, with the :as clause to give the lib a shorthand prefix, and avoiding :use or :refer in most cases |
| 18:28 | pilne | am i strange for liking clojure even more because of nightcode being simple and easy to setup? (: |
| 18:36 | sobel | no, but there's much more to love |
| 18:37 | pilne | i'm hoping so, i come from a functional background, but i've found myself needed to write some java/javascript compatible things, so I'm happy I found clojure (: |
| 18:37 | pilne | a buddy of mine suggested scala first, but i like to do my own googling, scala is a lot nicer than java, but it still felt very object based and alien to my brain lol |
| 18:39 | justin_smith | ~scala |
| 18:39 | clojurebot | scala is http://scalaz.github.io/scalaz/scalaz-2.9.0-1-6.0.1/doc.sxr/scalaz/Kleisli.scala.html |
| 18:40 | pilne | ? |
| 18:40 | neoncontrails | pi1ne: what's nightcode? |
| 18:41 | j-pb | clojure ide written in clojue |
| 18:41 | pilne | it is (so far for me) a quick, light, easy ide, i tried setting up eclipse with java... and coming from a vim or atom and a terminal background... i was more lost than a blind man in the middle of the sahara |
| 18:42 | pilne | eclipse with scala when my buddy recommended it* |
| 18:42 | neoncontrails | Oh cool. By any chance does it have inline evaluation like lighttable does? |
| 18:43 | pilne | i don't see it explicitly stated, but the website is sparse, and nothing I have attempted to learn so far has required it |
| 18:43 | pilne | https://sekao.net/nightcode/ |
| 18:43 | neoncontrails | I don't know of any other editors besides lighttable which implement that feature, which is a little unfortunate because lighttable feels quite beta |
| 18:44 | pilne | i looked at lighttable, and it feels like it could win me away from atom someday, but not quite yet |
| 18:44 | ianhedoesit | light table is more of an alternative for nightcode, not atom, no? |
| 18:44 | justin_smith | it's based on atom-shell and isn't actively developed |
| 18:44 | neoncontrails | It's definitely a great concept and very lightweight compared to IntelliJ, which is what I use 99% of the time |
| 18:44 | Seylerius | justin_smith: I think part of the problem with clj-barcode is that it's using barbecue 1.5-beta. |
| 18:45 | pilne | atom and light table to me feel about the same, highly advanced window-based text editors with great plugin extensibility |
| 18:45 | justin_smith | pilne: yes, light-table uses atom-shell, it's basically a variation on atom in a lot of ways |
| 18:46 | pilne | so, in theory, a plugin could do the inline evaluation in atom? |
| 18:46 | justin_smith | the hard part would be hooking up to the nrepl protocol, after that it should be quite simple |
| 18:47 | neoncontrails | lighttable borrows a few aspects of emacs as well I feel (like lisp-encoded user preferences) which limits the love I have for it |
| 18:53 | pilne | i think what i liked most about clojure (besides that it is a functional lisp dialect) is that it was the only jvm targeting language i found that a) wasn't superbly obscure b) hasn't hammered a giantmegazord IDE down my throat as "the way" |
| 18:55 | neoncontrails | pi1ne: Your b) refers to Scala and Eclipse right? |
| 19:00 | Seylerius | Okay, it's fscking weird. I can require clj-barcode, I can create a barcode with it, but about a minute or two after /saving/ the barcode using clj-barcode's save-to-file function, the JVM dies in a fire. |
| 19:00 | jplur | justin_smith: ah you are right, my repl was using load-string to sanitize the input |
| 19:00 | Seylerius | I've tried saving as both jpeg and png, to no avail. |
| 19:03 | pilne | yes, scala, as well as that "ceylon" thing that redhat is making |
| 19:04 | pilne | does the jvm give any reason for self-conflagrating? |
| 19:05 | pilne | and just reading groovy's description was enough to tell me that it wasn't the path i wanted to explore >.< |
| 19:05 | Seylerius | Yep, there we go. I'd stuck a barcode in a var, waited around a while, did other shit in the repl, then came back and saved the barcode to a file, and it died. |
| 19:05 | Seylerius | Reasons? Let's see... |
| 19:06 | justin_smith | Seylerius: maybe you could turn on core dumps and use gdb to see what the jvm was doing when it died |
| 19:06 | justin_smith | Seylerius: or connect the vm to jvisualvm, turn on tracing, and visualvm should tell you what was happening when it died too |
| 19:09 | pilne | hrm... i think i just found a project to do at some point in the future.... re-write something like "how to design programs" but target clojure, a racket to clojure translation shouldn't be too hard, and that was honestly one of the best book/tutorials i've ever worked with. |
| 19:09 | Seylerius | Here's the error output, as unhelpful as it is: http://sprunge.us/ZYUT |
| 19:10 | Seylerius | justin_smith: I think I will try connecting the JVM up to something. |
| 19:12 | Seylerius | Time to learn visualvm. |
| 19:13 | justin_smith | Seylerius: visualvm is pretty simple - it comes with the jdk, on the left side of the window you get a list of java processes, double click one to connect to it |
| 19:14 | justin_smith | then it has tabs for tracing, metrics, etc. |
| 19:14 | justin_smith | it's a really cool way to figure out what the hell your clojure program is doing sometimes |
| 19:15 | Seylerius | Shiny. |
| 19:16 | Seylerius | Anything in particular I should set it to do other than attach to my jvm before instructing it to DIAF? |
| 19:17 | justin_smith | Seylerius: hmm... you could try to turn on CPU profiling, but sometimes that fails - but if it works that would end up giving you the best info |
| 19:17 | justin_smith | but no matter what visualvm should be able to give you some idea of what was happening when the vm death occured |
| 19:19 | Seylerius | Okay, CPU profiling turned on happily. |
| 19:20 | justin_smith | so yeah, in that case, when it dies visualvm should have very detailed info about what was happening |
| 19:34 | Seylerius | justin_smith: Okay, so I did a thread dump before requiring clj-barcode, after requiring clj-barcode, and after saving the barcode but before the crash. |
| 19:46 | Seylerius | justin_smith: So, it seems that after creating and saving the barcode, an AWT_XAWT thread was launched, and then immediately thereafter a Java2D Disposer. The Disposer sat "WAITING (on object monitor)" for the remainder of the run. |
| 19:47 | justin_smith | Seylerius: interesting - and do you have a vm with all the awt classes (eg. not headless)? |
| 19:47 | Seylerius | Hmm? |
| 19:48 | justin_smith | Seylerius: there are "headless" jvms that don't have the awt classes |
| 19:48 | justin_smith | it's one source of odd behavior I have seen |
| 19:49 | Seylerius | justin_smith: Active JVM: java-8-jdk (oracle) |
| 19:49 | justin_smith | OK, so yeah, that's not a headless jdk |
| 19:49 | justin_smith | was worth checking though |
| 19:50 | Seylerius | Should I try again with coredumps enabled? |
| 19:50 | justin_smith | oh, so you did see the crash, but visualvm didn't tell you what crashed? |
| 19:51 | Seylerius | visualvm didn't seem to do anything special with the crash. |
| 19:51 | justin_smith | did it acknowledge that the vm crashed? |
| 19:51 | Seylerius | Just says "application terminated" |
| 19:52 | justin_smith | interesting |
| 19:52 | Seylerius | Didn't do anything other than quietly note that the vm is no longer running. |
| 19:52 | Seylerius | And stop producing new data. |
| 19:53 | justin_smith | yeah, I would check out if you can find the return value ($? in the shell iirc) and maybe try with core-dumps on so you can use gdb to see what it was doing when it crashed |
| 19:53 | Seylerius | How do I turn on core dumps? |
| 19:53 | justin_smith | Seylerius: what OS? |
| 19:53 | Seylerius | Linux |
| 19:54 | Seylerius | (ArchLinux x64) |
| 19:54 | justin_smith | there's a ulimit that by default has core dumps turned off on most distros |
| 19:54 | justin_smith | so you would set the limit higher than the size of a clojure vm core dump (some huge number I guess lol) |
| 19:55 | justin_smith | Seylerius: http://www.akadia.com/services/ora_enable_core.html |
| 19:57 | Seylerius | Yeah, the JVM's output suggests `ulimit -c unlimited` |
| 19:57 | justin_smith | ulimit core settings are a reminder of a time when running program size was a larger percentage of hard disk size :) |
| 20:23 | pilne | is this tutorial correct in stating that clojure is "not well-suited for high-performance numeric operations. Though it is possible, you have to jump through hoops to achieve performance comparable with Java." https://aphyr.com/posts/301-clojure-from-the-ground-up-welcome |
| 20:24 | justin_smith | pilne: yes, but it should be noted that it is straightforward to code numerically intensive parts of your application in java, and the rest in clojure, and integrate the two |
| 20:25 | justin_smith | pilne: clojure has better host interop than any other language I know of - in fact its usually easier to use java code from clojure than it is from java |
| 20:25 | pilne | sweet, so it is kinda like ocaml or racket in that regard, except it is only meant to bring in java, not "any language(1)" (1) =(if you are willing to write your own bindings) |
| 20:26 | justin_smith | right, there's no "write the bindings" step |
| 20:26 | pilne | i can totally live with the agony of a few lines of java here and there, everyone has at least a little inner masochist right? (: |
| 20:26 | justin_smith | which is why I mention that clojure has better interop (I have done ffi in ocaml and guile) |
| 20:27 | justin_smith | pilne: a cool example of a mixed java / clojure project is pink, which is an audio synthesis engine written mostly in clojure, with a few java classes for the most performance sensitive internals |
| 20:28 | justin_smith | the cool thing about that to me is that unlike most exploritory audio programming environments, you can use a high level language (clojure natch) for the DSP level, not just for plumbing between predefined DSP units |
| 20:28 | pilne | so it can kinda be seen similar to inline compiling in c++ except without the horror of assembly (: |
| 20:29 | justin_smith | compared to supercollider where all DSP code is in c++, or pd, where all DSP code is c, or csound where you can do custom DSP but csound still isn't all that high level :P |
| 20:29 | justin_smith | heh |
| 20:29 | WickedShell | I'm tripping over problems with lein uberjar. It was working but it seems to be related to when I added a second namespace. ie my project was in src/foo (namespaces of foo.core and such)and I've now added src/bar (namespace bar.tools etc) is there anything I need to do to uberjar to make this work? |
| 20:29 | justin_smith | but it's separate files - you still have .java in one file and .clj in another, it's just that the work together nicely |
| 20:29 | justin_smith | WickedShell: what error are you getting? |
| 20:30 | pilne | i think clojure is going to make my somewhat forced to jvm experience, a very plesant one, maybe even a semi permanent change (: |
| 20:30 | WickedShell | justin_smith, it hangs forever after compiling everything in the foo namespace |
| 20:30 | justin_smith | WickedShell: I'd check for top level side effects in the end of foo or in bar |
| 20:30 | WickedShell | or at least on the last file, which is where it includes bar |
| 20:30 | justin_smith | WickedShell: this would include any go loops launched at the top level, any futures, db connections, etc. |
| 20:31 | justin_smith | any of those can make uberjar compilation hang - clojure only has one compilation mode even if you are doing aot for packaging, and it's exactly the same compilation behavior you would expect in the repl - no top level effects are deferred unless you defer them |
| 20:32 | WickedShell | the bar namespaces has no side effects/go's etc. Its a wrapper for a small bit of java I wrote that also has no sideeffects |
| 20:32 | justin_smith | WickedShell: try using jstack to see what the compiling process is doing |
| 20:33 | justin_smith | WickedShell: I bet it is inside some async or side effecting code - that's the common cause of a hang at least |
| 20:33 | WickedShell | justin_smith, what's jstack? I'm unfamiliar with it, but I'd love to find where this is happening |
| 20:33 | justin_smith | WickedShell: jstack comes with the jdk, it's a command line program that shows you a thread dump for every thread in a vm, if you pass it the PID of your program |
| 20:33 | justin_smith | one of those stack traces will probably be very enlightening |
| 20:34 | justin_smith | WickedShell: if you have a terminal with the process running, kill -3 or control+break will also make it dump all stacks |
| 20:34 | justin_smith | but jstack is nice because it's more flexible, you can pipe it to a file or less, etc. |
| 20:34 | WickedShell | I'm on windows at the moment sadly |
| 20:35 | justin_smith | WickedShell: jstack, or the control+break shortcut should still work on windows |
| 20:35 | WickedShell | yeah jstack is working, looking at the results now, still figuring out how to interpret the results |
| 20:36 | justin_smith | heh, yeah, welcome to the fun world of clojure stack traces! |
| 20:36 | justin_smith | it's the dark side of "lots of small simple functions that each do only one simple thing" :) |
| 20:42 | pilne | eh, i'd rather find problems at compile time, which is why i've always enjoyed racket ocaml and haskell lol |
| 20:42 | justin_smith | pilne: this can be an issue with clojure, in many ways inherent in the lispy design |
| 20:43 | justin_smith | though racket is better than clojure at finding problems statically |
| 20:43 | pilne | yeah, but i'm used to those kinda things (: every time i've tried/had to learn one of the "OO" languages, my brain has wanted to put itself in the garbage disposal lol |
| 20:44 | justin_smith | pilne: part of the issue here is clojure made the intentional decision not to abstract very far from the vm - which is awesome for interop and performance, but can be ugly when debugging because there is no layer hiding the vm implementation details |
| 20:44 | pilne | ahhhhhh |
| 20:45 | justin_smith | compare scala, which abstracts away from the vm quite a bit (which causes a separate set of problems, but also allows very clear error handling) |
| 20:45 | justin_smith | or can, at least, even if they don't always succeed |
| 20:45 | pilne | meh, i like to write my programs gradually, debugging small functional parts, and then weaving them together, so hopefully i'll avoid the nastiest of those |
| 20:46 | WickedShell | justin_smith, I'm a bit lost here, would you mind taking a look at the stack dump? I'm struggling to see what the compilier is waiting on |
| 20:46 | justin_smith | WickedShell: feel free to share on refheap, I've done this a few times so I have a decent clue of what to look for |
| 20:47 | WickedShell | justin_smith, https://www.refheap.com/110527 |
| 20:47 | justin_smith | pilne: for some context, what WickedShell is running into is one of the few cases where something isn't identical between repl interaction and packaging / deploying scenarios - things like this are not super common |
| 20:48 | WickedShell | This is the first time I've ever run into it, till now its been shockingly easy to deploy |
| 20:48 | justin_smith | WickedShell: this is suspicious "swiftgcs.maprenderer$fn__15220$fn__15221.invoke(maprenderer.clj:353)" |
| 20:48 | justin_smith | this should not be hapening at compile time |
| 20:49 | justin_smith | it's being invoked by core.async somewhere |
| 20:49 | pilne | hrm, i tend to not trust repls because the first one i really messed with was haskell's and it is not exact due to it running inside the Io Monad, so i see the repl as a snippet type thing for the most part. |
| 20:49 | justin_smith | pilne: clojure only has one compiler, and it's the one in the repl |
| 20:49 | pilne | so that means it is being run at the top level (the maprenderer.clg) |
| 20:50 | pilne | clj* |
| 20:50 | justin_smith | pilne: the issue we are seeing here is running a task that would not cause an error if run when loading the code in a repl, but will if all you are doing is trying to compile byte code and then exit |
| 20:50 | pilne | same as haskell, but since the repl is running in a "monad" it behaves differently than compiled code |
| 20:50 | justin_smith | pilne: well, indirectly - like I said core.async is invoking it |
| 20:50 | WickedShell | It's not new, that line hasn't changed in a long time, although i'm starting to work on moving away some of the spinups that were happening eariler |
| 20:51 | pilne | it sounds like something similar to putting an "impure" function in the top level of haskell without handling the IO properly |
| 20:51 | justin_smith | exactly the same problem, though the details are different of course |
| 20:52 | justin_smith | WickedShell: the crux of this, is you should not have a go block started up and trying to render anything or load files or whatever that code is doing, when aot compiling |
| 20:52 | pilne | because the compiler will try and run it, instead of compiling it? |
| 20:52 | justin_smith | pilne: compiling it will run it - the clojure compiler doesn't have a separate "compile only" mode |
| 20:53 | WickedShell | justin_smith, out of curiosity is the line number refering to the start of the statement? (the line in question is the start of a let) |
| 20:53 | justin_smith | if you have (def x (some-side-effecting-fn)) - then compiling that line of code means running htat side effecting fn |
| 20:54 | justin_smith | WickedShell: it's being invoked by core.async, so there is no stack trace showing where the go block was launched |
| 20:54 | justin_smith | that's the nature of core.async |
| 20:54 | WickedShell | Yeah that's what I thought |
| 20:54 | justin_smith | somebody started a go block, and it should be wrapped up and started only from your -main |
| 20:54 | justin_smith | or some apropriate init |
| 20:55 | justin_smith | WickedShell: in fact, there are many of thse blocks running it seems |
| 20:55 | WickedShell | I'll chase it all down, and see if that fixes anything. It was on my todo list |
| 20:55 | WickedShell | Yeahh I spin up a bunch of pub/subs in weird spots becuase I didn't know where to do it when I first started |
| 20:56 | justin_smith | WickedShell: if you didn't guess, the trick to finding what hangs the uberjar process is scanning the stack traces for things that are not java or clojure internals. Because only clojure internals or their java basis should be running while making a jar. |
| 20:57 | WickedShell | I'm suspicous that the Graphics2D dispose stuff is resposnsible but I'm not sure |
| 20:57 | justin_smith | WickedShell: it's not! |
| 20:57 | justin_smith | the thing that is responsible is the parked go block |
| 20:57 | justin_smith | the vm will not exit while go blocks are parked, unless you tell it to forcefully |
| 20:58 | justin_smith | but I'm sure you agree it's cleaner not to be starting them up in the first place if you are just packaging a jar |
| 20:58 | justin_smith | WickedShell: there's a function (shutdown-agents) that will make all that stuff stop in a friendly way |
| 21:00 | WickedShell | justin_smith, I do, I just didn't know where to put them early on. |
| 21:00 | justin_smith | WickedShell: my typical MO is to move each startup into a function definition, and call all those functions from -main |
| 21:01 | justin_smith | WickedShell: or in the case of a library, have a single "init" that starts all the rest up, and document that the client should call it |
| 21:01 | justin_smith | WickedShell: there's also stuartsierra/component if any of this has return values that other stuff needs to use at init time |
| 21:01 | WickedShell | Yeah. The biggest reason I hadn't was I had some early teething problems with access/startup order |
| 21:02 | justin_smith | yeah, stuartsierra/component helps with startup order too |
| 21:20 | neoncontrails | Say you've broken the src files of your web app into /clj and /cljs branches. Assuming the location of your handler and source paths was correct before, how do those change with the update? |
| 21:21 | justin_smith | neoncontrails: not at all, unless you fucked it up |
| 21:21 | justin_smith | neoncontrails: oh, sorry, never mind |
| 21:21 | neoncontrails | justin_smith: Oh wow. The one case I didn't even consider |
| 21:21 | justin_smith | neoncontrails: point at the new location of the files :P |
| 21:21 | justin_smith | I was thinking of something different |
| 21:22 | justin_smith | so if instead of src/ it's now clj/ or cljs/ that's the change you would make in your :source-paths and :cljsbuild keys respectively |
| 21:22 | justin_smith | but if it's src/clj and src/cljs that's a different change, of course |
| 21:22 | neoncontrails | I'm getting a FileNotFoundException pointing at "clj/myapp/handler.clj" which is precisely where it is in the structure... |
| 21:23 | justin_smith | what is your :source-paths setting? |
| 21:23 | justin_smith | the default (if you didn't specify at all) is ["src"] - which of course would be wrong now |
| 21:24 | neoncontrails | :source-paths is ["src/clj"], which could have something to do with it. But I've tried a lot of permutations |
| 21:24 | justin_smith | similar change in your :cljsbuild :build :source-paths vector (works the same way) |
| 21:24 | justin_smith | neoncontrails: well, if you don't have a directory called src, that's broken |
| 21:24 | neoncontrails | and my cljsbuild source-paths is ["src/cljs"] |
| 21:24 | justin_smith | same |
| 21:25 | justin_smith | what's the full path from the dir project.clj is in to handler.clj? |
| 21:25 | neoncontrails | my dir structure is myapp > src > cljs | clj > myapp > handler.clj | core.cljs |
| 21:26 | justin_smith | so src -> clj -> myapp -> handler.clj? then that :source-paths setting should work |
| 21:26 | neoncontrails | yup. Alright, that's what I thought too. Hmm. |
| 21:27 | justin_smith | this might sound dumb, but have you tried lein clean? |
| 21:27 | justin_smith | sometimes uncleaned stuff can have very odd results |
| 21:28 | neoncontrails | that's a good point. I'll try that |
| 21:30 | neoncontrails | Ooh, a new error. "No such namespace" at least resolves that one :P |
| 21:32 | neoncontrails | Aaand hallelujah. It's alive! My HTTP server is finally alive. |
| 21:32 | neoncontrails | Beers for everyone. |
| 21:32 | WickedShell | justin_smith, apparently despite having not changed that code for a long time, that was the problem I've moved some arbitrary portion of the async/spin up stuff into functions from main and that fixed it.. I would have bet money that nothing I touched wasn't responsible but I'll take it. Thanks for the assistance |
| 21:33 | WickedShell | Now I'm going to move the rest of them so I don't have to go through this again in the future :) |
| 21:36 | justin_smith | haha |
| 21:36 | justin_smith | neoncontrails: so it was a "lein clean" issue? lol |
| 21:38 | neoncontrails | justin_smith: that's merely one of a few obstacles I cleared today, but thankfully one of the last |
| 21:39 | justin_smith | So, I have a concurrency problem. I have a cljc file where I am handling potentially multipart messages. The message parts are in an atom containing a map of maps. The problem is that I need to remove all the parts of one message and send that message when its last part comes in, but not send it twice. |
| 21:39 | justin_smith | so I can't do the send inside the swap!, because retries |
| 21:40 | justin_smith | and I can't just test the state of the atom after returning from the swap!, because I think two threads could see the state of the atom with all of the parts present... |
| 21:40 | justin_smith | in cljs I can use an agent and all is well |
| 21:40 | justin_smith | maybe the easy fix is to use an agent in clj, and atom in cljs? |
| 21:41 | justin_smith | blergh |
| 21:41 | neoncontrails | justin_smith: above my skill level, but I'm so starving for fun programming puzzles I'd like to give it a shot |
| 21:41 | neoncontrails | What happens if you send the message twice? Just hypothetically. |
| 21:42 | justin_smith | neoncontrails: a single expensive graph computation, that uses up a big chunk of server CPU and doesn't finish for 15 minutes or so, could happen twice in parallel |
| 21:42 | justin_smith | huge waste of resources, and degradation of performance visible to clients |
| 21:43 | justin_smith | maybe I can store the message send as a memoized / delayed thing that would be guaranteed to only run once for a given message? but I think that would be an abuse of memoize |
| 21:45 | justin_smith | this makes me think cljs should have agents :P |
| 21:45 | neoncontrails | I was gonna say something similar. If the message is indeed the same, perhaps you could insert messages into a set before offloading them to the threadpool |
| 21:45 | justin_smith | just to make cross platform code easier |
| 21:46 | justin_smith | neoncontrails: oh yeah, and blacklist based on the set |
| 21:46 | neoncontrails | Sounds sensible to me :) |
| 22:49 | neoncontrails | My compiler is having namespace issues following the steps in this tut: http://www.christopherbiscardi.com/2014/01/15/scaffolding-a-clojurecompojure-webapp-for-heroku/ |
| 22:50 | neoncontrails | Is it implicit in these steps where run-jetty and the 'handler' namespace are declared? I followed the steps exactly and they're not resolving |
| 22:50 | neoncontrails | http://pastebin.com/thHPDTAf |
| 22:53 | neoncontrails | I considered modifying the namespace of the handler.clj file itself to 'handler', but that leaves open the question of what 'site' refers to in that context |
| 23:10 | justin_smith | neoncontrails: if the file is named scaffold_app.handler, the ns should be scaffold-app.handler |
| 23:11 | justin_smith | neoncontrails: also you are referring to a function handler/site that is not pulled into scope in that file |
| 23:11 | justin_smith | you could change run-jetty to ring/run-jetty and you need to require the namespace that defines handler/site |
| 23:12 | neoncontrails | I concluded as much, but what I'm stuck on is the ambiguity of filling in those blanks (handler especially) |
| 23:12 | justin_smith | neoncontrails: well, you as the app developer are expected to implement a handler |
| 23:13 | justin_smith | neoncontrails: usually people use a lib like compojure or polaris that lets you declare routes and generate a handler that will access those routes when given a request |
| 23:15 | neoncontrails | That's reasonable, but my understanding of the tutorial is that it illustrates the process of doing precisely that. No? |
| 23:16 | justin_smith | neoncontrails: did you run the lein-new compojure command to generate the project? |
| 23:17 | justin_smith | the unorthodox ns name makes me think no, and lein new compojure would have generated a handler |
| 23:17 | neoncontrails | I did. They don't change those templates year to year, do they? |
| 23:18 | justin_smith | sometimes weekly |
| 23:18 | justin_smith | but really, lein new compojure foo should generate foo/handler |
| 23:18 | justin_smith | or something like that |
| 23:21 | neoncontrails | Wait, wait: when you say 'lein new compojure would have generated a handler'... I should *not* be modifying that handler then |
| 23:21 | neoncontrails | Is that what you're saying? |
| 23:21 | justin_smith | neoncontrails: no no, a template is for making your initial project |
| 23:22 | justin_smith | it should create and hook up a handler, and that's your starting point |
| 23:22 | justin_smith | and you should modify it |
| 23:22 | neoncontrails | The pastebin link above is a modified version of the scaffold_app.handler which came with the template |
| 23:22 | justin_smith | umm... then the template is broken |
| 23:22 | neoncontrails | Oh. |
| 23:22 | justin_smith | how did you call the template? |
| 23:22 | neoncontrails | :( |
| 23:22 | neoncontrails | "lein new compojure scaffold_app" |
| 23:23 | justin_smith | OK I am recreating here |
| 23:23 | justin_smith | it makes a file in src/scaffold_app/handler.clj |
| 23:23 | neoncontrails | much appreciated |
| 23:24 | neoncontrails | Correct. Here's my version of that with the updates: http://pastebin.com/thHPDTAf |
| 23:24 | justin_smith | neoncontrails: the thing your tutorial calls "handler" the template calls "app-routes" |
| 23:24 | justin_smith | the tutorial is old |
| 23:25 | neoncontrails | I see. Got it, so replace all instances of app-routes with 'handler' then |
| 23:26 | justin_smith | also, my src/scaffold_app/handler.clj has an ns called scaffold-app.handler, and the fact that your ns had scaffold_app as part of it made me think you were not using the template |
| 23:26 | justin_smith | because that's not normal naming in clojure, at all |
| 23:27 | neoncontrails | oh. You're referring to the underscore, yes? |
| 23:27 | justin_smith | right |
| 23:28 | neoncontrails | Yeah like I said I tried a few things that seemed halfway reasonable to declare a handler namespace |
| 23:29 | neoncontrails | one of them was modifying the handler's namespace to handler but that didn't work, clearly |
| 23:29 | neoncontrails | but good point, I'll fix that. |
| 23:44 | neoncontrails | justin_smith: does anything stick out to you w/r/t that ring.middleware.defaults :require statement? It's looking for assets in that library that don't exist |
| 23:47 | justin_smith | neoncontrails: resources/public by any chance? |
| 23:48 | neoncontrails | justin_smith: Specifically it's looking for "ring/middleware/not_modified.clj" which lies outside the scope of any variables mentioned in the handler |
| 23:49 | justin_smith | it requires the ring.middleware.not-modified ns, yes https://github.com/ring-clojure/ring-defaults/blob/master/src/ring/middleware/defaults.clj#L14 |
| 23:49 | justin_smith | so it's not finding it? |
| 23:49 | neoncontrails | It isn't. I'll add that one as well |