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
www + d: Move comments likes tally from d to www #610
Conversation
398d068
to
36a9296
Compare
@lukebp I addressed all of your comments. I've also changed every reference from "comment vote" to "comment like" or the equivalent (e.g functions names, variables, etc) which required some changes on the GUI: decred/politeiagui#911. |
6e847a6
to
443b4a5
Compare
Code review looks good to me. I tested this PR and it is working as expected. |
politeiad/backend/gitbe/decred.go
Outdated
if decredPluginCommentsUserCache != nil { | ||
seen = decredPluginCommentsUserCache | ||
} | ||
commentsLikes := []decredplugin.LikeComment{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use make here with the somewhat correct length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't make use of make here because is not possible to know the correct length because the journals haven't been replayed at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then use a PNOOMA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From slack resolution:
fernandoabolafio [3:05 PM]
ok, so 1st one:
I wrote: `commentsLikes := []decredplugin.LikeComment{}`
and you asked me to use `make` and estimate a length for this array.
So, the total number of like comments for a proposal is really hard to estimate. So why should we allocate the memory for a random number instead of letting it allocate as needed by using what I wrote or `var commentLikes []decredplugin.LikeComment`?
moo31337 [3:12 PM]
because that requires a bunch of mallocs under the hood
if you have no idea about size pick something large like 1024
make(x,0,1024)
if you do know the size do: make(x,0,len(xxx))
politeiawww/backend.go
Outdated
uclr := www.UserCommentsLikesReply{} | ||
b.RLock() | ||
defer b.RUnlock() | ||
for k, v := range b.userLikeActionByCommentID { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably needs to go into a map. Do we have an idea how many iterations we do here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a map, this is how it is defined:
// User vote action on each comment
userLikeActionByCommentID map[string]map[string]int64 // [token+userid][commentid]action
The number of iterations is equals to the number of comment votes a user has given to a specific proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am talking about the for loop. What is a normal amount of iterations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends on fo the number of users and proposals. The worst scenario is NU x NP
, being NU the total number of users and NP the total number of proposals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From slack resolution:
fernandoabolafio [3:18 PM]
ahh, okay, that makes sense, thanks
2nd one:
You asked me how many iterations we could be doing for:
`for k, v := range b.userLikeActionByCommentID {...}`
So, the worst scenario here is a number of iterations equals to `totalNumberOfUsers x totalNumberOfProposals`. For the current live Pi I would estimate something about 1300 interactions (in the worst case) considering 13 proposals and 100 users.
Is that your question?
moo31337 [3:31 PM]
is this a one time deal?
fernandoabolafio [3:33 PM]
no, it happens as a result of an user request for their comment likes for a given proposal. E.g every time a logged in user access a proposal route.
moo31337 [3:34 PM]
so can we not iterate 1300 times?
that is an expensive lock
fernandoabolafio [3:35 PM]
Yeah, I can optimize that
// results and the vote resultant action for the user | ||
// | ||
// This function must be called WITH the mutex held | ||
func (b *backend) _updateResultsForCommentLike(like www.LikeComment) (*www.Comment, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks expensive, can we optimize this a bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is an expensive call. Even though the code looks a bit complex, none of the operations run inside this function is costly. It grabs a value from the inventory, do some pretty basic math calculus and update that value in the inventory. So I think it is okay to make the entire function atomic.
What bits do you see as expensive for this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From slack resolution:
fernandoabolafio [3:35 PM]
Yeah, I can optimize that
okay, so the last one:
https://github.com/decred/politeia/pull/610/files#diff-c4d289a7e5b50d4535278b93a68b671aR178
You say that this function `_updateResultsForCommentLike(like www.LikeComment) (*www.Comment, error)` looks expensive.
I don’t think it is an expensive call. Even though the code looks a bit complex, none of the operations run inside this function is costly. It grabs a value from the inventory, do some pretty basic math calculus and update that value in the inventory. So I think it is okay to make the entire function atomic. What’s your concern? (edited)
moo31337 [3:53 PM]
ok
i can deal with that
politeiawww/inventory.go
Outdated
commentLikes := ir.commentsLikes | ||
|
||
for _, likes := range commentLikes { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No returns here please. Makes it hard to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am bit confused here. Do you want to move the return outside of the loop or remove at all the return value from this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No I don't want the whitespace between the for loops.
d455181
to
eae628c
Compare
* Updates signup warning text * Removes paragraph
This PR removes the comment likes tally from d and add into www. It also standardizes the terminology as comment likes instead of mixing comment votes and comment likes across structs and functions.
The comment likes are all fetched from d when the www inventory is initialized and it is updated as new "comment likes" come in.
closes #603