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

Weighted Reaction System 2.0 implementation #91

Merged
merged 41 commits into from
Jul 31, 2019
Merged

Conversation

antonkomarev
Copy link
Member

@antonkomarev antonkomarev commented Jul 29, 2019

Part of #85

To Do

  • Add rate attribute to Reaction model
  • Add getRate method to Reaction model
  • Change weight attributes type to float
  • Change getWeight methods return type to float
  • Change incrementWeight methods argument type to float
  • Change decrementWeight methods argument type to float
  • Change love_reactant_reaction_counters.weight db column type to decimal(13, 2)
  • Change love_reactant_reaction_totals.weight db column type to decimal(13, 2)
  • Change love_reactions.weight db column type to decimal(4, 2)
  • Add $rate argument to reactTo method
  • Allow to change reaction rate
  • Add $rate to Reactant::isReactedBy method
  • Add $rate to Reactant::isNotReactedBy method
  • Add $rate to Reacter::hasReactedTo method
  • Add $rate to Reacter::hasNotReactedTo method
  • Test for love_reactions.rate db column min value
  • Test for love_reactions.rate db column max value
  • Write about min\max values in documentation

Min\Max Values

  • Reaction::RATE_MIN = 0.01
  • Reaction::RATE_MAX = 99.99
  • ReactionCounter::WEIGHT_MIN = -99999999999.99
  • ReactionCounter::WEIGHT_MAX = 99999999999.99
  • ReactionTotal::WEIGHT_MIN = -99999999999.99
  • ReactionTotal::WEIGHT_MAX = 99999999999.99

I decided not to create constants for ReactionCounter & ReactionTotal weight ranges for now. They are computed automatically and it's nearly to impossible to reach the limits in near future.

How did I calculated this decimal value?

If we will take the most popular YouTube video with 40 000 000+ likes multiply this value by 99.99 (RATE_MAX) we will receive ~4 000 000 000 total weight (10 digits). Because decimals are stored using a binary format that packs nine decimal digits into 4 bytes, then we will have 2 packs for integer part (9 + 1) which will require 4 bytes + 1 byte. But +1 digit wouldn't add extra byte because 1-2 digits have same size of 1 byte, so we could start with 11 digits on the integer part and 2 digits on fractional part.

  • DECIMAL(4, 2) require 2 + 1 = 3 bytes
  • DECIMAL (13, 2) require 4 + 1 + 1 = 6 bytes

A decimal type can store a Maximum of 65 Digits values, with 30 digits after decimal point. This is another one reason why I decided not to add range limits for counters. You are free to modify your database columns and extend or reduce weight range without touching codebase.

@antonkomarev antonkomarev added this to the v8.0.0 milestone Jul 29, 2019
@antonkomarev antonkomarev changed the title Add Reaction rate Weighted Reaction System 2.0 Jul 29, 2019
@antonkomarev
Copy link
Member Author

antonkomarev commented Jul 29, 2019

$reaction->getAttributeValue('rate') === $rate

Need to use Reaction contract.

Variant 1

$reaction->getRate() === $rate

I think it's better stop on this variant because this accessor will be useful for the statistics too.

Variant 2

$reaction->hasRate($rate)

@antonkomarev
Copy link
Member Author

antonkomarev commented Jul 31, 2019

Automated DB Schema changes like love_reaction_types.weight column requires doctrine/dbal to be installed:

$ composer require doctrine/dbal

@antonkomarev
Copy link
Member Author

antonkomarev commented Jul 31, 2019

We can add 3rd property ?float $rate to these Models & Facades methods:

  • Reactant::isReactedBy
  • Reactant::isNotReactedBy
  • Reacter::hasReactedTo
  • Reacter::hasNotReactedTo

Use Case 1

Send notification to support team leads when user reacted with minimum rate to conversation with support manager.

$reactant->isReactedBy($reacter, $reactionType, $rate)

It will check if $reacter reacted to this $reactant with exact $reactionType and $rate amount.

Use Case 2

Open access to restricted application area to users who reacted with maximum rate to our post.

$reactant->isReactedBy($reacter, null, $rate)

It will check if $reacter reacted to this $reactant regardless of the $reactionType but with exact $rate amount.

@antonkomarev antonkomarev self-assigned this Jul 31, 2019
@antonkomarev antonkomarev merged commit 5e2a346 into master Jul 31, 2019
@antonkomarev antonkomarev deleted the add/reaction-rate branch July 31, 2019 23:13
@antonkomarev antonkomarev changed the title Weighted Reaction System 2.0 Weighted Reaction System 2.0 implementation Feb 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant