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