Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Immutable for state.flags. #4252

Open
chrisbobbe opened this issue Sep 9, 2020 · 2 comments
Open

Use Immutable for state.flags. #4252

chrisbobbe opened this issue Sep 9, 2020 · 2 comments
Labels

Comments

@chrisbobbe
Copy link
Contributor

chrisbobbe commented Sep 9, 2020

This would be another instance of #3949 and #3950.

Once something like #4201 lands, we'll have a roadmap for doing this. Done!

In addition to the performance benefit, this would be a big improvement to code quality. The FlagsState type is the following:

export type FlagsState = {|
  read: { [messageId: number]: boolean },
  starred: { [messageId: number]: boolean },
  collapsed: { [messageId: number]: boolean },
  mentioned: { [messageId: number]: boolean },
  wildcard_mentioned: { [messageId: number]: boolean },
  summarize_in_home: { [messageId: number]: boolean },
  summarize_in_stream: { [messageId: number]: boolean },
  force_expand: { [messageId: number]: boolean },
  force_collapse: { [messageId: number]: boolean },
  has_alert_word: { [messageId: number]: boolean },
  historical: { [messageId: number]: boolean },
  is_me_message: { [messageId: number]: boolean },
|};

I'm not sure state.flags itself should be made an Immutable.Map because it has a certain set of named and non-optional properties (see FlagsState above), but the values at those properties certainly look like good candidates for Immutable.Maps. I'm not sure what we should land on for state.flags, but I do think it should be something from Immutable if we can.

In addition to the performance benefit, this will also be good for code quality and correctness. Currently, we have two instances of const newState = {}; in the flags reducer; that contradicts the FlagsState type (its properties are not optional). Flow v0.113, which we get with RN v0.62 (#3782), will start to have an issue with this, indirectly. An obvious solution would be to initialize newState to initialState instead of {}; the properties we care about updating will clobber the ones on initialState, and it's much clearer that we won't end up with an incomplete state stored. But the implementation is such that initialState itself—defined once, at the top of flagsReducer—would get mutated. Which is no good. So I think it would be great to try to rework the logic with immutable data structures.

@chrisbobbe chrisbobbe added a-redux blocked on other work To come back to after another related PR, or some other task. labels Sep 9, 2020
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 9, 2020
An empty object is badly formed data. It goes against `FlagsState`,
and the upcoming new version of Flow (v0.113, with the RN v0.62
upgrade) would see that.

But the implementation seems works for us, and the type complaint
isn't resolved straightforwardly without introducing "gotcha" bugs
that have to do with mutability, or making drastic changes. I've
filed zulip#4252 for using `Immutable` for `state.flags`; I think it
would be most productive to start there.
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 11, 2020
An empty object is badly formed data. It goes against `FlagsState`,
and the upcoming new version of Flow (v0.113, with the RN v0.62
upgrade) would see that.

But the implementation seems works for us, and the type complaint
isn't resolved straightforwardly without introducing "gotcha" bugs
that have to do with mutability, or making drastic changes. I've
filed zulip#4252 for using `Immutable` for `state.flags`; I think it
would be most productive to start there.
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 17, 2020
An empty object is badly formed data. It goes against `FlagsState`,
and the upcoming new version of Flow (v0.113, with the RN v0.62
upgrade) would see that.

But the implementation seems works for us, and the type complaint
isn't resolved straightforwardly without introducing "gotcha" bugs
that have to do with mutability, or making drastic changes. I've
filed zulip#4252 for using `Immutable` for `state.flags`; I think it
would be most productive to start there.
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 17, 2020
An empty object is badly formed data. It goes against `FlagsState`,
and the upcoming new version of Flow (v0.113, with the RN v0.62
upgrade) would see that.

But the implementation seems works for us, and the type complaint
isn't resolved straightforwardly without introducing "gotcha" bugs
that have to do with mutability, or making drastic changes. I've
filed zulip#4252 for using `Immutable` for `state.flags`; I think it
would be most productive to start there.
@gnprice
Copy link
Member

gnprice commented Sep 18, 2020

Sounds like a good plan to me!

I'm not sure state.flags itself should be made an Immutable.Map because it has a certain set of named and non-optional properties (see FlagsState above), but the values at those properties certainly look like good candidates for Immutable.Maps. I'm not sure what we should land on for state.flags, but I do think it should be something from Immutable if we can.

I think this is likely a good use case for Immutable.Record:
https://immutable-js.github.io/immutable-js/docs/#/Record
But I haven't actually played with that data structure yet, or read its whole docs closely.

chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 18, 2020
…te`.

And tell Flow to ignore the lie. Obviously, we want to address this;
I think zulip#4252 (using Immutable for this bit of state) is a good
place to start.

See discussion [1] for how this lie helps us in the short term.

[1] zulip#4247 (comment)
@chrisbobbe
Copy link
Contributor Author

chrisbobbe commented Sep 18, 2020

I think this is likely a good use case for Immutable.Record:
https://immutable-js.github.io/immutable-js/docs/#/Record
But I haven't actually played with that data structure yet, or read its whole docs closely.

Hmm, maybe! I came across that while putting this issue together, but I kind of got stuck on the name (and then still as I read a bit of its doc)—it sounds like a struct-like thing you'd reach for when you want to hold information about a single entity. FlagsState is meant to hold information about lots of entities. I'm not sure what any negative consequences might be if we used it, though.

gnprice pushed a commit to chrisbobbe/zulip-mobile that referenced this issue Sep 18, 2020
…te`.

And tell Flow to ignore the lie. Obviously, we want to address this;
I think zulip#4252 (using Immutable for this bit of state) is a good
place to start.

See discussion [1] for how this lie helps us in the short term.

[1] zulip#4247 (comment)
@chrisbobbe chrisbobbe removed the blocked on other work To come back to after another related PR, or some other task. label Dec 11, 2020
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Jan 28, 2022
Greg pointed out that we should be doing this; see
  zulip#5188 (comment)

The existing `$FlowFixMe`s put zulip#4252 as their reason. That issue
would be good to fix, but it's not actually the reason the fixmes
are needed. This is.
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this issue Jan 31, 2022
Greg pointed out that we should be doing this; see
  zulip#5188 (comment)

The existing `$FlowFixMe`s put zulip#4252 as their reason. That issue
would be good to fix, but it's not actually the reason the fixmes
are needed. This is.
gnprice pushed a commit to chrisbobbe/zulip-mobile that referenced this issue Feb 1, 2022
Greg pointed out that we should be doing this; see
  zulip#5188 (comment)

The existing `$FlowFixMe`s put zulip#4252 as their reason. That issue
would be good to fix, but it's not actually the reason the fixmes
are needed. This is.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants