untangled

NEW CHANNEL: #fulcro
mitchelkuijpers 2017-04-06T15:49:39.850503Z

I am running into an issue for which I know a solution, but i am curious if this was such a wrong approach. I get a callback from a user action which returns 0 or more things that I need to save let's call that action foo/save And after that is done I load the thing by doing a df/load. No when I run this only the last foo will get loaded because my tx looks lik this [(foo/save {:id tempid1}) (foo/save {:id tempid2})] And now the server will only return the mutation tempid mapping for the last action. No I can make a foo/save-bulk but that does not give me anything expect for more code

tony.kay 2017-04-06T16:58:15.343455Z

@mitchelkuijpers So, this is a constraint of Om. The return from the server is a map, keyed by mutation name. I thought we just put in a patch that would make those go as separate network requests

tony.kay 2017-04-06T16:58:35.350725Z

though, I do not recommend triggering load from within a mutation

tony.kay 2017-04-06T16:58:44.354026Z

that is what load-action and remote-load are for

tony.kay 2017-04-06T16:59:15.364826Z

and, for that matter, direct access to the untangled/load mutation within your top-level tx

tony.kay 2017-04-06T17:01:00.404582Z

so: 1. Yes, you might want a save-bulk, just because that would reduce network traffic 2. What you are doing should work in the latest version (the mutations should cause two net requests) 3. If you're CALLING load from within a mutation, that is not a supported thing. Use composition (`load-action` + remote-load) or directly use the untangled/load mutation in your tx.

tony.kay 2017-04-06T17:03:27.457640Z

On (3), it sounds since you already have a remote mutation, you'd need an addition to the tx for the loads...which you could write as a mutation and use load-action, or just directly use untangled/load: (transact! this [(foo/save {}) (untangled/load {}) (foo/save {}) (untangled/load {})])

tony.kay 2017-04-06T17:04:47.485928Z

Not sure why you need the loads at all, since you knew all of the novelty on the client to begin with...I guess the server is adding novelty as well? If that is the case you could also use the server's mutation return values by adding a mutation-merge handler, which would eliminate the need for the load

mitchelkuijpers 2017-04-06T17:08:39.567149Z

@tony.kay on 2 should that work in 0.8.1? Because I am running that

tony.kay 2017-04-06T17:09:25.583232Z

Yes...let me look up the patch

tony.kay 2017-04-06T17:11:59.635782Z

OK. The patch I was thinking of was by jasonjckn

tony.kay 2017-04-06T17:12:08.638731Z

and it covered reads with this problem

tony.kay 2017-04-06T17:12:15.640831Z

so, perhaps it isn't fixed for mutations

mitchelkuijpers 2017-04-06T17:12:25.644568Z

Btw I am doing a (om/transact!) and a (df/load) from where I get the callback with the id of id's of which I only know that. I thought about using untangled/load directly but was not sure that was a valid approach

mitchelkuijpers 2017-04-06T17:13:25.664402Z

But I think I change it to a bulk mutation and then run the reads, that seems like the most simple solution

tony.kay 2017-04-06T17:13:31.666525Z

ok, remote mutations will be queued in front of reads, so that should be ok...it's mainly the same-named mutations that are causing your issue, I think

tony.kay 2017-04-06T17:13:39.669296Z

yes, what you said

mitchelkuijpers 2017-04-06T17:13:41.669989Z

Yes exactly

tony.kay 2017-04-06T17:14:15.680838Z

I think I will put in an issue, though. Untangled can solve Om's problem here. We have a sequential queue...we can separate out the mutations

mitchelkuijpers 2017-04-06T17:15:02.697018Z

That is a good point, it would be nice to just work. but do you want to run all mutations and then the reads?

tony.kay 2017-04-06T17:17:10.740270Z

Yes. All mutations should go before reads that were queued at the same time

tony.kay 2017-04-06T17:17:32.747800Z

normally, that means we order the mutations first and reads seconds and send one net request

tony.kay 2017-04-06T17:17:44.752022Z

but in cases where there are collisions on name, we have to split it up

mitchelkuijpers 2017-04-06T17:17:49.753489Z

Might also be nice to do some magic on the server and still send one mutation

tony.kay 2017-04-06T17:18:06.759561Z

the one mutation thing is up to you

tony.kay 2017-04-06T17:18:11.761129Z

I cannot morph that for you

mitchelkuijpers 2017-04-06T17:18:17.763219Z

That is a good point

tony.kay 2017-04-06T17:18:54.775749Z

