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

Initial implementation #6

Merged
merged 51 commits into from
Feb 6, 2020
Merged

Initial implementation #6

merged 51 commits into from
Feb 6, 2020

Conversation

levb
Copy link
Contributor

@levb levb commented Jan 5, 2020

See https://github.com/mattermost/mattermost-plugin-solar-lottery/blob/dev/demo.md

To run the entire demo script on your local instance, type /lotto demo all, requires test-data.

/lotto info for current info.

Lev Brouk and others added 30 commits December 7, 2019 13:49
Also refactored p.API dependencies into api.PluginAPI
- initial user.IsAvailable based on the calendar
- also `user [dis]qualify` now complete
…bars-4.5.3

Bump handlebars from 4.1.2 to 4.5.3 in /webapp
@levb
Copy link
Contributor Author

levb commented Jan 13, 2020

Thanks @crspeller for the review, it's a lot of lines, appreciate it!

  • Overall the CLI needs some more work to make it nice to use.

Noted, both structurally (command/flag set) and heuristically, like allowing just a space-separated rotation names and @usernames.

  • A glossary of terms (rotation, shift... etc) would be especially useful.

👍

  • Some work needs to be done around smaller rotations. Got some strange results (like the same user being scheduled repeatedly)

Yes, I saw the same thing just before the demo. Likely de-randomized something in the last refactoring of the scheduler; adding tests should help.

  • It would be nice if the "guess" was stable if no parameters changed.

👍 will add a --randomize or something for the rare other use case.

  • User vs admin commands and help would be nice.

Right. One obvious improvement begging to be made is the concept of rotation admin(s) but sysadmin vs user would be a great step forward, agreed.

Integration with the workflow plugin would be great.

Let's file additional enhancement issues for the necessary APIs?

@levb
Copy link
Contributor Author

levb commented Jan 20, 2020

Filed #11 and #12 filed to address some of the concerns.

I could not reproduce the small rotation weirdness, will try again, will file as separate issues; also need more tests for fill now.

@crspeller @cpoile I'm submitting the feedback as a separate PR, since it's quite massive. It can be re-pointed at master if it makes it easier (lots of refactoring there)

@levb levb requested review from aaronrothschild and crspeller and removed request for aaronrothschild January 20, 2020 03:40
* Refactored api file structure, api_ for wrappers

* updated dependencies

* PR Feedback: renamed event type other to personal

* PR Feedback: ResolveRotationName to return ErrNotFound when no results

* PR Feedback: nits and naming

* PR Feedback: removed PostAction placeholder

* Copyright (c) 2019-...

* PR Feedback: comment in plugin/api.go

* PR Feedback: nits

* Refactored solar-lottery autofill, no tests yet

* added weight tests

* Added tests for solar-lottery needs, pickUser

* test for fillOne, bunch of refactoring, fixes

* More fillOne tests, fixes

* Refactored MORE!

* amend minor

* amend minor

* amend minor
Copy link
Contributor

@cpoile cpoile left a comment

Choose a reason for hiding this comment

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

This is huge, I'm learning a lot.

These are notes I'm taking while working through the code.

It's interesting -- you're using fields on structs (like in api) to carry parameters into methods, kind of like a context in a request... Yah, that is what you're doing. You're treating slash commands like http requests. Hah, nice. Once I figured that out it became a lot clearer. Maybe we can rename it to make this a bit more clear on first sight? What you're doing feels like it's overloading the meaning of an api struct -- because in other places we've used just to hold api methods or helper methods. This is more like a context.

I'm using the demo code as examples -- if we're going to push to community we definitely need thorough explanations for the commands, and formatted examples. Like: Here are the steps to set up a team, set up an icebreaker event, set up a SET, give someone time off. The rotation commands are particularly difficult, I think.

Is there a way to specify a rotation that has randomness but makes sure that all eligible people are picked i times before someone is picked for their i+1th time? Because that's how I imagine the ice-breaker should work.

Guess will fail completely if it can't fill a rotation. Maybe it should try its best, because often we don't have a full icebreaker, or maybe SET is less one person.

Minor nits (todos):

  • the box profile pic is Jira's

server/plugin/plugin.go Show resolved Hide resolved
server/command/command.go Outdated Show resolved Hide resolved
server/api/level.go Outdated Show resolved Hide resolved
server/api/level.go Outdated Show resolved Hide resolved
server/api/level.go Outdated Show resolved Hide resolved
server/command/user_unavailable.go Outdated Show resolved Hide resolved
server/command/rotation_join.go Outdated Show resolved Hide resolved
server/api/rotations.go Outdated Show resolved Hide resolved
server/api/user.go Outdated Show resolved Hide resolved
server/api/rotation.go Outdated Show resolved Hide resolved
@levb
Copy link
Contributor Author

levb commented Jan 22, 2020

This is huge, I'm learning a lot.

Thanks, I did myself in the process. Go is very different from C where it comes to packaging code.

It's interesting -- you're using fields on structs (like in api) to carry parameters into methods, kind of like a context in a request... Yah, that is what you're doing. You're treating slash commands like http requests. Hah, nice. Once I figured that out it became a lot clearer. Maybe we can rename it to make this a bit more clear on first sight? What you're doing feels like it's overloading the meaning of an api struct -- because in other places we've used just to hold api methods or helper methods. This is more like a context.

