Skip to content

Instantly share code, notes, and snippets.

@svoop
Created May 17, 2023 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save svoop/8e09c82d79169cff73ba071ab2adaf80 to your computer and use it in GitHub Desktop.
Save svoop/8e09c82d79169cff73ba071ab2adaf80 to your computer and use it in GitHub Desktop.
Build Checkpoint for Render
#!/usr/bin/env ruby
require 'bundler/inline'
require 'optparse'
require 'timeout'
gemfile do
source 'https://rubygems.org'
gem 'redis'
end
class BuildCheckpoint
TIMEOUT = 300
POLLING = 2
def initialize
option_parser.parse!
@build_count = ARGV.pop || 1
@environment = ENV['RAILS_ENV'] or fail 'RAILS_ENV must be set'
@commit = (ENV['RENDER_GIT_COMMIT'] or fail 'RENDER_GIT_COMMIT must be set')[1, 8]
@redis = Redis.new(url: (ENV['BUILD_REDIS_URL'] or fail 'BUILD_REDIS_URL must be set'))
@build_id = ['build-checkpoint', @namespace, @environment, @commit].compact.join('-')
STDOUT.sync = true
end
def wait
puts "⏳ waiting for other builds to reach #{@build_id}"
@redis.set(@build_id, '0', nx: true, ex: TIMEOUT)
Timeout::timeout(TIMEOUT) do
@redis.incr(@build_id)
loop do
count = @redis.get(@build_id)
fail Timeout::Error if count.nil?
break if count >= @build_count
sleep POLLING
end
end
sleep POLLING + 2
@redis.del(@build_id)
puts "🎉 all #{@build_count} builds have reached the checkpoint"
rescue Timeout::Error
puts "💣 timeout elapsed - some builds may have failed"
exit 1
end
private
def option_parser
OptionParser.new do |o|
o.banner = <<~END
Waits until NUMBER of builds have reached this checkpoint or the timeout is reached
Usage: build-checkpoint NUMBER
END
o.on('-n', '--namespace STRING', String, 'optional namespace to further isolate this checkpoint (default: none)') { |v| @namespace = v }
end
end
end
begin
BuildCheckpoint.new.wait
rescue => exception
puts "#{File.basename($0)}: #{exception.message}"
exit 1
end
@digerata
Copy link

digerata commented Dec 1, 2023

In the Render Feedback comment:

For this to work, you have to set BUILD_RENDER_URL to a Render service (internal URL is okay).

Do you mean BUILD_REDIS_URL?

Also, I'm curious what the sleep is for on line 38? To make sure all waiting builds see the updated value before deleting?

@svoop
Copy link
Author

svoop commented Dec 2, 2023

@digerata Yeah, BUILD_REDIS_URL it is. Without the extra sleep, my builds (which vary a lot in build speed) sometimes matched to pass the checkpoint but then caused trouble down the lane. Your mileage may vary, you might just try whether it's working without for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment