Skip to content
This repository has been archived by the owner on Feb 5, 2020. It is now read-only.

Commit

Permalink
FEED-206: Fixed that there are no duplicate individual feedback reque…
Browse files Browse the repository at this point in the history
…sts are made
  • Loading branch information
Redmer Loen committed Oct 29, 2018
1 parent 960f398 commit 2248551
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
2 changes: 1 addition & 1 deletion backend/flindt/integrations/providers/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def send_message(self, message):
try:
if not settings.SILENT_RUN:
self.slacker.chat.post_message(self.user.slack_user_name, message, as_user='@flindt')
logger.info('Slack send to {}.'.format(self.user.slack_user_name))
logger.info('Slack send to {} ({}).'.format(self.user.email, self.user.slack_user_name))
except Error as e:
from flindt.round.manager import IntegrationError
raise IntegrationError('Slack error "{}" for user "{}"'.format(e, self.user))
60 changes: 39 additions & 21 deletions backend/flindt/round/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from django.utils import timezone

from flindt import settings
from flindt.feedback.models import (Feedback, FeedbackOnIndividual, FeedbackOnRole)
from flindt.user.models import User

Expand All @@ -26,7 +27,6 @@ class NoSolutionFound(Exception):
class NoSolutionPossible(Exception):
pass


class UserInformationNotComplete(Exception):
def __init__(self, data):
super(Exception, self).__init__()
Expand Down Expand Up @@ -70,6 +70,8 @@ def __init__(self, _round):
# Will increase if no solution can be found.
self.max_reviews_per_user = 0

self.already_received_individual_feedback_by_user = {}

def start_round(self):
"""
This will try to create feedback objects for every receiver and sender
Expand Down Expand Up @@ -153,6 +155,8 @@ def do_all_users_have_a_role(self):
return users_without_role

def do_all_users_have_a_slack_id(self):
if settings.SILENT_RUN:
return []
receivers = self.round.participants_receivers.all()
senders = self.round.participants_senders.all()

Expand Down Expand Up @@ -226,6 +230,7 @@ def _create_individual_feedback_for_participants(self):

for i in range(self.round.individuals_to_review):
for participant in self.round.participants_receivers.all():
logger.info('Creating individual feedback for user: {}'.format(participant))
question = self.round.question_for_individual_feedback
individual = FeedbackOnIndividual(question=question)
feedback = Feedback(
Expand Down Expand Up @@ -339,6 +344,7 @@ def _match_role_feedback_to_senders(self, feedbacks):
senders.remove(feedback.recipient.id)

users_done = self.users_have_given_feedback_on_role.copy()

# From the list of users that have given feedback, remove the users
# that have given the maximum number of reviews.
for key, count in dropwhile(lambda user: user[1] >= self.max_reviews_per_user, users_done.most_common()):
Expand Down Expand Up @@ -403,6 +409,9 @@ def _match_individual_feedback_to_senders(self, feedbacks):
# Get first object from the list.
feedback = feedbacks[0]

if feedback.recipient.id not in self.already_received_individual_feedback_by_user:
self.already_received_individual_feedback_by_user[feedback.recipient.id] = []

senders = self._get_senders_for_user(feedback.recipient)

users_done = self.users_have_given_feedback_on_individual.copy()
Expand All @@ -419,27 +428,34 @@ def _match_individual_feedback_to_senders(self, feedbacks):

for sender in senders:
matched_sender = sender
self.users_have_given_feedback_on_individual[sender] += 1

try:
self.tries += 1
self.counter += 1
self.max_depth = max(self.counter, self.max_depth)
if self.tries % 10000 == 0:
logger.info(
'(tries: {}, max depth: {}) counter: {}{}'.format(
self.tries, self.max_depth, self.counter * '#', ' ' * 100
)
)
# Use the feedbacks objects from 1 and higher to prevent using the same object
# over and over again.
self._match_individual_feedback_to_senders(feedbacks[1:])
except MatchNotFoundError:
self.counter -= 1
self.users_have_given_feedback_on_individual[sender] -= 1
matched_sender = None
# Check if the matched_sender already is giving individual feedback
# to the user, to prevent duplicate individual feedback requests.
if matched_sender in self.already_received_individual_feedback_by_user[feedback.recipient.id]:
logger.info("Sender: {} already giving individual feedback to user. {}".format(matched_sender, feedback.recipient.id))
else:
break
logger.info("User {} matched to {} for individual feedback.".format(matched_sender, feedback.recipient.id))
self.already_received_individual_feedback_by_user[feedback.recipient.id].append(matched_sender)
self.users_have_given_feedback_on_individual[sender] += 1

try:
self.tries += 1
self.counter += 1
self.max_depth = max(self.counter, self.max_depth)
if self.tries % 10000 == 0:
logger.info(
'(tries: {}, max depth: {}) counter: {}{}'.format(
self.tries, self.max_depth, self.counter * '#', ' ' * 100
)
)
# Use the feedbacks objects from 1 and higher to prevent using the same object
# over and over again.
self._match_individual_feedback_to_senders(feedbacks[1:])
except MatchNotFoundError:
self.counter -= 1
self.users_have_given_feedback_on_individual[sender] -= 1
matched_sender = None
else:
break

if not matched_sender:
if self.tries >= 10000:
Expand All @@ -452,3 +468,5 @@ def _match_individual_feedback_to_senders(self, feedbacks):
feedback.individual = feedback.individual
feedback.sender_id = matched_sender
feedback.save()

logger.info("Matching recepient {} to sender {}".format(feedback.recipient, feedback.sender))

0 comments on commit 2248551

Please sign in to comment.