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

Cs/sc 3593 geo max distance and travel #34695

Merged
merged 21 commits into from
Jun 19, 2024

Conversation

Charl1996
Copy link
Contributor

@Charl1996 Charl1996 commented May 30, 2024

Product Description

Demo video

New criteria has been added to the geospatial disbursement algorithm section, namely:

  • Max distance from user
  • Max travel time
  • Travel mode (walk, cycle, drive)

image

The max travel time criteria is only available for the Road Network Algorithm as Mapbox gives us this information.

Technical Summary

Ticket

It has been decided to incorporate the travel mode option as well so projects can more accurately apply the algorithm results in their own contexts. Also, adding the travel mode is low hanging fruit, since mapbox makes it easy to specify this.

Also, the max distance criteria uses kilometre since the metric system is not as widely used globally. Should we allow the user to specify the unit themselves?

Feature Flag

GEOSPATIAL and support_road_network_disbursement_algorithm

Safety Assurance

Safety story

Tested locally.

Automated test coverage

Unit tests included.

QA Plan

QA ticket

Migrations

  • The migrations in this code can be safely applied first independently of the code

Rollback instructions

  • This PR can be reverted after deploy with no further considerations

Labels & Review

  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@Charl1996 Charl1996 added awaiting QA QA in progress. Do not merge product/feature-flag Change will only affect users who have a specific feature flag enabled labels May 30, 2024
@dimagimon dimagimon added the reindex/migration Reindex or migration will be required during or before deploy label May 30, 2024
@Charl1996 Charl1996 marked this pull request as ready for review May 30, 2024 09:17
Copy link
Contributor

@zandre-eng zandre-eng 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, just left a few comments.

corehq/apps/geospatial/forms.py Show resolved Hide resolved
corehq/apps/geospatial/models.py Outdated Show resolved Hide resolved
@Charl1996 Charl1996 mentioned this pull request May 30, 2024
3 tasks
Copy link
Contributor

@zandre-eng zandre-eng left a comment

Choose a reason for hiding this comment

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

Thanks for the change, looks good from my end.

Copy link
Contributor

@mkangia mkangia 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, mostly non blocking feedback.

I believe using Kilometers only would be annoying to users.
Having something as default and then letting user change it would be fine.
Bonus would be to change the value based on what the user selects to they don't need to convert it themselves i.e if it was 25 KMs and user selects a different metric, update the 25 to the corresponding value for the new metric.

@@ -75,6 +79,24 @@ class Meta:
required=False,
min_value=1,
)
max_case_distance = forms.IntegerField(
label=_("Max distance (km) to case"),
help_text=_("The maximum distance (in kilometer) from the user to the case. Leave blank to skip."),
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: kilometers?

name='travel_mode',
field=models.CharField(choices=[('walking', 'Walking'), ('cycling', 'Cycling'), ('driving', 'Driving')], default='driving', max_length=50),
),
]
Copy link
Contributor

Choose a reason for hiding this comment

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

can we merge the two migrations into one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can do that

@@ -68,6 +79,7 @@ class GeoConfig(models.Model):
api_token = models.CharField(max_length=255, blank=True, null=True, db_column="api_token")

def save(self, *args, **kwargs):
assert self.travel_mode in [self.WALKING, self.CYCLING, self.DRIVING]
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't this already validated by the model since we add choices there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately not; one is still able to create a record with a different value.

Copy link
Contributor

Choose a reason for hiding this comment

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

okay. I believe the model supports adding validators as well in case you want to consider that but this is also okay

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's true. I forgot about those. Maybe I'll add it there

Copy link
Contributor

Choose a reason for hiding this comment

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

