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

DEV-1096 - add a new "pipeline" concept #67

Merged
merged 34 commits into from
Apr 19, 2022
Merged

Conversation

torbensky
Copy link
Collaborator

@torbensky torbensky commented Mar 24, 2022

This PR adds a new concept called "pipelines" to the rules package. It is intended as a replacement for the "ruleset" concept. While Rulesets are still supported, the internal implementation of them has been re-written to be entirely Pipeline based, so there is no significant reason to continue using them in new code.

A "pipeline" is a series of "stage functions" which are executed in sequence, one after another, in order to modify a game state and produce a next game state. Pipelines can also be executed to initialise a game state and to check if a game has ended. The design of the pipeline system is intended to facilitate easy customization and extension of game modes. Each existing game mode has been broken down into a series of bite-sized logic, called "stages", so that the stages can be re-used in other game modes. For example, the logic to move snakes each turn is its own stage. Any other game type that wishes to have this type of movement behavior can simply include this stage.

Overview:

  • added new Pipeline type which is a series of stages
  • added a global registry of pipeline stages
  • re-wrote Ruleset internals to use Pipeline
  • full test coverage of new types/methods

- added new Pipeline type which is a series of stages
- added a global registry to facilitate plugin architecture
- 100% test coverage
@torbensky torbensky added the enhancement New feature or request label Mar 24, 2022
@codecov-commenter
Copy link

codecov-commenter commented Apr 5, 2022

Codecov Report

Merging #67 (02e5f10) into main (86ef6ad) will increase coverage by 2.10%.
The diff coverage is 91.81%.

@@            Coverage Diff             @@
##             main      #67      +/-   ##
==========================================
+ Coverage   65.67%   67.78%   +2.10%     
==========================================
  Files          12       13       +1     
  Lines         979      984       +5     
==========================================
+ Hits          643      667      +24     
+ Misses        316      309       -7     
+ Partials       20        8      -12     
Impacted Files Coverage Δ
board.go 96.15% <ø> (ø)
solo.go 83.33% <50.00%> (-16.67%) ⬇️
wrapped.go 85.71% <50.00%> (+12.74%) ⬆️
constrictor.go 82.35% <62.50%> (+3.78%) ⬆️
royale.go 97.22% <83.33%> (-2.78%) ⬇️
standard.go 97.59% <93.75%> (+2.90%) ⬆️
pipeline.go 100.00% <100.00%> (ø)
ruleset.go 100.00% <100.00%> (ø)
squad.go 100.00% <100.00%> (+6.34%) ⬆️

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@torbensky torbensky marked this pull request as ready for review April 11, 2022 17:27
@torbensky torbensky removed the request for review from chris-bsnake April 11, 2022 17:27
Copy link
Contributor

@robbles robbles left a comment

Choose a reason for hiding this comment

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

Looking good so far! Still have a few bits left to read through.

pipeline.go Show resolved Hide resolved
pipeline.go Outdated Show resolved Hide resolved
standard.go Outdated Show resolved Hide resolved
Copy link
Contributor

@robbles robbles left a comment

Choose a reason for hiding this comment

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

Tested integrating this into engine, and it works as expected! It was very easy to use with the PipelineRuleset interface.
Great work on this!

pipeline.go Outdated
for _, s := range stageNames {
fn, ok := registry[s]
if !ok {
return pipeline{err: errors.New("stage not found")}
Copy link
Contributor

Choose a reason for hiding this comment

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

It'll be handy for troubleshooting if this error includes the unknown stage name. Ran into this already during testing when I misspelled one and couldn't see it right away 😅 .

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, if you can make these errors a specific type, e.g. rules.RulesetError or a new type specific to Pipelines, then engine can detect these errors and return HTTP 400 and a better message for bad game creation requests.

It's not consistent, but we do this in a few places already:
https://github.com/BattlesnakeOfficial/rules/blob/main/board.go#L101

Copy link
Contributor

Choose a reason for hiding this comment

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

Realized just now that engine could definitely do this internally, since it knows when it's getting the error via rules, and the assumption is that any rules error on game creation is an invalid request from the client.
It's probably more consistent if rules returns a specific error type though?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

An error type is a good idea. I had originally setup the error message to include the stage name, but then I removed it because I wanted the error to be static for simpler comparison. But it did nag at me that it would be useful to know which stage caused the error. I think an error type would allow the best of both worlds - a convenient way to check for the error type and a clear message.

pipeline_internal_test.go Outdated Show resolved Hide resolved
StageFeedSnakesStandard,
StageSpawnFoodStandard,
StageEliminationStandard,
StageSpawnFoodNoFood,
Copy link
Contributor

Choose a reason for hiding this comment

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

Just noticed this - We have both spawn_food.standard and spawn_food.no_food stages - technically how it worked before, but probably redundant now?

Now I'm wondering if constrictor could just be implemented as this list without either stage?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

haha yeah - that is a bit silly!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh, I left spawn_food.no_food, but I'm seeing now that you mentioned we should remove it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll need to update some tests to handle that because there are a few that create initial board states with food and expect the ruleset to remove that

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

... although part of me feels safer with it still in there, just in case...

@robbles robbles merged commit d378759 into main Apr 19, 2022
@robbles robbles deleted the dev-1096-add-stage-pipeline branch April 19, 2022 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants