Skip to content

Instantly share code, notes, and snippets.

@emad-elsaid
Created October 28, 2018 13:00
Show Gist options
  • Save emad-elsaid/c059b48191bde7030f34aa77b35bc304 to your computer and use it in GitHub Desktop.
Save emad-elsaid/c059b48191bde7030f34aa77b35bc304 to your computer and use it in GitHub Desktop.
require 'sinatra'
set :port, 3000
TEMPLATE = DATA.read
class Async
# execute a block identified by `id` synchronously if block is done returns
# the block return value if not finished it returns the `default` value the
# if the `id` id not provided it uses the block source location as an id
# Example:
# having a long running script calling
# `Asybc.command { `ssh user@ip-address ps`}`
# will return nil immediatly until the server responds with the `ps` output,
# only then that line will return the output.
# this pattern is useful if you have a long running server that needs to do
# alot of async operations and aggregate the response of whatever returned,
# and refreshes the result periodically, allowing you to render the result and
# update it on periods
def self.command(id: nil, default: nil, &block)
id ||= block.source_location
result(id, default, &block) || default
end
def self.result(id, default, &block)
create(id, default, &block) || get(id)
end
def self.create(id, default, &block)
@commands ||= {}
return if @commands.key?(id)
@commands[id] = Thread.new do
Thread.current[:output] = block.call
end
default
end
def self.get(id)
thread = @commands[id]
return if thread.status
thread[:output]
end
end
get '/' do
Async.command do
`ssh vps ps`
end
end
__END__
Hello world!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment