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

Resource Fuzzing #374

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion frontend/src/pages/MapView/Map/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ const Map = ({
setViewport(viewState);
};

const getPosition = (resource) => {
// if resource has a spider coord (recomputed location) then display marker at that position
if (resource.location.spiderCoordinates) {
return resource.location.spiderCoordinates;
}
return resource.location.coordinates;
};

const getMarkerPoints = () => {
// If the location information came back correct, display on the map
if (center && center[0]) {
Expand All @@ -110,7 +118,7 @@ const Map = ({
data,
pickable: true,
wrapLongitude: true,
getPosition: (d) => d.location.coordinates,
getPosition: (d) => getPosition(d),
iconAtlas: MarkerImg,
iconMapping: mapping,
};
Expand Down
53 changes: 52 additions & 1 deletion frontend/src/utils/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,41 @@ async function deleteResource(id) {
).result;
}

function spiderResources(resourceList) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is looking great, @Polarpi. I'm wondering if we can refactor these two below methods a bit to get it in bit of a more functional programming style, which can make this complex logic a bit easier to debug if things aren't working as we expect. Right now we're doing the spidering computations to the array in-place, which results in there being side effects produced in the computation—for example, the resourceList passed in as an argument to spiderResources will now be modified after calling the function rather than returning a new, modified list, since JS is passing the reference to the array in for resourceList and we're modifying that reference.

It would be great if we can refactor a bit of the logic here to have us map over the resourceList, and for each resource, calling computeSpideredCoordinates which takes in resource, the (unmodified) resourceList, and returns a copy of resource with the spiderCoordinates added. Here's an example of how that's handled in the backend with distances. We don't need RamdaJS necessarily here, but if we can make the computeSpideredCoordinates be solely responsible for managing adding the coordinates to one resource object and returning a copy with those values added, then it becomes a matter of us mapping through resourceList to do this for each resource object.

I definitely see the challenge in having computeSpideredCoordinates do it this way rather than filtering and modifying them all simultaneously. Definitely open to alternate solutions here, this is just a suggestion—I think the main priority is to make sure that we're not causing unintended side effects by calling spiderResources to the passed in array or underlying objects, which is why immutability is key here.

resourceList.forEach((resource) => {
// already has spidered coordinates, so continue
if (resource.location.spiderCoordinates) {
return;
}
resourceList = computeSpideredCoordinates(resource, resourceList);
});
return resourceList;
}

function computeSpideredCoordinates(resource, resourceList) {
const resourcePos = resource.location.coordinates;
const matchLoc = resourceList.filter(
(r) =>
r.location.coordinates[0] === resourcePos[0] &&
r.location.coordinates[1] === resourcePos[1]
);
// resources at same location
if (matchLoc.length > 0) {
const numPoints = matchLoc.length;
const distance = 0.005; // radius of circle
let curAngle = 0;
const addAngle = (Math.PI * 2) / numPoints; // distribute new locations around a circle
matchLoc.forEach((matchResource) => {
const matchResourceLoc = matchResource.location.coordinates;
const newLoc0 = matchResourceLoc[0] + Math.cos(curAngle) * distance;
const newLoc1 = matchResourceLoc[1] + Math.sin(curAngle) * distance;
matchResource.location.spiderCoordinates = [newLoc0, newLoc1];
curAngle = curAngle + addAngle;
});
}
return resourceList;
}

async function editUser(data, id) {
return (
await apiRequest({
Expand All @@ -111,6 +146,18 @@ async function editUser(data, id) {
}

// Redux dispatches for resources and users
async function refreshResources(changedResource) {
let resourceList = (await apiRequest({ endpoint: `resources/` })).result;
resourceList = computeSpideredCoordinates(changedResource, resourceList);
store.dispatch(replaceAllResources(resourceList));
}

async function refreshAllResources() {
let resourceList = (await apiRequest({ endpoint: `resources/` })).result;
resourceList = spiderResources(resourceList);
store.dispatch(replaceAllResources(resourceList));
}

async function refreshAllUsers() {
const userList = (await apiRequest({ endpoint: `users/` })).result;
store.dispatch(updateUsers(userList));
Expand All @@ -125,17 +172,20 @@ async function editAndRefreshResource(data, id) {
await editResource(data, id);
const newResourceData = await getResource(id);
store.dispatch(updateResource(newResourceData));
refreshResources(newResourceData);
}

async function addAndRefreshResource(data) {
const { id } = await addResource(data);
const processedData = await getResource(id);
await store.dispatch(insertResource(processedData));
refreshResources(processedData);
}

async function deleteAndRefreshResource(id) {
await deleteResource(id);
store.dispatch(removeResource({ _id: id }));
refreshAllResources();
}

function addFilterTag(data) {
Expand All @@ -148,7 +198,8 @@ function removeFilterTag(data) {

async function filterAndRefreshResource(keyword, address, tag, radius) {
const results = await getSearchResults(keyword, address, tag, radius);
store.dispatch(replaceAllResources(results.resources));
const resourceList = spiderResources(results.resources);
store.dispatch(replaceAllResources(resourceList));
if (results.center) {
store.dispatch(updateMapCenter(results.center));
}
Expand Down