-
Notifications
You must be signed in to change notification settings - Fork 0
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
base: master
Are you sure you want to change the base?
WIP Feature/handle users in multiple experiments #1
Conversation
_experimentCookieValueFactory = experimentCookieValueFactory; | ||
} | ||
|
||
//TODO: Not sure we need this, being in no experiments isn't a special case |
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.
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
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.
lol i ended up with the same question again two and a half years later :v
what is this for?
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.
Looks good, Tommo. Few little bits.
{ | ||
return _abTestingService.GetVariation(experimentId, variationNumber); | ||
} | ||
|
||
private IEnumerable<Experiment> FilterExperiments(IEnumerable<Experiment> experments, string userAgent) |
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 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)); |
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 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?
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.
Taking that into account Looking at the FilterVariations
method, this might read better as the below to mirror what's going on in FilterVariations()
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")) | |
); |
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.
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 |
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.
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) |
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.
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); |
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.
Good update 👍
{ | ||
using (var db = _databaseProvider.GetDatabase()) | ||
{ | ||
return db.Query<ExperimentDto>("FROM AbExperiment"); | ||
var now = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); |
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.
Should this use an ITimeProvider
?
$"AND '{now}' >= [StartDate] OR StartDate IS NULL " + | ||
$"AND '{now}' < [EndDate] OR StartDate IS NULL "); |
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.
Would some brackets help disambiguate this (I always prefer being specific with a chain of AND
/OR
statements)
$"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)); |
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.
Should this use an ITimeProvider
?
private const string Seperator = "~"; | ||
private const string ExperimentSeperator = "-"; | ||
|
||
public string RawValue; |
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.
Is this ever meant to be set externally? If not, would it be better as:
public string RawValue; | |
public string RawValue { get; private set; } |
var currentWeight = 0; | ||
foreach (var o in opts) | ||
{ | ||
currrentWeight += t.Weight; | ||
if (currrentWeight > selectedNumber) | ||
return t; | ||
currentWeight += o.Weight; | ||
if (currentWeight > selectedNumber) | ||
return o; |
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.
Spelling FTW!
Wow, this is a blast from the past. |
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 |
No description provided.