Skip to content

Use a stageJoiner to join stages together#59

Open
mhagger wants to merge 4 commits into
moar-streamsfrom
stage-joiner
Open

Use a stageJoiner to join stages together#59
mhagger wants to merge 4 commits into
moar-streamsfrom
stage-joiner

Conversation

@mhagger

@mhagger mhagger commented Jun 14, 2026

Copy link
Copy Markdown
Member

The old code used a stageStarter type to help with starting up stages. There are two awkward things about that approach:

  • The pipe that is needed to join stages depends on the two adjacent stages, not on the stdin and stdout of a single stage. So stageStarter wasn't able to figure out what pipe was needed; that logic kindof needed to live in the Pipeline type.

  • Since the read and write ends of a pipe are created together, the stageStarter could also not be as helpful in closing those streams if there was an error.

So instead, use a new helper type, stageJoiner, to figure out how to join two adjacent stages together. The stageJoiner can now do part of the work for us:

  • stageJoiner.validate() checks that the adjacent stages' requirements are met WRT whether they need stdin/stdout to be supplied at all.

  • stageJoiner.createPipe() figures out what kind of pipe to create for the two adjacent stages.

  • stageJoiner.closePipe() closes the pipe (if it has already been created and needs closing) on errors.

This also removes most of the need for special-casing the last stage.

/cc @znull

@mhagger mhagger force-pushed the moar-streams branch 2 times, most recently from 56b4c3f to 07cbbcf Compare June 14, 2026 14:19
mhagger added 4 commits June 14, 2026 16:21
The two aspects of a stage's stream requirements are coupled. For
example, of the four possible combinations of `(StreamRequirement,
NeedsFile)`, one of them, `(StreamForbidden, true)`, makes no sense.

So instead of encoding these two aspects separately, encode the three
meaningful combinations into a single `StreamRequirement` type with
possible values `StreamAcceptAny`, `StreamPreferFile`, and
`StreamForbidden`.
The old code used a `stageStarter` type to help with starting up
stages. There are two awkward things about that approach:

* The pipe that is needed to join stages depends on the two adjacent
  stages, not on the stdin and stdout of a single stage. So
  `stageStarter` wasn't able to figure out what pipe was needed; that
  logic kindof needed to live in the `Pipeline` type.

* Since the read and write ends of a pipe are created together, the
  `stageStarter` could also not be as helpful in closing those streams
  if there was an error.

So instead, use a new helper type, `stageJoiner`, to figure out how to
join two adjacent stages together. The `stageJoiner` can now do part
of the work for us:

* `stageJoiner.validate()` checks that the adjacent stages'
  requirements are met WRT whether they need stdin/stdout to be
  supplied at all.

* `stageJoiner.createPipe()` figures out what kind of pipe to create
  for the two adjacent stages.

* `stageJoiner.closePipe()` closes the pipe (if it has already been
  created and needs closing) on errors.

This isn't a panacea; for example, some loops have to iterate over
stages, and some over stage joiners. But I think that it's less
confusing this way.
@mhagger mhagger marked this pull request as ready for review June 14, 2026 14:28
@mhagger mhagger requested a review from a team as a code owner June 14, 2026 14:28
Copilot AI review requested due to automatic review settings June 14, 2026 14:28

Copilot AI 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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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