-
-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New task: socket-server #549
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great addition IMO! 👍 Just a few minor suggestions.
boot/core/src/boot/task/built_in.clj
Outdated
a accept ACCEPT sym "Namespaced symbol of the accept function to invoke."] | ||
(let [repl-soc (delay (core/launch-socket-server *opts*))] | ||
(core/with-pass-thru [fs] | ||
@repl-soc))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This starts the server but doesn't shut it down afterwards. Not sure if that's necessary, maybe you can comment on that. See boot.core/cleanup
and clojure.core.server/stop-server
if you decide to add it.
https://github.com/boot-clj/boot/blob/master/doc/boot.core.md#cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleanup task is currently problematic with REPL. If boot
is run inside repl task, cleanup from that boot-in-boot would kill also host REPL. So, for now, this probably shouldn't use cleanup
: #554
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know much about boot-in-boot so I'll defer to your judgment that cleaning up is dangerous right now.
boot/core/src/boot/core.clj
Outdated
(let [effective-port (-> ((resolve 'clojure.core.server/start-server) opts) | ||
(.getLocalPort))] | ||
(doto (io/file ".socket-port") .deleteOnExit (spit effective-port)) | ||
(util/info "Socket server started on port %s on host %s.\n" effective-port (:host opts))))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function should be moved into a namespace that is available within pods.
And could there be a more useful return value than nil? Maybe the name (which is needed when stopping servers) or a function that stops the server?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR to return the name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure which namespace would appropriate. I also don't understand the "accessible from pods" distinction - could you elaborate why that would be useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically boot.core
cannot be loaded in a pod because it has stateful stuff that we don't want to replicate. There may be a moment where you want to launch a socket server in a pod though which, with the function in boot.core
, would require copying the implementation somewhere where it can be loaded by the pod.
For this reason I'm suggesting we put the function somewhere where it is also available in pods. That could be boot.util
or boot.pod
, probably there are more, but these two come to mind...
fd451e7
to
193a355
Compare
Looking into this again, I thought about your suggestion, @martinklepsch. boot.pod or boot.util don't seem appropriate places to put this code as they contain fns to do with pods or utilities. I don't fully understand why code in a pod would want to run I chose core.clj so the fn sits next to |
The concern is not cluttering core but instead making it available as a general utility (which includes usage from within pods) which is not possible when it's put into core. Seeing that there is Edit: if you look closely at |
Would this mean that the code needs to be run in a pod, like the nrepl server? |
@pesterhazy no, you can still run it in your regular REPL just like that or wherever you want of course (theoretically everything is in a pod but that's more of a detail and probably not what you're concerned about). |
193a355
to
d5bf0db
Compare
Exposes the Socket Server functionality available in Clojure 1.8 or above as a task. By default, the handler function is clojure.core.server/repl, but a different handler can be specified.
d5bf0db
to
2c26383
Compare
I've updated the PR as per the comments above |
I think this is good to merge but maybe someone else can take a look too? @Deraen @alandipert? |
Just took a look. Awesome, thanks! Looking at this I thought it might be cool if |
Great work, folks. Thank you! |
@alandipert, thanks for merging! Could you outline a scenario where opening a socket server into a pod would be useful? |
@pesterhazy I think what @alandipert is thinking of are situations where you want to "look into a pod" but don't have a reference to the pod object and instead only have the name. I have never needed to look into a pod like that myself though. |
@pesterhazy getting a REPL in a pod with the Using |
Exposes the Socket Server functionality available in Clojure 1.8 or above as a new task. By default, the handler function is clojure.core.server/repl, but a different handler can be specified.
This is useful because Clojure's standard way of enabling the socket server, by setting a system property, doesn't work well with boot (#453).
Wheres
boot repl --server
, provides nREPL functionality used in CIDER,boot socket-server
can be used e.g. with Emacs's inf-clojure mode. It starts up much faster thanboot repl --server
(12s vs 80s), and is more easily accessible usingnc
ortelnet
. But compared to REPLy it is pretty bare-bones and doesn't provide advanced features like auto-completion or beautiful stack traces.This commit adds a new task rather than extending
repl
. The reason is that Socket Servers provides not just REPL but server functionality in general, and thatrepl
semantics are already confusing because of how--server
and--client
flags work.Like
repl
,socket-server
defaults to picking a port at random and stores it in a file, .socket-port, in the current directory.Fixes #453