Comments (3)
User Stories
1. Re-frame database shape is reflecting the the app access patterns (writing for handlers, reading for subscriptions) by correctly indexing for fast lookups and normalised storage for fast, consistent updates
When designing the data-structure of re-frame app-db, always have in mind how the data will be accessed and how it will impact performance and consistency.
For example whenever you need random access to any piece of data which will be red much more often then wrote, put it in map and construct the key in such way that simple and fast lookup (without additional filtering) is guaranteed, even if it means that construction of key is little bit more complicated/slower.
If something has to be unique, put it in set.
Any derived data shouldn't be in database at all and should be computed from source data on fly by default (in super rare cases, we can revisit that when it would hurt performance).
Current situation
Some derived data are stored in db and recalculated explicitly (tags for discovery statuses). But the most problematic thing is proliferation of data indexed by message-id (:message-data
, :message-id->transaction-id
, :message-status
, :unviewed-messages
, :handler-data
), which all are just workarounds around the fact that the primary path where messages live (:messages
) is not indexed in any way.
2. Subscriptions form efficient signal graph, with minimal amount of Level-1 subscriptions and highest possible re-use of all subscriptions
There is not much to elaborate on this, whenever some subscriptions needs input, always check if the input is not already provided by another subscription, so you won't be creating another Level-1 subscription when absolutely not necessary.
Also, whenever you use some function to compute subscription values, make sure that the function is only taking what's necessary to produce result.
Current situation
Some subscriptions are essentially duplicated, and there are cases where subscription function takes whole app-db as argument, even when not necessary - https://github.com/status-im/status-react/blob/develop/src/status_im/chat/subs.cljs#L109-#L114
3. All the events in application are related to outside inputs and there are no artificial intermediate events anymore
This is maybe the most ambitious task of the whole idea. The vision is to only have such events, which naturally maps to asynchronous input from "outer world" into our application. Good examples are user actions (typing, swiping), network callbacks, callbacks from phone modules (camera, permissions, etc.).
If any operation the events perform needs to be re-used (like reloading contacts) it will be exposed as a plain (pure) function which operates with re-frame cofx
map on input and produces fx
map as output.
This approach, when implemented consistently everywhere has huge potential benefits:
- We will have much less events exposed and they will completely describe the "surface" area of our application (think about role of commands in CQRS event driven systems)
- We will reduce the the amount of subscription re-computations, as for each distinct action,
:db
effect will be produced and swapped into app-db only once - Most of the system logic will be captured in pure functions, which will be hooked to minimal possible amount of events - dream to test, play with in repl, etc.
- Ugly non idiomatic events like
[:set ...]
or[:set-in ...]
will disappear
Possible problems are that when you try to combine data from multiple coeffects consuming and effects producing functions, it will get non-trivial, for example sometimes you have to check for :db
both in coeffects (if no function produced :db
effect yet) and effects, you have to make sure that plural effects like saving something into realm are properly accumulated, etc.
But it's still just data munging and Clojure is wonderful language to work with data, so we will eventually evolve some helpers/patterns which will make such compositions a breeze.
Current situation
There are some namespaces where the approach above was already started (for example status-im.chat.events.input
and status-im.commands.events.loading
) but we still have to go a long way to implement it everywhere, the most problematic are in my opinion events in the contacts module and application startup events.
4. Co-effects and effects are isolating the side-effects everywhere and we re-use them to highest possible degree
Co-effects but most importantly effects only capture the essence of the side-effect operation (realm op, network call, etc) and nothing else, they are not highly specific and don't contain much logic.
The upside of coding them that way (always striving to make them absolutely minimal) is that more of our logic will live in the pure functional domain, which is much easier to test (you don't have to mock so much logic) and reason about, and additionally, as the effects will be fairly generic, they could be re-used to much higher degree.
Current situation
Although we moved to cofx
/fx
based handlers almost completely, there is very little in term of coeffects/effects standardisation, some of them are duplicated and registered under different keywords in different namespaces, some of them are really complex, specific to just one use case and containing a lot of logic, for example here - https://github.com/status-im/status-react/blob/develop/src/status_im/ui/screens/contacts/events.cljs#L145-#L159 (which should be just :http
effect with callback logic not owned by effect)
from swarms.
I can pledge some of my time that I spend in idea 9 since the two seems closely related
from swarms.
Closing this as it hasn't been touched in ~3 months. Feel free to re-open if this is something that we are going to tackle soon
from swarms.
Related Issues (20)
- Weekly Digest (6 October, 2019 - 13 October, 2019)
- Weekly Digest (13 October, 2019 - 20 October, 2019)
- Weekly Digest (15 December, 2019 - 22 December, 2019)
- Weekly Digest (22 December, 2019 - 29 December, 2019)
- Weekly Digest (19 January, 2020 - 26 January, 2020)
- Weekly Digest (26 January, 2020 - 2 February, 2020)
- Weekly Digest (2 February, 2020 - 9 February, 2020)
- Weekly Digest (9 February, 2020 - 16 February, 2020)
- Weekly Digest (16 February, 2020 - 23 February, 2020)
- Weekly Digest (23 February, 2020 - 1 March, 2020)
- Weekly Digest (12 April, 2020 - 19 April, 2020)
- Weekly Digest (19 April, 2020 - 26 April, 2020)
- Weekly Digest (26 April, 2020 - 3 May, 2020)
- Weekly Digest (3 May, 2020 - 10 May, 2020)
- Weekly Digest (28 June, 2020 - 5 July, 2020)
- Weekly Digest (5 July, 2020 - 12 July, 2020)
- Weekly Digest (12 July, 2020 - 19 July, 2020)
- Weekly Digest (19 July, 2020 - 26 July, 2020)
- Weekly Digest (26 July, 2020 - 2 August, 2020)
- Weekly Digest (2 August, 2020 - 9 August, 2020)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swarms.