Just a general query, Changing calculations in the solver, how much does that effect HQ performance or the view performance?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mkangia When you say "Changing calculations", do you refer to the user changing the travel mode for instance, or do you refer to us changing anything related to the calculations (adding additional constraints, etc)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The user changing the travel mode for instance is something that's on mapbox in terms of performance. It doesn't affect HQ performance (although I haven't tested with massive amounts of data).

Adding additional constraint checking also doesn't seem to affect the performance in a meaningful way, but also, haven't tested with massive amounts of data.

I think the general expectation is that the disbursement runner might take a while (couple of seconds), hence why we have the spinner on the UI instead of hanging. I think it might be worth doing some sort of load test maybe and see what happens when we give it all the data we can (on the UI I think we limit it to 100 cases; not sure for CHWs).

Copy link
Contributor

Choose a reason for hiding this comment

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

I was just generally asking that the changes we make to the solver here, how much does that effect performance.
Could it become too slow leading to higher wait time for user on HQ UI or the page to itself could take too long to load.

not a blocker here for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I see. No, the changes does not affect load time at all. The only affect it might have is when actually running the disbursement.

Copy link
Contributor

Choose a reason for hiding this comment

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

right, and that could take a while. You say we limit to 100 cases, so we only calculate for 100 cases at once in one request?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so we only calculate for 100 cases at once in one request?

Correct

@Charl1996
Copy link
Contributor Author

@mkangia

Having something as default and then letting user change it would be fine.

So are you suggesting that we allow the user to set up their preference w.r.t. metric or imperial?

@mkangia
Copy link
Contributor

mkangia commented May 31, 2024

So are you suggesting that we allow the user to set up their preference w.r.t. metric or imperial?

Does mapbox support all metrics or just kms and then we would need to convert it for the user?
I do think some users would be habitual of using say, miles, and would get annoyed if they have to convert it to kms every time they want to set this value.

@Charl1996
Copy link
Contributor Author

Does mapbox support all metrics

A brief look at their docs it doesn't seem like they support other metrics.

@mkangia
Copy link
Contributor

mkangia commented May 31, 2024

A brief look at their docs it doesn't seem like they support other metrics.

Cool. Fine to leave it for feedback from others then.

@Charl1996 Charl1996 force-pushed the cs/SC-3593-geo-max-distance-and-travel branch from 0df6b8c to d501221 Compare June 3, 2024 10:05
@Charl1996
Copy link
Contributor Author

Just force pushed due to a rebase where I added all the migrations into one file.

@@ -96,6 +96,7 @@ class Meta:
help_text=_("The travel mode of the users. "
"Consider this when specifying the max travel time to each case."),
widget=Select(choices=GeoConfig.VALID_TRAVEL_MODES),
validators=[validate_travel_mode]
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

Choose a reason for hiding this comment

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

oh actually, what is this? In forms I believe the recommended way is to use clean_ methods.
On models, we have validators.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mkangia I followed this example from the django docs. But maybe if you think I should rather move it to the clean methods I can do that?

Copy link
Contributor Author

@Charl1996 Charl1996 Jun 4, 2024

Choose a reason for hiding this comment

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

I see in HQ there are a couple of instances where we use this paradigm (here and here).

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool. I might be limited by what I know here then. But this is better than calling assert.

@Charl1996
Copy link
Contributor Author

Merged #34696 and #34716 into this branch

@Charl1996 Charl1996 added QA Passed and removed awaiting QA QA in progress. Do not merge labels Jun 18, 2024
@Charl1996 Charl1996 requested review from mkangia and zandre-eng June 18, 2024 11:02
Copy link
Contributor

@mkangia mkangia left a comment

Choose a reason for hiding this comment

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

Reviewed last three commits that seem to be new after the two merges.

@Charl1996 Charl1996 merged commit 600c11b into master Jun 19, 2024
13 checks passed
@mkangia mkangia deleted the cs/SC-3593-geo-max-distance-and-travel branch July 16, 2024 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
product/feature-flag Change will only affect users who have a specific feature flag enabled QA Passed reindex/migration Reindex or migration will be required during or before deploy
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants