This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-16
Channels
- # beginners (115)
- # boot (13)
- # boot-dev (13)
- # chestnut (1)
- # cider (1)
- # clara (10)
- # cljs-dev (21)
- # cljsjs (1)
- # cljsrn (2)
- # clojure (120)
- # clojure-dusseldorf (2)
- # clojure-greece (13)
- # clojure-ireland (1)
- # clojure-italy (3)
- # clojure-nlp (3)
- # clojure-russia (2)
- # clojure-spec (13)
- # clojure-uk (82)
- # clojured (5)
- # clojurescript (47)
- # core-async (2)
- # core-logic (8)
- # cursive (45)
- # datomic (2)
- # editors (1)
- # emacs (39)
- # fulcro (166)
- # graphql (1)
- # hoplon (16)
- # keechma (5)
- # off-topic (202)
- # perun (4)
- # protorepl (7)
- # re-frame (28)
- # reagent (13)
- # ring (27)
- # ring-swagger (16)
- # rum (1)
- # shadow-cljs (25)
- # spacemacs (20)
- # sql (141)
- # yada (4)
@levitanong B will see A’s result IF A claims to be remote at the time of the call
technically B will always see A’s result of optimistic update…it’s the networking that defers if detected
@tony.kay Yeah, it’s the networking layers that I’m finding problematic. What I need is for A’s networking layer to finish its job and merge novelty back into state (via ok-callback
) before B starts, so that B sees the novelty that A introduced
For now, I’ve made a workaround to make the reconciler available in the networking layer to call transact!
after the ok-callback
@tony.kay Oddly enough, it actually is.
Is there a special behavior for load-action
?
you include (remote-load env)
in the remote side to indicate you want to process the load queue
(defmutation a
[{:keys [foo]}]
(action [{:keys [state] :as env}]
(swap! state assoc :something nil)
(df/load-action env :asdf nil
{:remote :google-places}))
(remote [env] (df/remote-load env)))
ah, I had assumed that setting a :remote
would make it override the (remote ...)
in the event of multiple load-action
s within a mutation, what should be done though?
multiple calls to remote-load
?
so technically you can get away with what you’re doing in most cases; however, with ptransact!, it needs to figure out which network a tx is going to wait on
and it cannot tell that from the load queue, because you could have queued a bunch of stuff…
right, because at call-time, it wouldn’t be able to see the action
hmm. i’m still getting the same result
as in: it should defer the second thing, but since :remote
doesn’t act, it should defer B until some future time
so, there is a function in prim called pessimistic-transaction->transaction
. It convers a tx to a pessimistic one.
ptransact!
is nothing more than (transact! this (p->t tx))
@tony.kay this is weird. If I don’t set the :remote
key on the load-action configuration, it tries to get from remote
, rather than the correct remote that I specify inside the defmutation
.
should both be set and match?
the remote side is technically for sending a mutation…but with load-action you’re morphing it to a read
ahhh right
Okay, I will now take a look at fulcro-inspect
And it would decide to defer if any remote for that mutation is “true”?
https://github.com/fulcrologic/fulcro/blob/develop/src/test/fulcro/client/primitives_spec.cljc#L933
oooh, this is cool. So this is something I can actually test in the REPL!
ptransact!
is new…still working out the kinks. good to have someone trying it out on something complicated
that which must be deferred is deferred. hmm.
Can i just say that I love that fulcro inspect arranges the keys alphabetically. It’s hell looking for the right key in devtools
@mandor2017 OK…found it. Ugly one. There was a bug in application initialization order, and the alternate branch inits were getting stomped. 2.1.1-SNAPSHOT is on clojars and it should fix it. I’ll probably patch it slightly more. It’s a bit ugly in that code segment.
Is fulcro-inspect supposed to show the effects of a remote merge? Because all I’m seeing is local mutations
merge!
is what is called by the callback of networking. Everything appears as a sequence of transactions local to the database.
I have a feeling i’m not doing remotes right…
normal remotes have simple rules: you must call the ok OR error callback once and only once for each network thing you’re asked to do.
you can also implement an updating remote that gets an extra callback (update) that can be called any number of times to update progress
yeah, this is what i’m aware of.
and the intended behavior is, the deferred transaction will only run after the ok-callback
is called, yes?
is there any possible explanation for the deferring not happening despite the system saying it is?
where does it say in fulcro-inspect?
it’s transient though, isn’t it?
It leverages a few things: 1. Mutations are queued before loads. 2. Loads are sequenced. 3. The deferred-transaction itself is a mutation that queues up a load.
So, it is expecting that you’re doing a mutation in step 1..so that a write is split off and sent
nope, I’m messing with the app state a bit in A
there we go.
yes, i’m only doing a load
no remote mutation
I guess I could do my data fetch via mutations. In fact, that’s what it was before I decided to experiment with load
the model is supposed to be that mutations are writes. I’ve allowed reads from writes. But, I’ve also done load combining..because reads should be…well, reads.
The model from the UI layer is that the potential ugliness of a read is hidden at the remote layer. This problem of “I want to read, then look at the result, then read again” isn’t really in the model
because when you’re using the model as designed it isn’t needed…it’s necessitated by legacy APIs, though
Or even just third-party APIs, right?
the idea is to eliminate this aspect of REST, that you have to hit different URLs to gather data.
So is the idiom then, to have a server you control, and have it do all the third-party stuff for you?
the model we’re shooting for here is that a single request can encapsulate what is needed, so the server can make those connections for you.
could you expound on the client network layer?
isn’t this the various remotes?
make one abstract load that you run from the UI. When your client network code sees it, make your 3 XHR calls to gather up the answer.
you can even use a post-mutation on that load to handle the possible different results
you’re back to callback hell…but there’s no avoiding it in this case..at least isolate it to a low layer
but then you wouldn’t have access to the state
you have the incoming request (which can encode parameters), and you own the network comm
i have an origin and a destination. I can get the coordinates for either one, but when I have both, compute the best route.
(load :google/route nil {:params {:origin o :dest d} :post-mutation 'decode-result-in-google-route)
that would take care of the state issue
now I’ve split my remotes into just the google remote, and some other service
to do this, it would seem I’d have to fold the other service into the google remote
well no
i’m pulling the coords from google
pulling routing from another API
heck, for that matter you could just put them all under on :remote
including your API, and treat those as “virtual” requests to the normal remote
lol, and then have some dispatching a-la parser?
true, true. So at that point, architecturally, what would be the use for having multiple remotes?
well, if you had a lot of different things you did against, say, google, then it might make sense from an organizational sense
ok, so Where It Makes Sense™ 😛
Alright, this has been eye-opening. Thanks, @tony.kay! I’m so glad you took the time to help me out.
you are most generous
Sure. Look at the client networking as a place you talk to servers (duh), but take that to the extreme of it can do any amount of interfacing (or even act like the server).
sorry you’ve spent so much time beating your head against a wall on this one problem
Oh, no worries. I got a lot of architecture learnings from this anyhow 😄
ciao! I hope you have a great evening.
Hi all, I’m encountering some odd behavior wherein sometimes a load marker works properly, and sometimes it just goes to :ready and never to :loading. (but still finishing the job) Has anyone experienced this behavior before?
@levitanong when you have many items enqueued, the enqueued items will be :ready
, then :loading
, if you look the history with inspect, can you see the :loading
at any point?
maybe it's just too fast and you are not seeing the loading view?
naw, there have been instances where it stays :ready for quite a while
humm, but it can be there for a while, if it's waiting for a previous network to end
are you using the old markers or the new ones?
there are new ones? lol
:marker :something-something
and you have to use df/marker-table
?
I guess it’s entirely possible that it stays :ready
for a long time, waiting for something to finish, then suddenly goes nuts and finishes loading before the UI can react. XD
yeah, I think that's whats happening
yeah i’ve been reading that
btw, nice work on the fulcro inspector! really useful.
though i’ve noticed that when i scrub the timeline, this error shows up in the console:
Component GlobalInspector threw an exception while rendering Error: No protocol method Mult.tap* defined for type null:
thanks 🙂
weird, I do nothing with core.async, this looks like something with the fulcro remote queue
but may be triggered by something on inspect, if you can get a small case to reproduce I can take a look