Skip to content

GWI Go Platform Challenge#71

Open
LeoStavropoulos wants to merge 1 commit into
GlobalWebIndex:mainfrom
LeoStavropoulos:main
Open

GWI Go Platform Challenge#71
LeoStavropoulos wants to merge 1 commit into
GlobalWebIndex:mainfrom
LeoStavropoulos:main

Conversation

@LeoStavropoulos

Copy link
Copy Markdown

No description provided.

@ba091724 ba091724 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hello @LeoStavropoulos
Thank you for taking the time to design and implement the assignment!

I have added a couple of comments for you to look when you have the time.

I would also like to get your opinion regarding the following scenario:
Let's consider that this project is part of a large system allowing users to save their favorites among a huge amount of assets persisted under an entity table Assets. Would you approach this implementation in a different way?

mux.Handle("POST /favorites", auth(http.HandlerFunc(h.Create)))
// mux.Handle("GET /favorites/mine", auth(http.HandlerFunc(h.ListMine))) // Removed, redundant
mux.Handle("DELETE /favorites/{id}", auth(http.HandlerFunc(h.Delete)))
mux.Handle("PATCH /favorites/{id}", auth(http.HandlerFunc(h.UpdateDescription)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can you spot any issues with the way this endpoint behaves?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Actually after reviewing it I can see a “semantic” issue in both the delete and updateDescription methods. They are returning a 500 status code instead of 404 for missing assets. Also, the error matching logic is a bit unreliable. If the error message changes, the code stops working properly. A typed error would be a better approach.

start := int64(offset)
stop := int64(offset + limit - 1)

ids, err := s.cache.GetIdsFromSet(ctx, start, stop)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Well done considering caching!
I saw your comment about a later application on FindAllByUser, all good and well.
Is there a reason for prioritising caching on FindAll over FindAllByUser?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The global findAll query is the most dangerous, performance wise, operation of this service. In a large database, offset queries would be slow and could lead to resources locking. On the other hand, the findAllByUser is scoped by an index on user_id, so it could have decent performance even without caching.

mux.Handle("GET /favorites/{id}", auth(http.HandlerFunc(h.Get)))
mux.Handle("POST /favorites", auth(http.HandlerFunc(h.Create)))
// mux.Handle("GET /favorites/mine", auth(http.HandlerFunc(h.ListMine))) // Removed, redundant
mux.Handle("DELETE /favorites/{id}", auth(http.HandlerFunc(h.Delete)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can you spot any issues with the way this endpoint behaves?

@LeoStavropoulos

Copy link
Copy Markdown
Author

Hello @ba091724

First of all, thank you for your time and effort reviewing my assessment and apologies for the late response.
In the scenario you are describing, the alternative approach I can think of is to alter the “favourites” table’s structure so that it becomes a join table (connecting user_id to asset_id). That way, it would prevent some storage redundancy (For example, in the current implementation if two users have the same favourite, this asset would be duplicated).
This would also impact the service layer of the app. The assets and favourites table should be joined, in order to fetch the asset data, but on large scale this join would be an issue. So, we would need a “favourite service” that returns a list of user’s favourites ids and an “assets service” that fetches the asset using this id. Also, some tweaks in the caching would be needed, like for example caching each asset once (globally)

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.

2 participants