This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # beginners (53)
- # boot (93)
- # cider (13)
- # cljs-dev (17)
- # cljsrn (20)
- # clojars (1)
- # clojure (349)
- # clojure-austin (1)
- # clojure-gamedev (5)
- # clojure-italy (1)
- # clojure-nl (16)
- # clojure-poland (1)
- # clojure-russia (26)
- # clojure-spec (57)
- # clojure-uk (6)
- # clojurebridge (5)
- # clojurescript (145)
- # code-reviews (2)
- # core-async (88)
- # cursive (1)
- # datomic (3)
- # defnpodcast (10)
- # events (7)
- # hoplon (20)
- # instaparse (1)
- # jobs-discuss (15)
- # keechma (26)
- # lein-figwheel (2)
- # leiningen (1)
- # liberator (11)
- # lumo (40)
- # off-topic (54)
- # om (32)
- # onyx (11)
- # pedestal (6)
- # perun (4)
- # planck (6)
- # re-frame (4)
- # reagent (12)
- # ring (3)
- # ring-swagger (10)
- # rum (1)
- # testing (4)
- # timbre (1)
- # unrepl (20)
- # untangled (111)
- # vim (1)
@noisesmith , I thought of that too and figured it would be the best way. I've begun building my functions out that way but I guess my concern is, should I use a
future for a single thread of my app? Basically what I have is I get a connection from a client, and then I want to just continue processing data coming in and going out of that stream indefinitely until otherwise noted.
But somehow I guess it just mentally feels odd that that's how I would go about handling the process? Maybe that's just in my head though.
that seems reasonable except thread-per-client is fragile (unless you strictly limit client count)
Yeah this isn't a billion client application. Just something really simple with 5 clients connecting into my server app sending data back and forth.
you can use stuartsierra’s excellent component library to manage data and resources and state that need to be shared between code in different namespaces without needing to create global singleton data
there are other alternatives people have made as component replacements too, but component is the one I have used and it works well
So I just ended up calling the main source directly, instead of the stub file. Seems to have worked.
@mbcev You need thread global variables correct? If so, that's what those are for exactly
@didibus actually what I was aiming for was the exact opposite. I wanted to make sure my data was isolated. What I had been doing was clumping all my "processing" code in one namespace for organizational purposes and then while repl dev-ing I created an atom that I could work on as I added/tested functions. But I don't need the atom anymore now that everything works as intended. I just pass the vector of maps in as a functional argument and my functions pass that around and work with it as necessary.
But when I was looking at stuarsierra/compontents and doing some more research I actually stumbled on Dynamic Vars.
So I appreciate the input also! They're not what I need for this project, but I've added them to my toolbelt!
@mbcev Well, you want it isolated at what level? At the thread level, or more granular?
@didibus well I don't know what is idiomatic I guess, but the way I'm "used to" thinking about things is the "everything is an object" world of Java. So when it comes to organizing my code now I have to consciously make an effort to remember that a namespace isn't equivalent to a java class/object.
So what I wanted was to put all my "processing" code in one namespace and all my networking code in another namespace.
My networking code gets clients and then spins up a future that starts off the processing code
It sounds like you probably didn't need a global, and that's probably for the best. They'd be useful if you needed multiple functions to share the value, but you did not need to share it between threads.
In a Java Class/Object what I'd do is have my private ArrayList MyObjName let's say and then my functions could be written to freely call MyObjName without me needing to worry about Client 1 messing with Client 2 because all the code and data is encapsulated
So I just wanted to figure out what the "right" way of doing that would be with Clojure, what I have ended up doing is having a
(start-process [structure, clientID]) function in which I pass my data structure and which client stream and then let the functions do their thing
Could Client 1 and Client 2 share a thread? If not, you can do the same thing you'd do in Java with dynamic vars. Though it would probably be more idiomatic if you didn't use global variables and had every function take all input as argument.
Thou just an FYI, dynamic Vars give you thread isolation. They're thread safe basically
ztellman/manifold for the stream abstractions and pooled queues. So honestly I probably didn't even need to use futures the way I did.
I'm just not entirely familiar with how all the individual components of what I'm doing work so I'm sure a more experienced dev could clean up or optimize what I'm doing.
You can definitely shoot yourself in the foot. But I think Clojure is pretty good at not letting you do that.
I own a few of the great books out there and have read each of them at least twice, have been following the community for a few years, and have watched plenty of the conferences on youtube so I have developed some sense of "idiomatic clojure", but I don't have tons and tons of actual use-case experience.
Ya, I've done some work projects in Clojure, but even I feel I only know the surface. If its a use case that's different from what I did, I'm lost again. Like never had to use core.async, or do any kind of web work, so these parts are obscure to me.
But ya, generally, would be better to just have increment-to-10 take a counter, instead of modifying a global, even though that global is thread safe.
Yeah 99% of what I'm doing can be done immutably so I don't need a mutable global or anything like that. The only reason I did need to keep track of state basically was to keep track of how much data my client had sent vs how much the server thread had received so that if necessary, the client could go back and resend missing data.
Ya, that's an interesting problem. Like you need a place to track progress, the progress could be updated by multiple threads, and the number of clients is dynamic.
If i wanted to use the
max function to find the max of something that wasn’t already defined, how would i go about doing that? extending the max function?