but if you say: transact w/mutation, load, load, transact w/mutation (on one thread sequence), then we do send: mutation mutation load load

tony.kay 2017-04-06T17:19:00.777709Z

as one network request

tony.kay 2017-04-06T17:19:08.780050Z

which is also a problem

tony.kay 2017-04-06T17:19:11.781288Z

same problem really

tony.kay 2017-04-06T17:19:16.783079Z

if the mutations collide in name

tony.kay 2017-04-06T17:19:21.784799Z

or the loads for that matter

tony.kay 2017-04-06T17:19:27.786946Z

but the loads are already fixed

tony.kay 2017-04-06T17:19:32.788746Z

we just didn't do it for mutations

mitchelkuijpers 2017-04-06T17:19:47.793536Z

Maybe you want to just log a warning?

tony.kay 2017-04-06T17:19:48.793887Z

cause we didn't think ppl would need to send more than one of the same

tony.kay 2017-04-06T17:19:58.797282Z

nah, we can split them. That is the general purpose solution

mitchelkuijpers 2017-04-06T17:20:12.801928Z

Ok cool

tony.kay 2017-04-06T17:20:21.805202Z

we could log a warning that we have to split it...so you could optimize

tony.kay 2017-04-06T17:20:35.810242Z

but the optimization would be what you're doing...writing a single bulk mutation

tony.kay 2017-04-06T17:21:02.819612Z

so we could say you're optimizing your code, and avoiding a temporary bug as a side-effect 😉

mitchelkuijpers 2017-04-06T17:22:59.859913Z

Btw we are thinking about moving to untangled/om-css we used to use the other ladderlife/om-css one but we have some issues with it since we are moving to server-side rendering. Composing css to root is actually insanely cool for getting something on screen as fast as possible. Because you can just inject a style tag with the absolute minimal css needed to show what is on screen

mitchelkuijpers 2017-04-06T17:23:40.874339Z

It was not written to support that but the idea pretty much fixed SSR

tony.kay 2017-04-06T17:23:46.876504Z

nice. It's a super-small lib...I put it out there as more of a proof-of-concept. I'd love untangled-ui to use it, though...would make themeing a pure cljs task

👍 1
mitchelkuijpers 2017-04-06T17:23:50.877631Z

My intern is fixing that pull request

tony.kay 2017-04-06T17:23:53.878517Z

NO CSS tooling would be soooooo sweet

tony.kay 2017-04-06T17:24:01.881541Z

Oh, that's you guys. cool!

mitchelkuijpers 2017-04-06T17:24:15.886Z

No, that is someone else

mitchelkuijpers 2017-04-06T17:24:24.889403Z

We saw the almost done pull request

mitchelkuijpers 2017-04-06T17:24:26.890234Z

And we need it 😛

tony.kay 2017-04-06T17:24:28.890791Z

Oh

tony.kay 2017-04-06T17:24:30.891494Z

I see

tony.kay 2017-04-06T17:24:31.891919Z

🙂

tony.kay 2017-04-06T17:24:37.893842Z

it shouldn't take much

mitchelkuijpers 2017-04-06T17:25:02.902621Z

No and it is great fun for intern

tony.kay 2017-04-06T18:42:07.557332Z

@mitchelkuijpers Updated 0.8.2-SNAPSHOT on clojars. It now does tx splitting to fix what we discussed. Repeat calls to a remote mutation will now get split into separate network requests. Order of mutation1 remote-read1 mutation2 remote-read2 in a single tx should end up as 4 network requests (assuming you have a dupe key on reads as well): mutation1, mutation 2, remoter1, remoter2 If nothing is duplicate, it will be one net request. Basically, does the "right thing" to make sure that Om's map return value won't cause loss of data when a tx has duplicate keys/mutation names

wilkerlucio 2017-04-06T19:44:44.805379Z

@tony.kay do you think it's feasible to have a dynamic endpoint on the network handler? I found myself in a situation where having it dynamic would be handy, because the UI is working on a service that is sharded at our company, so I would like the user to be able to switch the shard he is accessing during runtime, and so each shard needs to target a different URL to do the calls, do you have another idea on how to handle this?

wilkerlucio 2017-04-06T19:59:06.088449Z

the best I can think of as now is to create a new network handler that uses some external atom to select the shard and then internally re-uses the standard network one, not super ideal, so please let me know if you have a different idea

cjmurphy 2017-04-06T20:00:30.118221Z

