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

Spawned procs should inherit goreman's stdin #140

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

corasaurus-hex
Copy link

Processes spawned via foreman inherit stdin from it. You can test this like so:

❯ cat Procfile
web: echo "Hello, $(read user; echo $user)"

❯ foreman start
23:16:12 web.1  | started with pid 91492
cora
23:16:14 web.1  | Hello, cora
23:16:15 web.1  | exited with code 0
23:16:15 system | sending SIGTERM to all processes

Why does this matter? Because some things care if stdin is a TTY or /dev/null (the previous stdin value for all launched procs):

❯ cora-goreman start watch
23:19:17 watch | Starting watch on port 5000
23:19:17 watch | > dev
23:19:17 watch | > npx tailwindcss -i ./app/assets/stylesheets/engine/tailwind-input.css -o ./app/assets/builds/tailwind.css --watch
23:19:18 watch | Rebuilding...
23:19:18 watch | Done in 167ms.
^C23:19:31 watch | Terminating watch

❯ /opt/homebrew/bin/goreman start watch
23:20:35 watch | Starting watch on port 5000
23:20:35 watch | > dev
23:20:35 watch | > npx tailwindcss -i ./app/assets/stylesheets/engine/tailwind-input.css -o ./app/assets/builds/tailwind.css --watch
23:20:35 watch | Terminating watch

You could always redirect /dev/null into your processes if that's what you want but forcing them to inherit your terminal's TTY is impossible if goreman is inserting /dev/null as stdin and so I think this is the better default.

Thoughts?

@mattn
Copy link
Owner

mattn commented Mar 30, 2023

web1: echo "Hello, $(read user; echo $user)"
web2: echo "Hello, $(read user; echo $user)"
web3: echo "Hello, $(read user; echo $user)"

What happen for this? It is not guaranteed which one will be called first?

@corasaurus-hex
Copy link
Author

Yep, there are no guarantees, the point is not to guarantee which tool gets to read from stdin the point is to 1. match how foreman works, 2. provide for tools that expect to be run via a tty.

@corasaurus-hex
Copy link
Author

My example was to demonstrate that the processes foreman starts inherit foreman's stdin, not to enable some kind of specific ordering of stdin behavior.

@mattn
Copy link
Owner

mattn commented Mar 30, 2023

Is it a specification that foreman handles standard input? If so, please show me the specification or the source code that intentionally implements it. I can't implement it without specification.

@corasaurus-hex
Copy link
Author

Here's the code: https://github.com/ddollar/foreman/blob/1445adc429d79b5b3dd1d54cf9dcb75d253c924f/lib/foreman/process.rb#L54

Foreman uses Process.spawn and redirects both stdout and stderr to the same destination. If you don't set a value for :in it will inherit the stdin of the current process that is calling Process.spawn.

Since the docs for Process.spawn are so crap and what it's doing is using posix spawn under the hood with file descriptor inheritance here's a demonstration that you can try that proves that not specifying an stdin for a spawned process means the process inherits the spawning process' stdin:

❯ cat test_stdin_inherited.rb
#!/usr/bin/env ruby

require 'time'

current_process_pid = $$

pid = Process.spawn("bash greet_user.sh", :out => $stdout, :err => $stdout)

puts "#{$0} - #{Time.now.iso8601} - #{current_process_pid} - Waiting on process #{pid} to exit!"

Process.waitpid(pid)

puts "#{$0} - #{Time.now.iso8601} - #{current_process_pid} - Process #{pid} exited!"

❯ cat greet_user.sh
#!/bin/sh

pid=$$

read -p "$0 - $(date -Iseconds) - $pid - What is your name? " user

echo "$0 - $(date -Iseconds) - $pid - Hello, $user"

❯ ruby test_stdin_inherited.rb
test_stdin_inherited.rb - 2023-03-30T11:48:05-05:00 - 37677 - Waiting on process 37774 to exit!
greet_user.sh - 2023-03-30T11:48:05-05:00 - 37774 - What is your name? Cora
greet_user.sh - 2023-03-30T11:48:08-05:00 - 37774 - Hello, Cora
test_stdin_inherited.rb - 2023-03-30T11:48:08-05:00 - 37677 - Process 37774 exited!

Tada! Proof that foreman spawns processes such that they all inherit stdin from the main foreman process. I've also demonstrated that this matters to some processes.

@joeblew99
Copy link

is this going forward ? stdin is really useful feature. I guess you would all agree.

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.

3 participants