Fork me on GitHub
#re-frame
<
2019-06-10
>
nooga10:06:45

is there some tool that would help me to find unused event handlers and subscriptions? I'm trying to clean cobwebs off a legacy project but it's quite hard to eyeball this.

nooga15:06:57

yeah, that's what I did

lilactown15:06:18

one of the shortcomings of everything-is-a-keyword in re-frame is that it doesnā€™t provide easy discovery of that sort of thing. if we used vars we could know by analyzing a call-graph

nooga15:06:16

although I tried writing a quick tool based on slurping all the files, read-stringing them and walking everything collecting handlers and rf/dispatches

nooga15:06:20

and it sort of worked

nooga15:06:28

built a graph

nooga15:06:00

perhaps I could release this as lein plugin or something šŸ˜„

knubie16:06:56

Has anyone found a way to persist and replicate a re-frame DB a la pouchdb?

Braden Shepherdson19:06:20

it's Just Data, so it can be serialized in some format and stored into LocalStorage or elsewhere.

Braden Shepherdson19:06:15

but I'm not aware of anything that does PouchDB-like sync to a backend automatically.

knubie19:06:07

Currently Iā€™m serializing with transit, but the app-db is so large now that itā€™s a significant performance hit to do that on every action

mccraigmccraig09:06:37

we just serialize our app-db to EDN on the filesystem when the app is backgrounded, and retrieve from EDN when the app has been evicted and is started or foregrounded

knubie12:06:08

Oh, thatā€™s a good idea. I hadnā€™t thought of leveraging backgrounding/foregroudning.

knubie12:06:07

What does ā€œhas been evictedā€ mean? (Iā€™m relatively new to app development)

knubie12:06:11

Itā€™s a little scary though, because if the app crashes before itā€™s backgrounded, the user would lose all of their work.

mccraigmccraig12:06:57

"evicted" means that, after backgrounding, the app's paused process image was killed by the o/s, so when next foregrounded it's starting from scratch

mccraigmccraig12:06:12

in the case of our app we also have most state server-side, so we are only storing locally so that the app can continue to work offline - so the risk of the user losing anything is small

mccraigmccraig12:06:41

if i needed to store everything then i would consider storing an occasional app-db snapshot, and then appending in a separate file, a list of mutation events to be applied to the app-db snapshot

mccraigmccraig12:06:39

you can probably arrange that neatly with a re-frame interceptor

mccraigmccraig12:06:28

and since you would only be appending event data (which will serialize nicely to EDN, since your re-frame events / app-db are all pure, simple data) to an already open file it will be blazingly fast

knubie13:06:07

thatā€™s actually the exact strategy I was using previously

knubie13:06:11

i ran into a couple of issues with that. 1) Not everything in the event data was neatly serializable (e.g. some cofx data had infinite sets or fns etc) and 2) Itā€™s possible that the implementation of the event handlers could change between the time the event was stored and when it was played back

knubie13:06:23

I think 2) probably isnā€™t much of an issue 99.9% of the time, though

mccraigmccraig14:06:21

[2] you can deal with in a similar way to how you would deal with e.g. messages from kafka being processed after a db schema changes - either make sure schema changes are backwards compatible (only additions - no field deletes / type changes until you are sure everything has been flushed) or drop changes with stale schema

mccraigmccraig14:06:21

[1] are you putting things which are not pure, simple data into your app-db ? if so, try and avoid doing that. it causes pain šŸ˜¬- could you store a pure-data description of a seed or generator for the infinite set instead ?

knubie19:06:17

[2] Yeah thatā€™s a good call. I had thought about doing that as well. Maybe Iā€™ll open source my current implementation and release it as a re-frame plugin/interceptor.

knubie19:06:05

[1] Not in the app-db, but in the cofx and args to the event message itself.

mccraigmccraig19:06:05

ah, i see what you mean for [1] ... in which case, you could perhaps look at the :db fx itself, after the event has processed, and use clojure.data/diff to extract a minimal diff to write to your change-log - cf https://clojuredocs.org/clojure.data/diff

mccraigmccraig19:06:13

i've only used the clojure.data/diff stuff for single-level diffs myself - but the docs indicate it's ok for nested structure diffs

knubie19:06:01

Iā€™m actually doing just that haha. Using a lib called differ https://github.com/Skinney/differ

knubie19:06:22

Good to know that at least one other person is having the same thought process as me

knubie19:06:07

Started out serializing and storing the entire db. Then moved on to just storing a list of cofxs and replaying them. Then after my concerns of [1] and [2], Iā€™m using the diffing strategy you described.

knubie19:06:12

and thatā€™s where I am now