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

Make background tasks lazy #95

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## HEAD

- Fix: Background task name lookup is now lazy, this fixes a bug when using `:::>- pre.erb background.start(...)` (https://github.com/zombocom/rundoc/pull/95)

## 4.1.1

- Fix: Visibility forwarding for `pre.erb` was accidentally reversed, this is now fixed. (https://github.com/zombocom/rundoc/pull/93)
Expand Down
9 changes: 7 additions & 2 deletions lib/rundoc/code_command/background/log/clear.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
class Rundoc::CodeCommand::Background::Log
class Clear < Rundoc::CodeCommand
def initialize(name:)
@spawn = Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
@name = name
@background = nil
end

def background
@background ||= Rundoc::CodeCommand::Background::ProcessSpawn.find(@name)
end

def to_md(env = {})
""
end

def call(env = {})
@spawn.log.truncate(0)
background.log.truncate(0)
""
end
end
Expand Down
9 changes: 7 additions & 2 deletions lib/rundoc/code_command/background/log/read.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
class Rundoc::CodeCommand::Background::Log
class Read < Rundoc::CodeCommand
def initialize(name:)
@spawn = Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
@name = name
@background = nil
end

def background
@background ||= Rundoc::CodeCommand::Background::ProcessSpawn.find(@name)
end

def to_md(env = {})
""
end

def call(env = {})
@spawn.log.read
background.log.read
end
end
end
Expand Down
32 changes: 20 additions & 12 deletions lib/rundoc/code_command/background/start.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,43 @@
class Rundoc::CodeCommand::Background
class Start < Rundoc::CodeCommand
def initialize(command, name:, wait: nil, timeout: 5, log: Tempfile.new("log"), out: "2>&1", allow_fail: false)
@timeout = timeout
@command = command
@name = name
@wait = wait
@allow_fail = allow_fail
FileUtils.touch(log)
@log = log
@redirect = out
FileUtils.touch(@log)

@spawn = ProcessSpawn.new(
@background = nil
end

def background
@background ||= ProcessSpawn.new(
@command,
timeout: timeout,
log: log,
out: out
)
puts "Spawning commmand: `#{@spawn.command}`"
ProcessSpawn.add(@name, @spawn)
timeout: @timeout,
log: @log,
out: @redirect
).tap do |spawn|
puts "Spawning commmand: `#{spawn.command}`"
ProcessSpawn.add(@name, spawn)
end
end

def to_md(env = {})
"$ #{@command}"
end

def call(env = {})
@spawn.wait(@wait)
@spawn.check_alive! unless @allow_fail
background.wait(@wait)
background.check_alive! unless @allow_fail

@spawn.log.read
background.log.read
end

def alive?
!!@spawn.alive?
!!background.alive?
end
end
end
Expand Down
11 changes: 8 additions & 3 deletions lib/rundoc/code_command/background/stdin_write.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ class StdinWrite < Rundoc::CodeCommand
def initialize(contents, name:, wait:, timeout: 5, ending: $/)
@contents = contents
@ending = ending
@spawn = Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
@wait = wait
@name = name
@timeout_value = Integer(timeout)
@contents_written = nil
@background = nil
end

def background
@background ||= Rundoc::CodeCommand::Background::ProcessSpawn.find(@name)
end

# The command is rendered (`:::>-`) by the output of the `def call` method.
Expand All @@ -20,11 +25,11 @@ def to_md(env = {})
# The contents produced by the command (`:::->`) are rendered by the `def to_md` method.
def call(env = {})
writecontents
@spawn.log.read
background.log.read
end

def writecontents
@contents_written ||= @spawn.stdin_write(
@contents_written ||= background.stdin_write(
contents,
wait: @wait,
ending: @ending,
Expand Down
11 changes: 8 additions & 3 deletions lib/rundoc/code_command/background/stop.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
class Rundoc::CodeCommand::Background
class Stop < Rundoc::CodeCommand
def initialize(name:)
@spawn = Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
@name = name
@background = nil
end

def background
@background ||= Rundoc::CodeCommand::Background::ProcessSpawn.find(@name)
end

def to_md(env = {})
""
end

def call(env = {})
@spawn.stop
@spawn.log.read
background.stop
background.log.read
end
end
end
Expand Down
9 changes: 7 additions & 2 deletions lib/rundoc/code_command/background/wait.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
class Rundoc::CodeCommand::Background
class Wait < Rundoc::CodeCommand
def initialize(name:, wait:, timeout: 5)
@spawn = Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
@name = name
@wait = wait
@timeout_value = Integer(timeout)
@background = nil
end

def background
@background ||= Rundoc::CodeCommand::Background::ProcessSpawn.find(name)
end

def to_md(env = {})
""
end

def call(env = {})
@spawn.wait(@wait, @timeout_value)
background.wait(@wait, @timeout_value)
""
end
end
Expand Down
16 changes: 10 additions & 6 deletions test/rundoc/code_commands/background_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ class BackgroundTest < Minitest::Test
def test_stdin_with_cat_echo
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
background_start = Rundoc::CodeCommand::Background::Start.new("cat",
name: "cat")
background_start.call

output = Rundoc::CodeCommand::Background::StdinWrite.new(
# Intentionally out of order, should not raise an error as long as "cat"
# command exists at execution time
stdin_write = Rundoc::CodeCommand::Background::StdinWrite.new(
"hello there",
name: "cat",
wait: "hello"
).call
)

background_start = Rundoc::CodeCommand::Background::Start.new("cat",
name: "cat")

background_start.call
output = stdin_write.call
assert_equal("hello there" + $/, output)

Rundoc::CodeCommand::Background::Log::Clear.new(
Expand Down
Loading