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

Add Process.run ?is_success to control definition of success #586

Merged
merged 1 commit into from
Jul 20, 2023

Conversation

SGrondin
Copy link
Collaborator

@SGrondin SGrondin commented Jul 19, 2023

Motivation

Some programs (ab)use exit codes in unconventional ways.

As an example I recently ran into: the npm outdated command checks a project's NPM dependencies and prints a status report (outdated, deprecations, etc).

But the exit code is 1 if any dependencies are in need of an update! While it successfully generated a status report, it still returned 1. Different return codes may indicate "true failures". I disagree with the design of this command, I'm not the only one and it's causing issues.

Regardless, this command is far from alone. Plenty of other programs behave in a similar way. Also, I may want to consider certain exit codes to be errors/success depending on the stdout output of the command, for example.

Suggestion

I suggest adding the following optional argument to Eio.Process.run: ?is_success:(int -> bool)

Since it runs after the process has exited, the user is able to inspect the output of stdout and stderr to make a decision.

But why not just call Eio.Process.spawn instead?

Eio.Process.run is a nicer interface, I wouldn't want to lose on (or have to recreate its) error handling. Most importantly though, Process.spawn is a leaky abstraction while Process.run is not. I don't have to stop and dig into Eio internals to use Process.run, I can quickly invoke it without breaking mental focus.

Adding is_success minimizes the number of use cases that require Process.spawn and (in my opinion) is a nice addition to Process.run that doesn't significantly increase complexity for the users nor maintainers.

PR suggestions > Issue suggestions, am I right? 😄

Copy link
Collaborator

@talex5 talex5 left a comment

Choose a reason for hiding this comment

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

Thanks, this looks useful! We should probably do the same for parse_out.

lib_eio/process.ml Outdated Show resolved Hide resolved
tests/process.md Outdated Show resolved Hide resolved
@SGrondin
Copy link
Collaborator Author

Thanks for the review @talex5
For parse_out do you think it would be better to also add the argument to await_exn (which is exposed in the .mli) or just to parse_out itself?

@talex5
Copy link
Collaborator

talex5 commented Jul 19, 2023

For parse_out do you think it would be better to also add the argument to await_exn (which is exposed in the .mli) or just to parse_out itself?

Adding to await_exn (as an optional argument) makes sense to me.

@SGrondin
Copy link
Collaborator Author

All done, feel free to edit the .mli docs/comments, it was difficult to phrase

Copy link
Collaborator

@talex5 talex5 left a comment

Choose a reason for hiding this comment

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

All done, feel free to edit the .mli docs/comments, it was difficult to phrase

I pushed some minor changes (and also added another test).

Ready to merge once CI passes - thanks!

@talex5 talex5 changed the title Feature request: control over Process.run success Add Process.run ?is_success to control definition of success Jul 20, 2023
@talex5 talex5 merged commit e10e176 into ocaml-multicore:main Jul 20, 2023
4 checks passed
@SGrondin SGrondin deleted the process-exit-success branch July 20, 2023 11:34
talex5 added a commit to talex5/opam-repository that referenced this pull request Aug 29, 2023
CHANGES:

New features / API changes:

