amnu3387
Hey, perhaps someone ran into this before and can help me out. Basically I’m opening a port that runs a bash script for launching chrome. It works fine on my local mac, chrome gets started, when the Port is sent Process.exit(pid, :normal), the chrome instance is killed.
Now I’ve deployed this umbrella app to ubuntu, it’s working, but chrome instances are not being killed when I .exit() the process. Any ideas?
#!/bin/sh
google-chrome --attrs --flag-switches-begin --headless --disable-gpu --remote-debugging-port="$1" --user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36" --user-data-dir=/dev/null --disable-extensions --disable-internal-flash --disable-bundled-ppapi-flash --incognito --ignore-certificate-errors --noerrdialogs --enable-internal-media-session --flag-switches-end & pid=$!
while read line ; do
:
done
kill -KILL $pid
And what calls that script:
def handle_cast({:start_session, reference, %{"pageUrl" => page_url}}, %{session: false} = state) do
IO.puts("Hound :start_session for reference: #{inspect page_url}")
port = find_available_port()
path = Path.absname(chrome_path(), Application.app_dir(:app_chrome))
chrome = Port.open({:spawn_executable, path},
[:binary, :use_stdio, :stderr_to_stdout, :exit_status, args: ["#{port}"]])
full_page_url = base_url() <> page_url
{:os_pid, pid} = Port.info(chrome, :os_pid)
case Regex.named_captures(~r/listening\son\s?(?<url>.*)\s/, handle_output(chrome)) do
%{"url" => url} ->
GenServer.cast(ChannelerServer, {:start_socket, %{port: port, reference: reference, page_url: full_page_url}})
GenServer.call(HoundKeeper, {:update, reference, chrome, pid, port, url}, 60_000)
_ -> {:error, "Not Active"}
end
{:noreply, state}
end
Ubuntu is 16.04
Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.5.2
Any ideas? Thanks
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
From my testing when headless was in beta is that chrome can still attach to another running session if it is called, so calling that could fork out to something the script no longer sees. From what I recall, if you want to safely shutdown a chrome headless instance then you need to tell it to do so itself. This could all be wrong now that it is released now though. ^.^;
amnu3387
I’m not entirely sure I’m following LOL
So say I want to kill an OS process from elixir, is there any system command for that or I’m better off running another shell script that just executes
kill -9 "$1"?I just thought it would have the same behaviour as in macosx (perhaps a bit naively)
OvermindDL1
The problem is not killing off an OS process,
killis just fine for that, it is that chrome often forks itself to new PID’s so the one you tried to kill actually does not belong to chrome any longer (it might even belong to something else).So yes, for a generic program that script is fine, however chrome is not a generic program, most specifically when running with
--remote-debugging-port=...as it will try to stay persistant. Thus to stop chrome properly you should notkillit (as it may often not work due to it forking away into new processes), but rather you need to send the ‘close’ signal to that port that you set up via--remote-debugging-portargument.Honestly you should probably write either a node script using the javascript API that google made to interact with it, or write a C++ program and use the C++ library that google made to interact with it, whichever you use ‘that’ is what you’d call from a Port in elixir. Yes chrome is weird (it should just handle it on stdin/stdout to be honest), but you have to use it’s API that you exposed at that port to properly shut it down,
killing chrome does not always work as you see.amnu3387
Yes, again my misunderstanding stems from the fact that in macosx killing the process that originated the debbuger will also close the main chrome instance and the debugger with no further forking. I’m being a bit lazy in reality, but if I could get away with it closing “automagically” I would lol! I’m not sure how using the node library helps, since it’s just a wrapper for the devtools protocol? Thanks either way, I’m gonna shut it down manually
OvermindDL1
Same in linux, however it is ‘chrome’ itself that likes to fork around depending on what other instances of it are running and so forth.
Yep, that’s all it does too. If you are already talking to the chrome debugger over it’s port, just order it to shut down.
You could do it from your shell script too, either a node command or just perl/curl/whatever the command over that port. Or even scan for the PID that is on that port and kill ‘that’ pid. ^.^
keathley
Wallaby manages all of this for you (no need for node or C++). You can look at what we did and port it to your hound setup.
amnu3387
Hi keathley, I did try wallaby and hound, I ended up not using either because I was unable to keep multiple sessions alive (say 20 sessions sitting for an arbitrary number of minutes on a page), with individual devtools debugger for each session (so 20 different pages, independent sessions, each one with an individual debugger attached for anywhere between 5min to 15min, sometimes more)? If you know that that can be achieved with wallaby, running chrome, I’m all to use what you guys already did.
I will indeed take a look at how you got it working, I was thinking “Browser.close” through the wire would suffice, but “devtools” is telling me:
%{"error" => %{"code" => -32601, "message" => "'Browser.close' wasn't found"}, "id" => 999}Thanks
amnu3387
Sharing what I found while researching and solving my issues with this, In case anybody needs some solutions for dealing with misbehaving ports/processes outside the beam - it’s a bit hacky, but hey, gets the work done on linux ubuntu and chromium instances.
First, use “kill” on the bash script itself, then have a function that aggregates recursively all the PIDS, kill them, checks the cleanup and as last resort “kill -9” them. kill -9 on chromium processes on linux is a bad idea, although sometimes it won’t help to just do the standard kill, as the processes will remain running, so you’re basically left with having to make sure you catch them all. In my particular case I can’t pgrep/grep on the process name, as I need to kill specific instances of chromium at certain times, and not all running instances of chromium.
For the bash script
This will grep all processes that mention the &background command PID (so the main process itself and any other forked processes that reference it as the Parent PID). Sends them a kill signal, and a -9 to the main process alone. Xargs is parallel, so all processes grepped there will receive a regular kill before the parent receives a -9.
This should work most of the time, but chromium sometimes is nasty. So I added a new layer at the application level. Since I always pass an arbitrary non-repeated debugger port to the chromium instance I can use that to identify the processes I’m interested in finding. You can use whatever, and even pass non-existing flags to identify your chromium instances, since they keep it as part of the “command” attribute that was ran to create the process:
This doesn’t rely on the PID from the bashscript - I’m also grepping on something I’m sure is unique in my use case “port=an_arbitrary_port_that_I_had_set” can only match for what I want so I’m fine with the hackiness of it. You could also start chromium with a flag such as --my-marker-flag=something and then grepping on this. I call this method after I “close” the port.
Lastly since it involves long-lived, always running processes and I don’t want to risk having any of them creep, and even although it seems what I’ve added before is enough to keep it tamed and under control, I went a bit further and added a sweeper based on time that will kill any chromium/chrome processes running more than 40min, and I recurrently send_after to call this: