untangled

NEW CHANNEL: #fulcro
2016-08-18T00:10:05.000631Z

So i'm having trasient issues with load-field-action when it's used twice back-to-back

2016-08-18T00:10:09.000632Z

transient*

2016-08-18T00:11:05.000633Z

if I load-field-action on field :x, and :y, :y wins because it comes later

2016-08-18T00:11:09.000634Z

and :x is given :untangled.client.impl.om-plumbing/not-found

2016-08-18T00:11:29.000635Z

loading field :x works fine. alone. loading :y works fine alone. when it's back to back, the one that comes last wins

2016-08-18T00:12:23.000636Z

here's my current backend code that has the bug

2016-08-18T00:12:28.000637Z

(defmethod api-read :entitlements
  [{:keys [parser query] :as env} key params]
  (parser env query))

(defmethod api-read :ent-profile
  [env key {:keys [sso-id]}]
  (auth/profile-by-id! sso-id))

(defmethod api-read :ent-details
  [env key {:keys [sso-id]}]
  (auth/entitlements-by-id! sso-id))

2016-08-18T00:12:32.000638Z

it's a recursive parser

2016-08-18T00:12:34.000639Z

here's LOG output

2016-08-18T00:13:02.000640Z

16-08-17 23:49:31 fabric INFO [admin.system:21] - Read Request: [ :entitlements [(:ent-details {:sso-id "54d2497fe3e8d00800893017"})]
 ] 
16-08-17 23:49:31 fabric INFO [admin.system:21] - Recursive Read Request: [ :ent-details  ] ({:sso-id "54d2497fe3e8d00800893017"})
16-08-17 23:49:45 fabric INFO [admin.system:21] - Read Request: [ :entitlements [(:ent-profile {:sso-id "54d2497fe3e8d00800893017"})]
 ] 
16-08-17 23:49:45 fabric INFO [admin.system:21] - Recursive Read Request: [ :ent-profile  ] ({:sso-id "54d2497fe3e8d00800893017"})

2016-08-18T00:13:11.000641Z

so you can see we get 2 read requests

2016-08-18T00:13:29.000642Z

in this case :ent-details came first, so it gets assigned :untangled.client.impl.om-plumbing/not-found in the app-state

2016-08-18T00:14:18.000643Z

#_ (do

     (transact! [(entitlements/load-profile {:sso-id "54d2497fe3e8d00800893017"})])
     (transact! [(entitlements/load-entitlements-details {:sso-id "54d2497fe3e8d00800893017"})])
     )
this reproduces the bug, even though the load-field-actions are in separate transactions

2016-08-18T00:14:40.000644Z

if however at the REPL, I evaluate the first transact!, and wait, then evaluate the second transact!

2016-08-18T00:14:49.000645Z

then the bug doesn't reproduce (both fields get loaded data)

2016-08-18T00:16:00.000646Z

finally if I change my api-read code to the following (always return both fields, even though only 1 is requested at any given time) , then the bug goes away

(defmethod api-read :entitlements
  [{:keys [parser query ast] :as env} key params]
  (let [sso-id (-> ast :children first :params :sso-id)]
    {:ent-profile (auth/profile-by-id! sso-id)
     :ent-details (auth/entitlements-by-id! sso-id)}))

2016-08-18T18:55:11.000651Z

@tony.kay ^^^

tony.kay 2016-08-18T20:16:51.000652Z

Hey there

tony.kay 2016-08-18T20:16:59.000653Z

Yeah, I saw the issue. Not had time to look at it

tony.kay 2016-08-18T20:18:38.000654Z

I've never tried it myself, but I did think it would work. On second thought, I'm considering what happens in the pipeline. When you add two things at the same time it tries to combine them into a single query to process all at once. That means that the queries will run in order, and since they are keyed to the same thing (the result is a map, and the key is the ident) that this bad thing will happen.

tony.kay 2016-08-18T20:20:35.000655Z

