This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-08
Channels
- # aleph (5)
- # announcements (3)
- # aws-lambda (24)
- # babashka (17)
- # beginners (59)
- # calva (168)
- # clerk (4)
- # clj-kondo (62)
- # clojure (77)
- # clojure-belgium (4)
- # clojure-brasil (10)
- # clojure-ecuador (3)
- # clojure-europe (41)
- # clojure-losangeles (2)
- # clojure-nl (2)
- # clojure-norway (24)
- # clojure-uk (2)
- # clojurescript (44)
- # clr (21)
- # community-development (7)
- # conjure (1)
- # cursive (6)
- # datalevin (15)
- # datomic (1)
- # deps-new (12)
- # emacs (45)
- # events (1)
- # fulcro (8)
- # funcool (7)
- # graphql (5)
- # hugsql (15)
- # jobs (2)
- # matcher-combinators (17)
- # meander (14)
- # membrane (31)
- # pathom (28)
- # pedestal (8)
- # practicalli (6)
- # re-frame (12)
- # releases (1)
- # remote-jobs (1)
- # shadow-cljs (32)
- # tools-deps (8)
- # vim (16)
Is there a canonical way to purge the cache of a particular resolver from within another? my use case is that I have a mutation that does a query with the parser from the env, this uses resolver A, but the mutation also does some inserts and the initial query needs to return the result of resolver A, but not the cached one from the inner query, rather the updated one after the mutation
Could you please provide some examples of input and output and what you’re expecting?
(ns com.wsscode.pathom3.test
(:require [clojure.test :as t]
[com.wsscode.pathom3.format.shape-descriptor :as pfsd]
[com.wsscode.pathom3.connect.operation :as pco]
[com.wsscode.pathom3.connect.indexes :as pci]
[com.wsscode.pathom3.connect.planner :as pcp]
[edn-query-language.core :as eql]
[com.wsscode.pathom3.interface.eql :as p.eql]
[com.wsscode.pathom3.interface.async.eql :as p.a.eql]))
(def counter (atom 0))
(pco/defresolver get-count
[env _]
{::pco/output [:counter]}
{:counter @counter})
(pco/defmutation inc-count
[{:keys [parser] :as env} _]
(println :counter-before (parser env [:counter]))
(swap! counter inc)
{})
(def env (-> (pci/register
[get-count
inc-count])
(assoc :com.wsscode.pathom3.error/lenient-mode? true)))
(def parser
(let [process (p.eql/boundary-interface env)]
(fn [env tx]
(process (assoc env :parser process) {:pathom/ast (eql/query->ast tx)}))))
(defn test-case []
(let [query [{`(inc-count) [:counter]}]]
(parser {} query))
)
com.wsscode.pathom3.test> (test-case)
:counter-before {:counter 0}
#:com.wsscode.pathom3.test{inc-count {:counter 0}}
com.wsscode.pathom3.test> @counter
1
com.wsscode.pathom3.test> (parser env [:counter])
{:counter 1}
com.wsscode.pathom3.test>
if you remove the query in the mutation and reset the counter:
com.wsscode.pathom3.test> (test-case)
#:com.wsscode.pathom3.test{inc-count {:counter 1}}
com.wsscode.pathom3.test> @counter
1
afaik. Pathom3 will execute mutations first so their results are available to resolvers after.
Calling the println in the mutations does seem to cache the result ::pco/cache?
= false is something you can do in the resolver to prevent the cached result
with pco/cache? false on the counter resolver:
com.wsscode.pathom3.test> (parser env [:counter {`(inc-count) [:counter]}])
:counter-before {:counter 0}
{:counter 1, com.wsscode.pathom3.test/inc-count {:counter 1}}
but considering the resolver is expensive and used in other situations, ideally I'm looking for a solution to only reset the cache in that particular mutation
@U03K8V573EC it’s relatively easy to clean a cache, im afk now to get the exact name, but at runner namespace, there is some resolver-cache keyword, and that lives in the env
its an atom, you can have a look at it, you will see the keys are tuples, you can dissoc the thing you want removed from the cache
another option, that may be a bit cleaner, is to configure that resolver (or even a set of resolvers) to use a separate cache store
doing so, they will have their own atom, this way you can just clean that cache (reseting the atom to an empty map)
If you don’t run the query in the mutation, pathom will execute the mutation first and the resolvers after and you get the incremented value.
@U3XCG2GBZ this is just a repro case, I need to run the query in the mutation for my use case since I'm using the results in the mutation
@U066U8JQJ having a separate atom that can be reset sounds like a good idea.
Depending on what you’re doing, you might need to consider any transactional issues.
If two requests are run simultaneously, they could both read a state of 0
and then both increment to 1
and write/return that. When you would probably intend on the result being 2
Fulcro wraps mutation with a plugin to turn exceptions into data:
(letfn [(wrap-mutate-exceptions [mutate]
(fn [env ast]
(try
(mutate env ast)
(catch Throwable e
(log/errorf e "Mutation %s failed." (:key ast))
;; FIXME: Need a bit more work on returning errors that are handled globally.
;; Probably should just propagate exceptions out, so the client sees a server error
;; Pathom 2 compatible message so UI can detect the problem
{:com.wsscode.pathom.core/errors [{:message (ex-message e)
:data (ex-data e)}]}))))]
(p.plugin/defplugin rewrite-mutation-exceptions {::pcr/wrap-mutate wrap-mutate-exceptions}))
One issue I encountered is if my query asks for attributes for the mutation eg
[{'(my-mutation {:paramA 1 :paramB 2) [:sum]}]
then I don't have the error in the result, instead just an empty map {my-mutation {}}
Is the only way to get the error to explicitly ask for the attribute :com.wsscode.pathom.core/errors
?:com.wsscode.pathom3.format.eql/map-select-include
might help
> I don’t have the error in the result Where, in Fulcro or in the actual response (look into the browser Network tab and parse the transit response). If it is missing from Fulcro but present in the actual response then yes, the problem is that F. strips out everything you do not ask for. At one point RAD app did add it automatically https://github.com/fulcrologic/fulcro-rad/commit/b0b8e288d808372480e0177cc98ffa00e487b273 (but not anymore, likely b/c it now needs to support both Pathom 2 and 3 and the key has changed)
@U3XCG2GBZ solution did the trick, it wasn't even for Fulcro in my case I was doing the pathom3 query in an endpoint for a legacy app
I’m not understanding EQL, I have a couple of resolvers like this:
{::pco/output [{:x/as [:x/a]}]}
{::pco/input [:x/a]
::pco/output [:x/bs]}
What query would give me each :x/a with it’s corresponding :x/bs?this should work too
[{:x/as [:x/bs]}]
{:x/as {:x/bs :something}}
{:x/as [{:x/bs :something}]}
You can expect data to come back like that depending on the relationship respectivelyNot sure what you mean, sorry. Could you send some examples?