@wilkerlucio: Is this what you mean: https://github.com/untangled-web/untangled-server/pull/11 - however it is not so much dynamic as multiple - but the client can change its mind, so dynamic in that respect.

wilkerlucio 2017-04-06T20:01:42.142670Z

I see this PR is on the server side, the server is not the problem, but the client

wilkerlucio 2017-04-06T20:01:51.146011Z

because we have the same service deployed in multiple shards

wilkerlucio 2017-04-06T20:02:13.152752Z

so each it's like it's own island, what I want is to be able, on the client, to change to which URL I'm going to point to

wilkerlucio 2017-04-06T20:02:31.159506Z

currently you can only setup the network once at the startup, then there is no way to change it in any manner

cjmurphy 2017-04-06T20:03:07.171725Z

Right, I understand the issue.

wilkerlucio 2017-04-06T20:03:55.187775Z

but you just made me think, maybe there is a way to change, after all the networking is a record in a map, maybe there is a way to change it, I'm going to look on that, thanks 🙂

cjmurphy 2017-04-06T20:04:23.197100Z

:networking can only be set, not changed.

cjmurphy 2017-04-06T20:04:53.207006Z

- that's what you are saying.

wilkerlucio 2017-04-06T20:05:04.210481Z

but this networking goes into the @app atom right? what if I just swap the atom and update the record?

cjmurphy 2017-04-06T20:05:32.219638Z

Yes perhaps it can be changed on the client...

tony.kay 2017-04-06T20:11:18.331401Z

@wilkerlucio So, this is something the user would actually be able to choose?

wilkerlucio 2017-04-06T20:11:45.339913Z

yes, the user should be able to choose on which shard he wants to use the service

wilkerlucio 2017-04-06T20:12:07.346682Z

it's related to managing dead messages on the kafka processes, so the user knows in which shard he wants to operate

tony.kay 2017-04-06T20:12:08.347198Z

At start, or at any time?

wilkerlucio 2017-04-06T20:12:19.350265Z

any time preferably

tony.kay 2017-04-06T20:14:11.386155Z

So, I'd probably do it as a custom networking on the client, with an atom that you can globally change (from within a mutation). The networking object would then select the remote

tony.kay 2017-04-06T20:14:35.394174Z

of course, you have to make sure the browser is going to allow it...e.g. no cross domain

wilkerlucio 2017-04-06T20:15:08.405178Z

that's fine, the service has a graph api open for CORS (it only runs in internal networks, so it's safe to open CORS)

tony.kay 2017-04-06T20:15:58.421206Z

yeah...you could also make a special mutation, like switch-remotes, that you set remote=true to. Hide the atom in your networking. When then networking sees a request to send switch-remotes, it handles thta instead of sending it

tony.kay 2017-04-06T20:16:23.428836Z

that's how we handle loads....the mutation comes in as a (remote) load mutation, and the processing layer transforms it to a query

wilkerlucio 2017-04-06T20:27:42.649119Z

yeah, I think I'll try with that, I just tried (swap! app assoc-in [:networking :remote :url] "<http://NEW-URL/api/admin/graph>") but that didn't worked

tony.kay 2017-04-06T20:28:29.664661Z

not sure why you expected it to...app-state has nothing to do with networking

tony.kay 2017-04-06T20:28:32.665630Z

oh

tony.kay 2017-04-06T20:28:38.667704Z

I see

tony.kay 2017-04-06T20:29:03.676146Z

Yeah, the running app is mounted...you just made a new data structure that nothing is using, and stored it in app

tony.kay 2017-04-06T20:29:13.679072Z

the existing code already closed over the networking

wilkerlucio 2017-04-06T20:40:14.894720Z

(defrecord DynamicNetwork [url-atom network]
  net/NetworkBehavior
  (serialize-requests? [this] (net/serialize-requests? network))

  net/IXhrIOCallbacks
  (response-ok [this xhr-io valid-data-callback]
    (net/response-ok network xhr-io valid-data-callback))
  (response-error [this xhr-io error-callback]
    (net/response-error network xhr-io error-callback))

  net/UntangledNetwork
  (send [this edn ok error]
    (-&gt; network
        (assoc :url @url-atom)
        (net/send edn ok error)))
  (start [this app]
    (net/start network app)))

wilkerlucio 2017-04-06T20:40:42.903988Z

@tony.kay @cjmurphy worked as a charm 🙂 ^^^

tony.kay 2017-04-06T22:08:02.366345Z

yeah, that looks good