Fork me on GitHub
#hoplon
<
2015-09-28
>
xificurC08:09:04

reading through your conversations makes me feel very small simple_smile Still a lot to learn

onetom09:09:38

xifi: i also feel lost quite often... especially since i have zero java experience

onetom09:09:38

and i never really wanted to have any so im a bit hesitant to dig deep into it instead of spending my life on cleaner, simpler systems... 😕

xificurC09:09:18

@onetom: yeah I only did very little java too

xificurC09:09:33

actually I only did enough of VBA. Too much

xificurC09:09:10

so I have to learn everything - clojure, html, css, js, sql & dbs, ...

voytech10:09:14

Hi I see in castra there is something like :rpc/query and also it seems it is after method body is evaulated. What is a rationale behind that :rpc/query - is it about isolating queries for results to be placed into response from method body only ? Are there some examples taking advantage from this ?

voytech10:09:36

Also is this functionality available in latest released version 2.2.2 ?

micha12:09:58

hi voytech

micha12:09:35

@voytech: the purpose of the :rpc/query annotation is to decouple the http response from the value returned by the function

micha12:09:58

the rpc endpoints, since they're functions, can be composed

micha12:09:58

in order to facilitate this kind of composition, most importantly for example when one rpc endpoint calls another, we only evaluate the preconditions/annotations on the endpoint that was actually called from the http client

micha12:09:00

that is to say if rpc endpoints f and g have :rpc/pre annotations, and f internally calls g, when f calls g the :rpc/pre will not be evaluated

micha12:09:15

this eliminates the need to mock state when composing rpc endpoints

micha12:09:25

it's the same with rpc/query

micha12:09:54

:rpc/query provides the latest state and returns it to the http client

micha12:09:02

so the function can return something different

micha12:09:52

so when f calls g we have (g 42) ;=> 43

micha12:09:28

but when the client calls g we have (g 42) ;=> {:rand 71}

voytech12:09:50

@micha That seems totally different that I was thinking 😛

micha12:09:27

the overall shape of my backends is like clusters of rpc functions that all have the same query

voytech12:09:37

@micha now I'm trying to apply real life scenario hmm.

micha12:09:23

that's from my current project at work

micha12:09:41

this is one part of the backend

micha12:09:51

it's the part that deals with advertisers

micha12:09:00

this forms a small cluster of rpc fns

micha12:09:12

but notice how they all return the same thing via :rpc/query

micha12:09:53

it's a simple CRUD thing there

voytech12:09:23

@micha ahh that is why there is condifiont on a request binding in the macro (in make-arity)

micha12:09:51

condifont?

voytech12:09:00

@micha condition 😛

voytech12:09:16