- Replace objects with variants (@talex5 @patricoferris ocaml-multicore/eio#553 ocaml-multicore/eio#605 ocaml-multicore/eio#608, reviewed by @avsm).
  Some potential users found object types confusing, so we now use an alternative scheme for OS resources.
  For users of the resources, the only thing that changes is the types:

  - Instead of taking an argument of type `#foo`, you should now take `_ foo`.
  - Instead of returning a value of type `foo`, you should now return `foo_ty Eio.Resource.t`.

  To provide your own implementation of an interface, you now provide a module rather than an object.
  For example, to provide your own source flow, use `Eio.Flow.Pi.source (module My_source)`.

  If you want to define your own interfaces, see the `Eio.Resource` module documentation.

- Add `Eio.Pool` (@talex5 @darrenldl ocaml-multicore/eio#602, reviewed by @patricoferris).
  A lock-free pool of resources. This is similar to `Lwt_pool`.

- Add `Eio.Lazy` (@talex5 ocaml-multicore/eio#609, reviewed by @SGrondin).
  If one fiber tries to force a lazy value while another is already doing it,
  this will wait for the first one to finish rather than raising an exception (as `Stdlib.Lazy` does).

- Add `Eio.Path.native` (@talex5 ocaml-multicore/eio#603, reviewed by @patricoferris).
  This is useful when interacting with non-Eio libraries, for spawning sub-processes, and for displaying paths to users.

- Add `Flow.single_write` (@talex5 ocaml-multicore/eio#598).

- Add `Eio.Flow.Pi.simple_copy` (@talex5 ocaml-multicore/eio#611).
  Provides an easy way to implement the `copy` operation when making your own sink.

- Eio_unix: add FD passing (@talex5 ocaml-multicore/eio#522).
  Allows opening a file and passing the handle over a Unix-domain socket.

- Add `Process.run ?is_success` to control definition of success (@SGrondin ocaml-multicore/eio#586, reviewed by @talex5).

- Add `Eio_mock.Domain_manager` (@talex5 ocaml-multicore/eio#610).
  This mock domain manager runs everything in a single domain, allowing tests to remain deterministic.

- Add `Eio.Debug.with_trace_prefix` (@talex5 ocaml-multicore/eio#610).
  Allows prefixing all `traceln` output. The mock domain manager uses this to indicate which fake domain is running.

Bug fixes:

- Fork actions must not allocate (@talex5 ocaml-multicore/eio#593).
  When using multiple domains, child processes could get stuck if they forked while another domain held the malloc lock.

- eio_posix: ignore some errors writing to the wake-up pipe (@talex5 ocaml-multicore/eio#600).
  If the pipe is full or closed, the wake-up should simply be ignored.

Build/test fixes:

- Fix some MDX problems on Windows (@polytypic ocaml-multicore/eio#597).

- The README depends on kcas (@talex5 ocaml-multicore/eio#606).

- Clarify configuration for lib_eio_linux and enable tests on other arches (@dra27 ocaml-multicore/eio#592).

- eio_linux tests: skip fixed buffer test if not available (@talex5 ocaml-multicore/eio#604).

- eio_windows: update available line to win32 (@talex5 ocaml-multicore/eio#588 ocaml-multicore/eio#591).
talex5 added a commit to talex5/opam-repository that referenced this pull request Aug 29, 2023
CHANGES:

New features / API changes:

- Replace objects with variants (@talex5 @patricoferris ocaml-multicore/eio#553 ocaml-multicore/eio#605 ocaml-multicore/eio#608, reviewed by @avsm).
  Some potential users found object types confusing, so we now use an alternative scheme for OS resources.
  For users of the resources, the only thing that changes is the types:

  - Instead of taking an argument of type `#foo`, you should now take `_ foo`.
  - Instead of returning a value of type `foo`, you should now return `foo_ty Eio.Resource.t`.

  To provide your own implementation of an interface, you now provide a module rather than an object.
  For example, to provide your own source flow, use `Eio.Flow.Pi.source (module My_source)`.

  If you want to define your own interfaces, see the `Eio.Resource` module documentation.

- Add `Eio.Pool` (@talex5 @darrenldl ocaml-multicore/eio#602, reviewed by @patricoferris).
  A lock-free pool of resources. This is similar to `Lwt_pool`.

- Add `Eio.Lazy` (@talex5 ocaml-multicore/eio#609, reviewed by @SGrondin).
  If one fiber tries to force a lazy value while another is already doing it,
  this will wait for the first one to finish rather than raising an exception (as `Stdlib.Lazy` does).

- Add `Eio.Path.native` (@talex5 ocaml-multicore/eio#603, reviewed by @patricoferris).
  This is useful when interacting with non-Eio libraries, for spawning sub-processes, and for displaying paths to users.

- Add `Flow.single_write` (@talex5 ocaml-multicore/eio#598).

- Add `Eio.Flow.Pi.simple_copy` (@talex5 ocaml-multicore/eio#611).
  Provides an easy way to implement the `copy` operation when making your own sink.

- Eio_unix: add FD passing (@talex5 ocaml-multicore/eio#522).
  Allows opening a file and passing the handle over a Unix-domain socket.

- Add `Process.run ?is_success` to control definition of success (@SGrondin ocaml-multicore/eio#586, reviewed by @talex5).

- Add `Eio_mock.Domain_manager` (@talex5 ocaml-multicore/eio#610).
  This mock domain manager runs everything in a single domain, allowing tests to remain deterministic.

- Add `Eio.Debug.with_trace_prefix` (@talex5 ocaml-multicore/eio#610).
  Allows prefixing all `traceln` output. The mock domain manager uses this to indicate which fake domain is running.

Bug fixes:

- Fork actions must not allocate (@talex5 ocaml-multicore/eio#593).
  When using multiple domains, child processes could get stuck if they forked while another domain held the malloc lock.

- eio_posix: ignore some errors writing to the wake-up pipe (@talex5 ocaml-multicore/eio#600).
  If the pipe is full or closed, the wake-up should simply be ignored.

Build/test fixes:

- Fix some MDX problems on Windows (@polytypic ocaml-multicore/eio#597).

- The README depends on kcas (@talex5 ocaml-multicore/eio#606).

- Clarify configuration for lib_eio_linux and enable tests on other arches (@dra27 ocaml-multicore/eio#592).

- eio_linux tests: skip fixed buffer test if not available (@talex5 ocaml-multicore/eio#604).

- eio_windows: update available line to win32 (@talex5 ocaml-multicore/eio#588 ocaml-multicore/eio#591).
nberth pushed a commit to nberth/opam-repository that referenced this pull request Jun 18, 2024
CHANGES:

New features / API changes:

- Replace objects with variants (@talex5 @patricoferris ocaml-multicore/eio#553 ocaml-multicore/eio#605 ocaml-multicore/eio#608, reviewed by @avsm).
  Some potential users found object types confusing, so we now use an alternative scheme for OS resources.
  For users of the resources, the only thing that changes is the types:

  - Instead of taking an argument of type `#foo`, you should now take `_ foo`.
  - Instead of returning a value of type `foo`, you should now return `foo_ty Eio.Resource.t`.

  To provide your own implementation of an interface, you now provide a module rather than an object.
  For example, to provide your own source flow, use `Eio.Flow.Pi.source (module My_source)`.

  If you want to define your own interfaces, see the `Eio.Resource` module documentation.

- Add `Eio.Pool` (@talex5 @darrenldl ocaml-multicore/eio#602, reviewed by @patricoferris).
  A lock-free pool of resources. This is similar to `Lwt_pool`.

- Add `Eio.Lazy` (@talex5 ocaml-multicore/eio#609, reviewed by @SGrondin).
  If one fiber tries to force a lazy value while another is already doing it,
  this will wait for the first one to finish rather than raising an exception (as `Stdlib.Lazy` does).

- Add `Eio.Path.native` (@talex5 ocaml-multicore/eio#603, reviewed by @patricoferris).
  This is useful when interacting with non-Eio libraries, for spawning sub-processes, and for displaying paths to users.

- Add `Flow.single_write` (@talex5 ocaml-multicore/eio#598).

- Add `Eio.Flow.Pi.simple_copy` (@talex5 ocaml-multicore/eio#611).
  Provides an easy way to implement the `copy` operation when making your own sink.

- Eio_unix: add FD passing (@talex5 ocaml-multicore/eio#522).
  Allows opening a file and passing the handle over a Unix-domain socket.

- Add `Process.run ?is_success` to control definition of success (@SGrondin ocaml-multicore/eio#586, reviewed by @talex5).

- Add `Eio_mock.Domain_manager` (@talex5 ocaml-multicore/eio#610).
  This mock domain manager runs everything in a single domain, allowing tests to remain deterministic.

- Add `Eio.Debug.with_trace_prefix` (@talex5 ocaml-multicore/eio#610).
  Allows prefixing all `traceln` output. The mock domain manager uses this to indicate which fake domain is running.

Bug fixes:

- Fork actions must not allocate (@talex5 ocaml-multicore/eio#593).
  When using multiple domains, child processes could get stuck if they forked while another domain held the malloc lock.

- eio_posix: ignore some errors writing to the wake-up pipe (@talex5 ocaml-multicore/eio#600).
  If the pipe is full or closed, the wake-up should simply be ignored.

Build/test fixes:

- Fix some MDX problems on Windows (@polytypic ocaml-multicore/eio#597).

- The README depends on kcas (@talex5 ocaml-multicore/eio#606).

- Clarify configuration for lib_eio_linux and enable tests on other arches (@dra27 ocaml-multicore/eio#592).

- eio_linux tests: skip fixed buffer test if not available (@talex5 ocaml-multicore/eio#604).

- eio_windows: update available line to win32 (@talex5 ocaml-multicore/eio#588 ocaml-multicore/eio#591).
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