TL;DR: don’t mix (shutdown-agents) with clojure.tools.namespace.
I just spent most of a frustrating weekend dealing with a really strange behavior in clojure.
I’ve been a huge fan of Stuart Sierra’s Workflow, pretty much since the day I discovered it. I tend to make a bunch of related changes all at once without stopping to verify each one individually. Which, really, probably cuts down on my overall productivity when I’m hacking in clojure.
I admit that I still have a lot of bad habits left over from inferior languages. It would have gotten beat out of me very quickly, if I hadn’t discovered this workflow about the same time that I was able to justify spending significant time on clojure projects.
I just went through the process of changing a symbol to a magic string in about 8 different places. I realize that I should have changed it into a function call instead, so I’ll never have to do this again (programmers who work with me get irritated about how far I’ll take this sort of refactoring), but I was in hacker mode anyway.
I’m intellectually aware that I should have made the change in one place, evaled it, tested it, and rinse/repeat. Except that none of the changes made sense individually. It was really an all-or-none thing. Which is at least a hint of an architectural smell, but…hacker mode. It was quick and painless enough to just run (reset) and then verify that the problem was solved. (For anyone who’s curious: keywords that are stored in monger automatically get converted to strings. Querying for those keywords later is going to fail. Yes, I’m very new to MongoDB).
Well, it would have been quick and painless. Except that my clojure session kept dying on the command after running a (reset). The error was a helpful “SocketException The transport’s socket appears to have lost its connection to the nREPL server”.
Actually, I suspect the server was dying at the end of the reset. But the client didn’t realize it until I tried to run the next command. And it seems like the problem usually happened after the second reset.
Yeah, weird. And horribly painful. I didn’t have a clue where to point the blame. tools.namespace has always seemed rock-solid to me.
I’m working on a brand-new (to me) linux distro that has been incredibly frustrating and painful because nothing seems to work properly. I was half-way inclined to blame it, but I was having a similar problem on my Ubuntu box. (Actually, the reason I switched to the weird server in the first place was because of this: I thought it might have something to do with the monger client because I didn’t have a database to connect it to).
I spent the weekend trying to work around this. I was very conscientious about eval’ing changes right after I made them. Until it got painful enough to really dig in and isolate the issue.
When I got rid of the namespace that uses core.async, the problem went away (along with pretty much all my functionality). For a while, I really believed that was the issue: I just upgraded to a brand-spanking-new version of an alpha-quality library, after all. Of course, it’s really only alpha-quality in the world of heavy-hitting clojure developers.
Long story made short: somewhere along the line, when I was setting up all the basics, I got the impression that calling (shutdown-agents) would be a good idea when things were exiting. Something about the program hanging for a minute or so waiting for work to time out. I mistakenly thought that meant it would be a good idea to do this in my (stop!) code.
That seems to have been the problem. In retrospect, I think I vaguely remember that the whole Workflow Reloaded thing uses an agent for the restart. And I can’t find any documentation about actually restarting this thread pool after you’ve killed it (I haven’t had any real reason to ever use an agent in anger, so this is really my first exposure to any of the associated gotchas).
I can’t say for sure that this was my pain point. But I haven’t had any issues since I commented that line out. So it seemed worth writing down to hopefully help me remember to never do that again.