This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-06-05
Channels
- # announcements (11)
- # architecture (22)
- # babashka (33)
- # beginners (15)
- # biff (8)
- # calva (7)
- # clj-otel (1)
- # cljs-dev (3)
- # cljsrn (5)
- # clojure (76)
- # clojure-art (1)
- # clojure-europe (36)
- # clojure-hamburg (3)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-poland (12)
- # clojure-spec (2)
- # clojure-uk (7)
- # clojurescript (9)
- # cursive (22)
- # data-science (6)
- # datomic (7)
- # fulcro (9)
- # hoplon (14)
- # instaparse (2)
- # jobs-discuss (14)
- # london-clojurians (1)
- # matrix (32)
- # music (1)
- # nbb (8)
- # off-topic (18)
- # pathom (29)
- # pedestal (6)
- # portal (34)
- # reagent (2)
- # reitit (4)
- # releases (1)
- # sci (10)
- # shadow-cljs (7)
- # tools-deps (4)
- # vim (6)
I searched for cache in this channel, but didn't see anything relevant to eviction. what is the general strategy to do this? should i use pathom wrappers (plugin?), should i update my smart-map env, or should i just mutate my cache (atom/voli) externally? (ei: some function changes the atom without knowing about the smart-map)
hello, there are different ways depending on how you are using the cache, but basically its by mutating it (if its an atom), there is an example using core cache and evicting via LRU here: https://pathom3.wsscode.com/docs/cache#using-corecache
i read the docs. I need my cache eviction to be based on an external trigger. something in my system changed, and keys in the cache are now dirty, i want them evicted. for this specific purpose, i prefer to use a basic cache.
sure, in this case you should be able to do it by mutating the cache, let me know if you have any issues to do it, glad to assist on it
i actually have tried this, and it doesn't seem to work. when i reset!
my cache atom the smart-map doesn't respect the new state of the cache. i'll post a code snippet
(defn init [_]
{:resource/example {}})
(pco/defresolver resource-resolver []
{::pco/cache-store ::my-cache*}
{::resource (init config)})
(def resource-resolver-cache (atom {}))
(def env
(-> (pci/register resource-resolver)
(assoc ::my-cache* resource-resolver-cache)))
(def generated-templates
(->
(pci/register [resource-resolver])
(psm/with-error-mode ::psm/error-mode-loud)
(psm/smart-map)
(psm/sm-touch! [::resource])
))
(->> generated-templates ::resource :resource/example)
;; => {}
(reset! resource-resolver-cache nil)
;; => nil
(->> generated-templates ::resource :resource/example)
;; => {}
:com.wsscode.pathom3.connect.runner/resolver-cache* #<Atom@3e0dcc3c {[scratch/resource-resolver {} {}] {:scratch/resource {:resource/example {}}}}>
i see this in the smart-map env . seems like it's dowing it's own thing with the cache
its possible to use, but its a weird place to be, because there is a bunch of mutable state involved
in general, I suggest you prefer to use the EQL interface, SM is great for small usages, or usages where a map interface is required
I updated your example in a way to make it work as a demo:
(ns com.wsscode.pathom3.demo-cache-sm
(:require [com.wsscode.pathom3.connect.indexes :as pci]
[com.wsscode.pathom3.connect.operation :as pco]
[com.wsscode.pathom3.connect.runner :as pcr]
[com.wsscode.pathom3.entity-tree :as p.ent]
[com.wsscode.pathom3.interface.smart-map :as psm]))
(def config {})
(defn init [_]
{:resource/example {}})
(pco/defresolver resource-resolver []
{::pco/cache-store ::my-cache*}
{::resource (init config)})
(def resource-resolver-cache (atom {}))
(def env
(-> (pci/register resource-resolver)
(assoc ::my-cache* resource-resolver-cache)))
(def generated-templates
(->
(pci/register [resource-resolver])
(psm/with-error-mode ::psm/error-mode-loud)
(pcr/with-resolver-cache resource-resolver-cache)
(psm/smart-map)
(psm/sm-touch! [::resource])))
(comment
(->> generated-templates ::resource)
;; => {}
(do
(swap! resource-resolver-cache assoc '[com.wsscode.pathom3.demo-cache-sm/resource-resolver {} {}]
{::resource "some other value"})
; note that we need this to clean up the internal entity atom that's holding the current values for
; the smart map
(psm/sm-update-env generated-templates p.ent/reset-entity! {}))
(->> generated-templates ::resource))
the thing you are hitting is the entity cache
, which is an atom the remembers the current state of the smart map
so after you clear your cache, when you asked the key, pathom was bringing from this entity cache, and not running any process at all (this is why your cache wasn't hit)
but even hitting it, just making it nil
wont break it, since in this scenario pathom will just ignore the cache (but it will give you a warning log in this case)
so in my example I swapped the cache to put an actual value to demonstrate it
if you have a point where you can use the EQL and just forward the data down, that could work as well, what smart map gives you is the ability to make it lazy (so you process each attribute as they get requested)
its a tradeoff, if you can know ahead of time and request it, its faster than discretly getting every attribute (which is similar to using sm-touch!
after starting the smart map)
ok. in this case i don't care about being lazy. in other parts of my app i guess i do, but i'll get to those later. i'll try the EQL approach.
:com.wsscode.pathom3.entity-tree/entity-tree* #<Atom@388a0d3f {:scratch/resource {:resource/example {}}}>,
i guess that this entry in the smart-map env is the entity cache
correct
i was able to get your code working. how would i do a similar cache busting with the EQL style interface. would i just have to do (swap! resource-resolver-cache assoc
'[com.wsscode.pathom3.demo-cache-sm/resource-resolver {} {}]
{::resource "some other value"})
should i just alter-var-root!
the resolver, or something else?
just swap the cache atom and you should be fine
because in eql processor you get fresh entities every time you run