@jasonjckn There are a few possible "right things" we could do. One is say you should write the query yourself (that's all load-field is really doing: using load-data, but writing the query for you). Another would be to scan the queue and "merge" (or at least warn) of dupe keys. The easiest is probably to add support in load-field to take a single keyword or a vector of keywords. The latter would just generate the proper query. Then it would be considered incorrect to call it twice at once.

tony.kay 2016-08-18T20:21:46.000656Z

We could also remove the "merge" bit from the queue processing. That was intended to make things more efficient, so I'm not really wanting to do that. I mean, load-data can exhibit a similar problem and it sort of breaks composition. So in that sense it is a bit of a concern

2016-08-18T20:21:46.000657Z

So i do like accepting a vector of keywords in load-field

2016-08-18T20:21:52.000658Z

definitely want that regardless

tony.kay 2016-08-18T20:22:53.000659Z

middle ground would just be to make the merge smarter. Leave the things that have dupe top-level keys as separate network requests. This restores composability

tony.kay 2016-08-18T20:23:20.000660Z

two load-field would run two network requests separately (unless you told it two fields with one call)

2016-08-18T20:23:24.000661Z

Yah, it sounds like the merge logic is broken, there should be no real difference between transact! twice back-to-back and transact! wait 1 second transact! but this merge 'optimization' is making these cases behave widly differently, so i would make sense to fix the merge or remove it until it works

2016-08-18T20:23:40.000662Z

right, i like that "two load-field would run two network requests separately (unless you told it two fields with one call)"

tony.kay 2016-08-18T20:24:08.000663Z

Well, the idea is that initial loads might ask for 10 different things, and you'd like them to go all at once...but now that we have :parallel it is less of a concern

2016-08-18T20:24:08.000664Z

i'm all for the optimized version, but until it works proper, may as well just have 2 network requests

tony.kay 2016-08-18T20:24:36.000665Z

although parallel uses separate network requests, it just doesn't serialize them

2016-08-18T20:24:42.000666Z

nods

tony.kay 2016-08-18T20:24:55.000667Z

Yeah, I think the general fix is to the merge

2016-08-18T20:25:32.000668Z

any idea when we can get this fixed?

tony.kay 2016-08-18T20:25:50.000669Z

I can take a look this afternoon I think

2016-08-18T20:26:03.000670Z

great, let me know if there's anything I can do to help

tony.kay 2016-08-18T20:26:09.000671Z

well, you can fix it 😉

2016-08-18T20:26:12.000672Z

yah lol

tony.kay 2016-08-18T20:26:30.000673Z

adding support for vector to load-field is probably relatively easy

2016-08-18T20:26:42.000674Z

well, it may take me a while to get up to speed , yah the latter is more suitable for me

2016-08-18T20:26:51.000675Z

feel free to skip the latter

2016-08-18T20:27:00.000676Z

perhaps i'll do it one day / it's not as pressing

2016-08-18T20:27:18.000677Z

although it's probably just 1 line change

tony.kay 2016-08-18T20:41:02.000678Z

actually load-field is not an easy fix

tony.kay 2016-08-18T20:41:12.000679Z

would be kind of invasive

tony.kay 2016-08-18T21:05:19.000680Z

@jasonjckn (or anyone wanting to get their hands dirty) I added TODO markers in u.c.impl.data-fetch/mark-loading function. If you do those, it should fix the load-field issue. It is basic stuff. Note that the items in the items-to-load sequence have data access helper functions (e.g. data-query returns the query for the item to load).

tony.kay 2016-08-18T21:05:29.000681Z

this is on develop on untangled-client

tony.kay 2016-08-18T21:05:51.000682Z

Volunteers let me know. I will work on it later if no one picks it up.

2016-08-18T21:11:49.000684Z

Nice, i will take a look

2016-08-18T21:40:19.000685Z

let's say you do the optimized version where if the Q contains 2 items with the same key, you merge the subquery, is it really that hard to get right? consider my parser

(defmethod api-read :entitlements
  [{:keys [parser query] :as env} key params]
  {:value (parser env query)})

(defmethod api-read :ent-profile
  [env key {:keys [sso-id]}]
  {:value (auth/profile-by-id! sso-id)})

(defmethod api-read :ent-details
  [env key {:keys [sso-id]}]
  {:value (auth/entitlements-by-id! sso-id)})
the problem is my backend parser api-read :entitlements is called twice with 2 different queries, even though the client merged them, such that my LOG output on the backend is
16-08-17 23:49:31 fabric INFO [admin.system:21] - Read Request: [ :entitlements [(:ent-details {:sso-id "54d2497fe3e8d00800893017"})]] 
16-08-17 23:49:31 fabric INFO [admin.system:21] - Recursive Read Request: [ :ent-details  ] ({:sso-id "54d2497fe3e8d00800893017"})
16-08-17 23:49:45 fabric INFO [admin.system:21] - Read Request: [ :entitlements [(:ent-profile {:sso-id "54d2497fe3e8d00800893017"})]] 
16-08-17 23:49:45 fabric INFO [admin.system:21] - Recursive Read Request: [ :ent-profile  ] ({:sso-id "54d2497fe3e8d00800893017"})
The backend got 2 read requests even though the client ‘merged’ them. If instead we just have a single read request into api-read :entitlements in the backend, this would also fix the issue. Then the LOG output would be
16-08-17 23:49:31 fabric INFO [admin.system:21] - Read Request: [ :entitlements [(:ent-details {:sso-id "54d2497fe3e8d00800893017"})
                                                                              (:ent-profile {:sso-id "54d2497fe3e8d00800893017”})]] 
16-08-17 23:49:31 fabric INFO [admin.system:21] - Recursive Read Request: [ :ent-details  ] ({:sso-id "54d2497fe3e8d00800893017"})
16-08-17 23:49:45 fabric INFO [admin.system:21] - Recursive Read Request: [ :ent-profile  ] ({:sso-id "54d2497fe3e8d00800893017”})
my understanding of the issue with the optimized version is the "missing keys / ::om-plumbing/not-found" code see's a focused query from merged items-to-load, but the backend sees separate read requests for each item to load

2016-08-18T23:08:51.000695Z

@currentoor @therabidbanana did you guys roll your own charts or did you use a library? trying to figure out how best to do charts with untangled and am curious to hear your experience

2016-08-18T23:09:24.000696Z

We're using c3

2016-08-18T23:09:38.000697Z

It's not too bad @kenbier did much of the heavy lifting there