My thinking - I'd like us to converge at some point in the future where there is a structure like

  • api - core logic
  • remote/... - anything with upstream backends (including workflow client-plugin-side code?)
  • store - persistence (basic, NO logic, mostly for easier mocking)

HTTP and Command interfaces really ought to become one at some point. I'd love for a senior community member/candidate to write an AST-based generator for these, with logging and all. With some creativity.

I am also hesitant to do much there until the HTTP endpoints are actually written and used - we'll see the best packaging then? I don't like the use of gorilla/mux for instance; other things aside it necessitates playing games with Context. One way would be to just rely on Context for everything but my understanding was that it was discouraged when it was designed. Anyway, I feel like it's something to solve later.

I'm using the demo code as examples -- if we're going to push to community we definitely need thorough explanations for the commands, and formatted examples. Like: Here are the steps to set up a team, set up an icebreaker event, set up a SET, give someone time off. The rotation commands are particularly difficult, I think.

I filed #11 to create a README. I agree that the documentation and "template use cases" are needed.

As far as improving the overall usability of the CLI, I suggest we wait until we gather experience on community. Having said that, there is one obvious improvement I'd like to make, and that is to rely on parameters (not flags) for rotation, user, and shift references, via a normalized syntax. Anything that is a @.+ is a user, anything that is a \w#[0-9]+ is a shift reference, anything else is a regexp on the rotation name. I'll think about it some more and file a HW ticket.

FWIW, I have mixed feelings at best about pflag, but nothing specific yet.

Is there a way to specify a rotation that has randomness but makes sure that all eligible people are picked i times before someone is picked for their i+1th time? Because that's how I imagine the ice-breaker should work.

No, but there is now separation of concern that should allow for an easy development of a queue Autofiller, which can keep its own persistence, and have its own logic if it wants to be smarter than a simple queue.

Separately, the current userWeight function in solarloterry only takes the LastServed into account. Once user's history is saved (a large-size new ticket?) it should be fully taken into account for scoring. I am still researching and thinking about how to best implement that. It may be the single best remaining improvement to the algorithm itself; its efficiency matters less than fairness IMO.

  • the box profile pic is Jira's

#16

@levb levb requested a review from cpoile January 22, 2020 20:06
@levb
Copy link
Contributor Author

levb commented Jan 22, 2020

@cpoile @crspeller I think I addressed both of yours feedback. I took the liberty of resolving the threads that I felt were done, to keep the PR manageable, feel free to reopen as appropriate.

I filed a bunch of follow up tickets, but the biggest obstacles to the community deployment in my mind are:

Copy link

@crspeller crspeller left a comment

Choose a reason for hiding this comment

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

Lots of little comments. The biggest thing is some architectural changes we chatted about. I tagged some of them with inline comments.

Lots of stuff to like in here! The server could use the expand semantics....

Will take another look after the big changes.

server/api/api.go Outdated Show resolved Hide resolved
server/http/http.go Outdated Show resolved Hide resolved
server/plugin/plugin.go Outdated Show resolved Hide resolved
server/plugin/plugin.go Outdated Show resolved Hide resolved
server/plugin/plugin.go Show resolved Hide resolved
server/command/rotation_add.go Show resolved Hide resolved

// Mandatory attributes
Name string
Period string

Choose a reason for hiding this comment

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

Why not use time.Duration for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is tricky. To start with, a "month" is not a duration. I am treating weeks like they are, but they really are not and all these should be treated similarly, by properly calculating start/end using the calendar math.

server/store/rotation_store.go Show resolved Hide resolved
server/api/period.go Outdated Show resolved Hide resolved
server/api/shift_api.go Outdated Show resolved Hide resolved
@levb
Copy link
Contributor Author

levb commented Jan 24, 2020

@crspeller, done.

  1. The Autofiller interface has to be defined in the solarlottery package, or it will create a circular dependency - it uses sl entities as parameters, and is needed by sl itself.
    I did create the tree though, moved Error there, much nicer. Also added a queue placeholder to show the intent. Also, since the top package name is always aliased to keep it short, I don't think duplicate names are an issue, thoughts?
  2. Thanks for suggesting renaming the test files, I ended up restructuring the code instead to match the tests, looks better now.
  3. Period/Duration is not a trivial matter, see my inline comment. Suggest leaving as is.

@levb levb requested a review from crspeller January 24, 2020 05:47
Copy link
Contributor

@cpoile cpoile left a comment

Choose a reason for hiding this comment

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

From the review last week, I can't see anything I would really want changed. We'll have to let it bake/shake-out on community for a bit.

Copy link

@crspeller crspeller left a comment

Choose a reason for hiding this comment

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

We could nitpick on this forever. It's a lot of code, so let's get it merged and start iterating on it. Once we get some real feedback we can improve the design. I think the overall design is good and it's already staring to bleed into our other plugins :D

@levb
Copy link
Contributor Author

levb commented Feb 6, 2020

I'm going to merge to master as is, and log a PM review ticket for the community deployment milestone, specifically after there's a README.

@levb levb added 4: Reviews Complete All reviewers have approved the pull request and removed 1: PM Review Requires review by a product manager 2: Dev Review Requires review by a core committer labels Feb 6, 2020
@levb levb added this to the v0.1 - community milestone Feb 6, 2020
@levb levb merged commit 58994fe into master Feb 6, 2020
@levb levb deleted the dev branch February 6, 2020 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4: Reviews Complete All reviewers have approved the pull request QA Review Done PR has been approved by QA
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants