Fork me on GitHub
#clojure-uk
<
2020-02-04
>
dharrigan06:02:15

Good Morning!

guy07:02:35

Morning!

Andrew08:02:04

Hello πŸ™‚ πŸ‘‹

4
practicalli-johnny09:02:30

ClojureBridge coach training this evening in London at Signal AI (near Old St. roundabout). We are looking for another 4 coaches to help with the event to match the 20 students we are aiming for. https://clojurebridgelondon.github.io/ Coaching is great experience for your career and at ClojureBridge London it will help you understand how much Clojure you know and if you have any gaps. You are also helping someone else get into the software industry at the same time. If you would like to coach but cant make it tonight, please get in touch directly (direct message me here). Thank you.

flefik09:02:04

I want to deploy an authenticated repl for my service. What are people doing to deploy this securely ssh reverse proxy + normal repl listening on loopback? Is there a better way wrapping the connection in TLS or something?

mccraigmccraig10:02:58

i tend to use ssh proxying as the default for most secure admin access - it seems hard to improve upon a single pubkey-only openssh port being the only admin route into your cluster

maleghast10:02:26

Morning All πŸ™‚

maleghast10:02:08

Anyone got a good recommendation for an up to date Clojure / Clojurescript Template (for lein new or clj -A:new) for a small website, i.e. limited overall size / amount of content and no Clojurescript complicated enough to make Reframe a requirement, Reagent will cut it..?

thomas10:02:33

if you just got front end there is Tenzing: https://github.com/martinklepsch/tenzing

thomas10:02:44

no idea how up to date it is though

rickmoynihan10:02:06

looks very old

rickmoynihan10:02:16

but I don’t have any recommendations

rickmoynihan10:02:36

I’d suggest looking for a shadow-cljs template

βž• 8
rickmoynihan10:02:51

and then adding your framework if it doesn’t ship with one already

martinklepsch10:02:16

Tenzing is very old indeed

alexlynham13:02:36

was gonna suggest this πŸ‘

jasonbell10:02:24

Good morning friends.

πŸ‘‹ 8
maleghast10:02:54

