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

WIP Feature/handle users in multiple experiments #1

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

ThomasAdams2
Copy link
Contributor

No description provided.

Gibe.AbTest/AbTest.cs Show resolved Hide resolved
Gibe.AbTest/AbTest.cs Outdated Show resolved Hide resolved
_experimentCookieValueFactory = experimentCookieValueFactory;
}

//TODO: Not sure we need this, being in no experiments isn't a special case
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we replace this with "are there any active experiments?"? It feels like this should never be allowed to return false in any other scenario

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol i ended up with the same question again two and a half years later :v

what is this for?

Gibe.AbTest/DefaultExperimentService.cs Show resolved Hide resolved
Gibe.AbTest/DefaultExperimentService.cs Show resolved Hide resolved
Copy link

@jdurcan jdurcan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, Tommo. Few little bits.

Gibe.AbTest/ExperimentCookieValue.cs Outdated Show resolved Hide resolved
Gibe.AbTest/AbTest.cs Outdated Show resolved Hide resolved
Gibe.AbTest/DefaultExperimentService.cs Outdated Show resolved Hide resolved
Gibe.AbTest/DefaultExperimentService.cs Outdated Show resolved Hide resolved
@stevetemple stevetemple changed the title Feature/handle users in multiple experiements WIP Feature/handle users in multiple experiements Jul 25, 2019
@stevetemple stevetemple changed the title WIP Feature/handle users in multiple experiements WIP Feature/handle users in multiple experiments Jul 16, 2020
@stevetemple stevetemple marked this pull request as draft December 10, 2020 14:29
@stevetemple stevetemple removed their request for review December 16, 2020 14:17
{
return _abTestingService.GetVariation(experimentId, variationNumber);
}

private IEnumerable<Experiment> FilterExperiments(IEnumerable<Experiment> experments, string userAgent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method (particularly line 56) is fairly difficult to read and understand what it's doing - could we use better naming? I know it's filtering, but what's it filtering for and/or why? A better name here would help immensely

{
return _abTestingService.GetVariation(experimentId, variationNumber);
}

private IEnumerable<Experiment> FilterExperiments(IEnumerable<Experiment> experments, string userAgent)
{
var filtered = experments.Where(e => e.Variations.Any(v => v.DesktopOnly) && !userAgent.Contains("Mobi") || !e.Variations.All(v => v.DesktopOnly));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't fully understand what the intent is here - especially given the lack of brackets to make it super-clear what order the && and || are being applied in (I've figured out they would be around the two sides of the &&)

I think what it's saying is:
"If I'm not on mobile, get me experiments that have at least 1 desktop-only variation"
Otherwise
"Get me experiments that aren't all desktop-only experiments"

Is that correct? Is that the logic we want?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking that into account Looking at the FilterVariations method, this might read better as the below to mirror what's going on in FilterVariations()

Suggested change
var filtered = experments.Where(e => e.Variations.Any(v => v.DesktopOnly) && !userAgent.Contains("Mobi") || !e.Variations.All(v => v.DesktopOnly));
var filtered = experments.Where(e =>
(e.Variations.Any(v => v.DesktopOnly) && !userAgent.Contains("Mobi"))
||
(e.Variations.Any(v => !v.DesktopOnly) && userAgent.Contains("Mobi"))
);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the multiple use of userAgent.Contains("Mobi"), would it read better, and centralise code using the DRY principle) if you created an IsMobile() method?

i.e.

private bool IsMobile(string userAgent) => userAgent.Contains("Mobi")

var filtered = experments.Where(e => e.Variations.Any(v => v.DesktopOnly) && !userAgent.Contains("Mobi") || !e.Variations.All(v => v.DesktopOnly));
if (!filtered.Any())
{
return experments.Take(1); //TODO: We should not return anything if there are no correct matches, this requires a refactor to use IEnumerables everywhere
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do this refactor then? As this method returns IEnumerable, I'm not sure what needs refactoring?

}
return filtered;
}

private IEnumerable<Variation> FilterVariations(IEnumerable<Variation> variations, string userAgent)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, not sure this name helps understand what's being filtered/why

public IEnumerable<VariationDto> GetVariations(string experimentId)
{
using (var db = _databaseProvider.GetDatabase())
{
return db.Query<VariationDto>("WHERE ExperimentId = @0", experimentId);
return db.Fetch<VariationDto>("WHERE ExperimentId = @0", experimentId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good update 👍

{
using (var db = _databaseProvider.GetDatabase())
{
return db.Query<ExperimentDto>("FROM AbExperiment");
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this use an ITimeProvider?

Comment on lines +32 to +33
$"AND '{now}' >= [StartDate] OR StartDate IS NULL " +
$"AND '{now}' < [EndDate] OR StartDate IS NULL ");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would some brackets help disambiguate this (I always prefer being specific with a chain of AND/OR statements)

Suggested change
$"AND '{now}' >= [StartDate] OR StartDate IS NULL " +
$"AND '{now}' < [EndDate] OR StartDate IS NULL ");
$"(AND '{now}' >= [StartDate] OR StartDate IS NULL) " +
$"(AND '{now}' < [EndDate] OR StartDate IS NULL)");

{
var variationsCookie = _experimentCookieValueFactory.ExperimentCookieValue(variations);

_cookieService.Create(CookieKey, variationsCookie.RawValue, DateTime.Now.AddDays(120));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this use an ITimeProvider?

private const string Seperator = "~";
private const string ExperimentSeperator = "-";

public string RawValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ever meant to be set externally? If not, would it be better as:

Suggested change
public string RawValue;
public string RawValue { get; private set; }

Comment on lines +80 to +85
var currentWeight = 0;
foreach (var o in opts)
{
currrentWeight += t.Weight;
if (currrentWeight > selectedNumber)
return t;
currentWeight += o.Weight;
if (currentWeight > selectedNumber)
return o;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling FTW!

@jdurcan
Copy link

jdurcan commented May 25, 2021

Wow, this is a blast from the past.

@ThomasAdams2 ThomasAdams2 marked this pull request as ready for review May 26, 2021 07:29
@ThomasAdams2 ThomasAdams2 marked this pull request as draft May 26, 2021 09:08
@ThomasAdams2
Copy link
Contributor Author

This work has been returned to being on hold as these changes are not required for https://jira.gibedigital.net/browse/BR-1757.

Good night sweet prince

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants