mirror of
https://github.com/l5yth/potato-mesh.git
synced 2026-10-30 19:41:58 +01:00
web,data: timeout specs hold their jobs on gates, not fixed sleeps (#1050)
This commit is contained in:
3 files changed
+42
-18
No files matched your search
@@ -126,10 +126,16 @@ def test_close_interface_respects_timeout(monkeypatch):
|
||||
|
||||
class SlowInterface:
|
||||
def close(self):
|
||||
blocker.wait(timeout=0.1)
|
||||
# Held until the test releases it, so the close still runs however
|
||||
# late the 0.01 s join returns. After 5 s it ends anyway, so a
|
||||
# _close_interface that waits for the close fails instead of hanging.
|
||||
blocker.wait(timeout=5.0)
|
||||
|
||||
daemon._close_interface(SlowInterface())
|
||||
assert any("timeout_seconds" in entry for entry in log_calls)
|
||||
try:
|
||||
daemon._close_interface(SlowInterface())
|
||||
assert any("timeout_seconds" in entry for entry in log_calls)
|
||||
finally:
|
||||
blocker.set()
|
||||
|
||||
|
||||
def test_close_interface_immediate_path(monkeypatch):
|
||||
|
||||
@@ -403,26 +403,30 @@ RSpec.describe "Federation crawl limits" do
|
||||
|
||||
it "lets the worker pool's task timeout end a crawl" do
|
||||
fed.lists[hostile] = %w[p1 p2 p3 p4].map { |name| peers.record("#{name}.fed.invalid") }
|
||||
# The first request holds until the pool's task timeout interrupts it,
|
||||
# however late that fires, so the crawl cannot go on by itself. After 5 s
|
||||
# it ends anyway, so a pool and a wait that both ignore their timeouts
|
||||
# fail, not hang.
|
||||
gate = Queue.new
|
||||
first = true
|
||||
fed.hooks << lambda do |_entry|
|
||||
if first
|
||||
first = false
|
||||
sleep 0.6
|
||||
gate.pop(timeout: 5)
|
||||
end
|
||||
end
|
||||
worker_pool = PotatoMesh::App::WorkerPool.new(size: 1, max_queue: 2, task_timeout: 0.3, name: "spec-fl6")
|
||||
|
||||
task = worker_pool.schedule { crawl(hostile) }
|
||||
outcome = begin
|
||||
task.wait(timeout: 5)
|
||||
:completed
|
||||
rescue PotatoMesh::App::WorkerPool::TaskTimeoutError
|
||||
:timed_out
|
||||
ensure
|
||||
worker_pool.shutdown(timeout: 1, force_kill_after: 1)
|
||||
end
|
||||
begin
|
||||
# The pool's message: the wait's own deadline raises "task deadline
|
||||
# exceeded", which is no task timeout ending the crawl (SPEC FL6).
|
||||
expect { task.wait(timeout: 3) }.to raise_error(PotatoMesh::App::WorkerPool::TaskTimeoutError, "task exceeded timeout")
|
||||
ensure
|
||||
gate.close
|
||||
worker_pool.shutdown(timeout: 1, force_kill_after: 1)
|
||||
end
|
||||
|
||||
expect(outcome).to eq(:timed_out)
|
||||
expect(fed.total).to eq(1)
|
||||
end
|
||||
|
||||
|
||||
@@ -39,10 +39,17 @@ RSpec.describe PotatoMesh::App::WorkerPool do
|
||||
end
|
||||
|
||||
it "fails tasks that exceed the configured timeout" do
|
||||
gate = Queue.new
|
||||
with_pool(task_timeout: 0.01) do |pool|
|
||||
task = pool.schedule { sleep 0.05; :late }
|
||||
expect { task.wait(timeout: 1) }.to raise_error(described_class::TaskTimeoutError)
|
||||
# The job holds until the pool's task timeout interrupts it, however
|
||||
# late that fires. The message is the pool's: the wait's own deadline
|
||||
# raises "task deadline exceeded". After 5 s the job ends anyway, so a
|
||||
# pool and a wait that both ignore their timeouts fail, not hang.
|
||||
task = pool.schedule { gate.pop(timeout: 5); :late }
|
||||
expect { task.wait(timeout: 3) }.to raise_error(described_class::TaskTimeoutError, "task exceeded timeout")
|
||||
end
|
||||
ensure
|
||||
gate.close
|
||||
end
|
||||
|
||||
it "ignores invalid timeout values" do
|
||||
@@ -130,13 +137,20 @@ RSpec.describe PotatoMesh::App::WorkerPool do
|
||||
|
||||
describe PotatoMesh::App::WorkerPool::Task do
|
||||
it "raises a timeout when the job exceeds the provided deadline" do
|
||||
gate = Queue.new
|
||||
with_pool do |pool|
|
||||
task = pool.schedule { sleep 0.1; :done }
|
||||
# The job holds until the gate opens, so the first wait can only end
|
||||
# at its own deadline, however late it wakes. After 5 s the job ends
|
||||
# anyway, so a wait that ignores its deadline fails instead of hanging.
|
||||
task = pool.schedule { gate.pop(timeout: 5); :done }
|
||||
expect do
|
||||
task.wait(timeout: 0.01)
|
||||
end.to raise_error(PotatoMesh::App::WorkerPool::TaskTimeoutError)
|
||||
expect(task.wait(timeout: 1)).to eq(:done)
|
||||
end.to raise_error(PotatoMesh::App::WorkerPool::TaskTimeoutError, "task deadline exceeded")
|
||||
gate << :open
|
||||
expect(task.wait(timeout: 5)).to eq(:done)
|
||||
end
|
||||
ensure
|
||||
gate.close
|
||||
end
|
||||
|
||||
it "reports completion status" do
|
||||
|
||||
Reference in new issue
Block a user