(if-not req# ...)

micha12:09:00

so in another rpc endpoint we may need to maybe upsert an advertiser

micha12:09:09

as a side effect of a different operation

micha12:09:18

so now i can just call the function if i want to

voytech12:09:23

@micha if in request context then the body is evaluated and a response is returned using query.

micha12:09:49

if not in request context the result of evaluating the body is returned

micha12:09:29

honestly i've sort of stopped composing rpc endpoints

micha12:09:43

i've found it's better to do the composition at the lower level

micha12:09:48

the one right under the rpc layer

micha12:09:09

but i like the :rpc/query notation for aesthetic reasons now simple_smile

micha12:09:21

it can probably be removed, really

micha12:09:21

it seemed like a good idea in the beginning

micha12:09:41

but never really turned out to be awesome enough in the real world

voytech12:09:50

@micha I'was recently had question on discourse hoplon about castra and http codes support.

voytech12:09:16

@micha because as far as I saw it uses only 500 and 200, and I was tarting to thing about authentication in Castra. And I think for me this is something what stops me to d othis on castra level

voytech12:09:59

@micha forgot. Thanks for great explanation of :rpc/query, and forgive so many typos (I didn't used to my new laptop's keyboard at work 😞 )

micha13:09:57

@voytech: you can make custom exceptions that return a different status code

micha13:09:11

i haven't found it very useful in practice though

micha13:09:26

we used to have more of that

micha13:09:51

but for RPC really i don't see the purpose of anything other than 200 or 500

micha13:09:04

since none of the problems can be fixed at the HTTP layer

micha13:09:31

the status code is simply a signal of whether the operation succeeded at the application layer

micha13:09:04

the nature of the problem is best expressed via the exception that's thrown and returned to the client

voytech15:09:55

@micha Thanks Micha I think I need to think about it. Currently I have authentication before castra endpoints. There is friend for security. It will let RPC calls only if authenticated, or if RPC calls can be public it also will let it go.

micha15:09:15

@voytech: doesn't friend support sending whatever status you want?

voytech16:09:11

@micha yes it does. And im using it. But now Im not sure yet - suppose we are doing castra call and we are not yet autenticated. It will return eg 401 but does castra on frontend handle it correctly - as it doesnt come from castra but from friend handler.. i need to check. Maybe it is focused only on 200 or 500. Maybe it will require some additional work.

voytech16:09:12

And it is not only about code, but about that response comes from friend handler ..

micha17:09:03

@voytech: ah i see what you mean

piotrek17:09:23

Hi. I am trying to wrap my head around loop-tpl* and understand how it removes no longer needed DOM nodes when the wrapped items get shrinked - https://github.com/hoplon/hoplon/blob/2d68aef74c00b2bbe2231973df08c08b5de32e80/src/hoplon/core.cljs#L564

piotrek17:09:00

the only thing I can see is just removing the elements from the current cell

piotrek17:09:11

is there any magic happening inside of the cell?

micha17:09:40

hi piotrek

micha17:09:13

the idea of loop-tpl is to maintain a pool from which dom elements are allocated

micha17:09:43

so there are two parts to think about: the items that are in the dom and the items that are in the pool

micha17:09:55

consider the following example

micha17:09:41

when this is first evaluated (i.e. when the page loads initially)

micha17:09:57

loop-tpl will see 2 things in the items cell

piotrek17:09:58

oh, so on-deck is an DOM element pool that get moved into the current cell and when they are no longer needed (`items` get smaller) they are returned to the pool (`on-deck`)?

piotrek17:09:44

so in case I get a very long seq in the template and I replace it with a much smaller seq, those DOM elements won’t be deallocated?

micha17:09:26

but it's easy to make a formula that is a window on that other seq

micha17:09:32

with bounded number of things

micha17:09:45

then have loop-tpl bind to that

piotrek17:09:06

I want to create an element which will remove the child node (you might recall my previous question some time ago on ng-if)

piotrek17:09:17

and I wanted to learn from loop-tpl

piotrek17:09:54

but I really need to remove the DOM element as it might be quite a big DOM sub tree (like in a UI tab content when I switch to another tab)

micha17:09:01

loop-tpl exists to provide way to move things into and out of the dom without deallocating them

micha17:09:14

why don't you just use jquery?

micha17:09:38

when you're doing manual memory management it's as good an interface as any

micha17:09:55

(-> (js/jQuery container) (.empty) (.append (some-fn-that-makes-elements)))

piotrek17:09:16

it would be something like

piotrek17:09:18

(def switch (cell= (should-be-displayed? sub-elem)))

micha17:09:21

equivalent to that is (the-container (cell= (some-formula-that-makes-children ...))

micha17:09:28

yeah you can do that

piotrek17:09:20

(if switch (.append ….) (.remove ….))

piotrek17:09:07

ok, thanks for the answers, I will play with it

micha17:09:19

you can do like this

micha17:09:41

if should-show? is a cell then the <h1> will be created and destroyed

micha17:09:56

depending on whether should-show? is true or false

piotrek17:09:13

so then there won’t be any memory leaks?

micha17:09:27

well that's all up to you

micha17:09:53

if you create things in there that will hold references to other things so they can't be garbage collected then you will have leaks

micha17:09:19

there's no way for hoplon to know what you created in there, or how to deallocate what you made

micha17:09:28

it'll just take it out of the dom

piotrek17:09:50

so when I do

piotrek17:09:35

(div
  (cell= (when should-show? (div (some-elem (another-elem …))))

micha17:09:58

it depends on what some-elem and another-elem do

micha17:09:23

(div (cell= (when should-show? (span "hi there"))))

micha17:09:28

that won't leak

piotrek17:09:34

let’s assume the they get some plain data (like maps, vectors) and render them

micha17:09:50

that seems fine yeah

micha17:09:04

the things to watch out for are closures and things like that

micha17:09:57

reasoning about memory leaks in js is tedious and time consuming

piotrek17:09:05

oh, closures which would keep a reference for example to the some-elem itself?

micha17:09:13

the only way to eliminate memory leaks is to use static allocation only

micha17:09:12

piotrek: i don't really know all the internal details of GC in browsers, and the known bugs etc

micha17:09:34

i just try to avoid the whole issue if i can

micha18:09:06

why not try it

micha18:09:14

you'll see pretty fast if you have a leak

micha18:09:40

the page will become unresponsive pretty fast if you are leaking with something large llike you describe

piotrek18:09:59

I guess I might try to memory profile my app to check for leaks

micha18:09:25

i mean it'll be obvious if it's a lot of stuff

piotrek18:09:23

@micha: thanks a lot for all the answers

micha18:09:33

sure, np!