Thanks - I may have to fork that one and write my own as I want a bunch of back-end stuff as well, but this (shadow-cljs#quickstart) looks like a good place to start, thanks πŸ™‚

maleghast10:02:29

(Clearly if anyone knows of a template that does both, preferably with Yada and Bidi, 'cos I know them, then that will save me the time of putting one together πŸ˜‰ )

practicalli-johnny14:02:20

Your requirements (or lack of them) suggests just using the app template and adding the libraries you want.

maleghast09:02:35

@U09LZR36F - guess which page on Github I have open this morning after a lot of thinking and reading..?

dominicm09:02:08

Let me know if you have any problems :)

maleghast09:02:13

@U05254DQM - Yes, I could do that, but as I explained to @guy in a thread yesterday I do have my reasons for wanting to roll-my-own

πŸ‘ 4
maleghast09:02:45

@U09LZR36F - I will.... I think that I am still going to put together my own template at some point, but for now Edge still wins.

dominicm09:02:36

If there's something about edge that could be different better, I'd certainly be open to hearing it!

maleghast10:02:40

Morning @jasonbell πŸ™‚ How's life with you, dear fellow?

jasonbell10:02:51

I’m good thanks @maleghast - really busy. Yourself?

maleghast10:02:32

Busy as all get out, but trying to enjoy it πŸ˜‰

thomas12:02:17

@maleghast The shadow-cljs one is most likely a better place to start then Tenzing.

practicalli-johnny14:02:46

@maleghast I would only recommend using shadow-cljs if you have specific npm packages you want to use. Also be aware that some parts of shadow-cljs are undergoing a significant rewrite. The project also failed to download last week.

πŸ‘ 4
practicalli-johnny14:02:17

For templates, If you just want a front end, then figwheel-main +reagent is the simplest react style. If you want full stack then luminous template. Or just use app template and add libraries when you actually need them.

practicalli-johnny15:02:57

Oh, it seems counter-terrorism is now illegal in the UK. So happy time for all the billions of terrorist in the UK https://twitter.com/MrMichaelSpicer/status/1224619601738137600?s=19

mccraigmccraig15:02:20

i've found shadow to invaluable on a larger cljs project, but it's easy enough to switch to it later, so no particular reason not to go with the easiest thing at the beginning

dominicm15:02:21

I'm still grumpy I can't use it in the same jvm as my server with a custom config.

rickmoynihan13:02:50

I think you can via the :deps option in shadow-cljs.edn

rickmoynihan13:02:11

I think there’s a small bug though; which initially confused me which is that shadow doesn’t seem to source user.clj, so you may manually need to load your dev namespace manually first

dominicm16:02:59

I think I didn't want that file at all. I'll have to check. I wanted it in my config.edn where I had aero

dominicm15:02:42

I need to look into whether that has changed yet, but I didn't get the impression it would.

maleghast15:02:54

OK, that escalated quickly - I just did the school run and suddenly the World is on its head again.

dominicm15:02:58

Webpack and figwheel has been fine for me.

maleghast15:02:08

So, Shadow or Not-Shadow?

dominicm15:02:07

I doubt it matters much 😊

otfrom16:02:31

having more core.async fun - one thing I really liked was being able to take a slow (wall clock) mapping function and push it through a pipeline and cut 1/3-1/2 off the total execution time of my processing pipeline

otfrom16:02:07

without having to worry about spawning loads more threads (tho I do need to be careful about how much of the pool I'm using if I use the pool threads)

otfrom16:02:39

early days, but I was pretty happy that I was just able to slap a (pipeline 3... in the middle of my flow

otfrom16:02:56

I'm really going to have to write this up properly

guy16:02:17

blog post! blog post! blog post!

guy16:02:23

can't wait to read it πŸ˜„

guy16:02:44

I've never really tried core.async so would be interesting to read

mccraigmccraig16:02:07

@otfrom we have a map-concurrently fn for manifold streams which lets you do similar things

mccraigmccraig16:02:12

works great for not beating up your db or an api too hard

otfrom16:02:12

@mccraigmccraig cool. I'm guessing that lets you dial in the level of parallelism you want?

mccraigmccraig16:02:10

yes, zakly (map-concurrently N f <stream>)

mccraigmccraig16:02:24

all it really does behind the scenes is use a buffered stream to control the number of realized mapped values in existence at any point in time

dharrigan18:02:02

What's the feeling? Do people intentionally mark their functions private (either with meta data or with -) or don't care?

dharrigan18:02:34

(functions that are only used within a namespace and not used elsewhere)

guy18:02:01

I feel like making it defn- makes it a bit more annoying to test

guy18:02:09

So i used to do it, but now i sorta am against it really

πŸ‘ 4
guy18:02:23

Unless its a library ur making

guy18:02:41

Its also a minor thing really in my eyes

dharrigan18:02:50

not a library, an application (restful service))

guy18:02:53

similar to 2 lines or 1 line inbetween functions

guy18:02:09

Yeah if its owned by you and only your teams gonna see it, i would just whatever everyone likes the most

guy18:02:17

its a minor style thing imo

dharrigan18:02:17

I have a team of one atm πŸ™‚

dharrigan18:02:24

moi! πŸ™‚

πŸ˜‚ 4
guy18:02:09

Then it should be easy to get consensus! haha

Wes Hall18:02:47

@dharrigan I feel that it is a good, if wanky and philosophical, exercise to try to make every function independently useful.

Wes Hall18:02:22

I don't really use private functions any more for this reason. A part of my brain now considers it a failure of design πŸ™‚

Wes Hall18:02:40

This is not to say that you necessarily should use them outside of the namespace they are in, just that they are isolated and independent units of functionality.

Wes Hall18:02:18

..and as @guy says, tests are one area where you might want to do this.

dharrigan19:02:36

Thanks for the input πŸ™‚

seancorfield19:02:08

I've gone back and forth on this. I've found that if you use a linter like Joker in real time in your editor, having defn- for implementation functions is very useful when you're refactoring since unused functions get highlighted immediately. But I like being able to easily test (some) of those functions and sometimes they become useful to other namespaces.

seancorfield19:02:44

So my baseline tends to be: in a library, make everything public by default, organize by namespaces to indicate "implementation" details and either use ^:no-doc or explicit wording in the docstring to discourage use of functions you do not consider part of the API. But in application code, use private by default and make things public as needed over time (and pretty much only ever test public functions still).

dharrigan19:02:55

Good advice - I can see that people have all different opinions on this one!

seancorfield19:02:23

(and opinions change over time based on different experiences πŸ™‚ )

dharrigan19:02:33

indeed πŸ™‚ Never stop learning!

seancorfield19:02:43

After nearly nine years of production Clojure work -- on the same code base where I was pretty much brand new to Clojure at the start of that -- there are parts of our code base that I hate and several decisions we made "back in the day" that I have been actively reversing over the last year or two. Huge amounts of painful refactoring.

❀️ 8
seancorfield19:02:06

One of the most painful decisions we made early on was to allow a certain amount of global state "hidden" in a few namespaces, rather than pass those things through the call chain. That has made testing much harder as functionality has increased/changes and it has made some new functionality extremely hard to implement. In particular, we had some global data source vars that we regret hugely, and some dynamic and/or inheritable thread local vars that were also a huge mistake.

πŸ‘ 4
dharrigan05:02:19

Well, was up early, so refactored my code to remove all state that is stored in a namespace as atoms. Now, any state, like a connection pool is stored in a map that is passed around to functions that need a db connection

dharrigan05:02:37

Should be easier to test now πŸ™‚

seancorfield05:02:41

Sounds much nicer!

dharrigan19:02:48

From this, and from other chats, in my application, I've reduced down to nearly zero (just a bit of refactoring to get to zero) any global state. Anything that is part of the system, is passed along as a parameter map to functions that need it.

dharrigan19:02:23

so when writing tests, I can easily craft a parameter map with "dummy" things to exercise code paths and functions

dharrigan19:02:57

an app-config as a map in functions that require access to "state" things

seancorfield19:02:31

Yup. Never assume you'll have just one database connection as your app grows. We started that way and now we have five I think.

dharrigan19:02:50

πŸ™‚ One of mine has two - but mostly just one πŸ™‚

dharrigan19:02:19

but I do connect out to kafka, postgresql and elasticsearch

seancorfield19:02:02

We have two readonly connections: one has access to only one schema, one has access to all schemas. Plus we have dedicated connections for each schema, with write access.

dharrigan19:02:07

btw, using the core cache stuff - pretty darn funky!

seancorfield19:02:24

That's just MySQL (Percona). We also have Redis and ElasticSearch.

seancorfield19:02:58

@dharrigan LMK if you have any Qs about core.cache. Are you using the wrapper namespace to handle the atoms for you?

dharrigan19:02:08

seems the right thing to do πŸ™‚