Open taylordowns2000 opened 6 years ago
In case it's useful, this is getting me 90% of the way there, but the process still shows up in the Exq.Api.processes(Process.whereis(Exq.Api))
tuple, and I get the [info] Re-enqueueing job from backup for node_id [taylor...] and queue [runs]
problem that others have faced.
def kill_process(process) do
Logger.info "Killing process."
Process.exit(IEx.Helpers.pid(process.pid |> String.replace(~r/[<>]/, "")), :kill)
Exq.Redis.JobStat.remove_process(Exq.Redis.Client, Application.get_env(:exq, :namespace), process, Exq.Support.Process.encode(process))
Exq.Stats.Server.process_terminated(Exq.Stats, Application.get_env(:exq, :namespace), process)
Exq.Stats.Server.record_failure(Exq.Stats, Application.get_env(:exq, :namespace), "I killed it.", process.job)
# Exq.Redis.Connection.flushdb!(Exq.Redis.Client)
end
I don't want to flushdb!
there at the end because that seems to drop everything from redis, not just the single job I killed. I've been scanning more issues and realizing that this is really similar to #305 .
To be honest, it still feels like I'm missing something obvious—like I'm trying to find a back door for something that should be straightforward! Apologies, again, if I'm just missing it.
you might want to check out Exq.Redis.JobQueue.remove_job_from_backup/5
defp extract_pid(process) do
process.pid |> String.replace(~r/[<>]/, "") |> IEx.Helpers.pid()
end
def kill_process(process) do
process
|> extract_pid()
|> Process.exit(:kill)
job_serialized =
process.job
|> Map.take(["queue", "retry", "class", "args", "jid", "enqueued_at"])
|> Exq.Support.Config.serializer.encode!()
Exq.Redis.JobQueue.remove_job_from_backup(
Exq.Redis.Client, Application.get_env(:exq, :namespace), process.host, process.job["queue"], job_serialized)
process_serialized =
process
|> Exq.Support.Config.serializer.encode!()
Exq.Redis.JobStat.remove_process(
Exq.Redis.Client, Application.get_env(:exq, :namespace), process, process_serialized)
Exq.Manager.Server.job_terminated(Exq, Application.get_env(:exq, :namespace), process.job["queue"], job_serialized)
end
Is it possible to kill a single processes (a busy worker) in Exq? I can generate a list of all the running processes with
Exq.Api.processess(Process.whereis(Exq.Api))
.If I get 10 results in that
{:ok, processes}
tuple, I'd like to be able to pick out the one that has been running for more than 10 minutes, say, and kill it while leaving the others running.Exq.Api.clear_processes(Process.whereis(Exq.Api))
works fine for clearing the whole list of processes, but when I pass in just thepid
of the bad/long-running process, it complains:If I manipulate that pid a bit I get:
And going further down this rabbit hole:
I'm really sorry if I've missed something in the docs, but I haven't been able to figure out how to kill (or configure Exq to automatically kill) processes that have been running for a long time. Ultimately, my objective here is to configure a queue that will kill anything that lasts more than X seconds.
Update: I found @akira 's helpful comment on #228 where he suggested
:timer.kill_after(:timer.seconds(600))
as a way to auto-kill long-running stuff. (Thank you!) Still wondering if it is possible to kill a single process by hand.Thanks in advance!