Implemented a more simplified worker pattern

This commit is contained in:
Charles Care
2019-10-07 20:05:14 +01:00
parent 2dcd14072f
commit be4cdea9ea
12 changed files with 505 additions and 411 deletions

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env ruby
require "bundler/setup"
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "pipeline"
Pipeline.load_config(File.expand_path('../../config/pipeline.yml', __FILE__))
# Pipeline.daemon
# Pipeline.build_analyzer "ruby"
Pipeline.build_test_runner "ruby"
# #!/usr/bin/env ruby
# require "bundler/setup"
# $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
#
# require "pipeline"
#
# Pipeline.load_config(File.expand_path('../../config/pipeline.yml', __FILE__))
# # Pipeline.daemon
# # Pipeline.build_analyzer "ruby"
# Pipeline.build_test_runner "ruby"

View File

@@ -46,7 +46,7 @@ class PipelineClient
end
def release_latest(track_slug)
send_msg("release-analyzer_#{track_slug}", 30)
send_msg("release-analyzer_#{track_slug}", 3)
end
def analyze(track_slug, exercise_slug, solution_slug, iteration_folder)

View File

@@ -6,7 +6,7 @@ pipeline = PipelineClient.new
# return
lang = ARGV[0] || "ruby"
lang = "ruby"
# pipeline.build_test_runner(lang)

View File

@@ -1,122 +1,122 @@
#!/usr/bin/env ruby
require "bundler/setup"
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "pipeline"
context = ZMQ::Context.new
front_end_socket = context.socket(ZMQ::ROUTER)
front_end_socket.bind('tcp://*:5566')
back_end_socket = context.socket(ZMQ::DEALER)
# back_end_socket = context.socket(ZMQ::ROUTER)
@back_end_socket = back_end_socket
status_socket = context.socket(ZMQ::SUB)
status_socket.setsockopt(ZMQ::SUBSCRIBE, "")
status_socket.bind('tcp://*:5555')
poller = ZMQ::Poller.new
poller.register(back_end_socket, ZMQ::POLLIN)
poller.register(front_end_socket, ZMQ::POLLIN)
poller.register(status_socket, ZMQ::POLLIN)
@workers = {}
def active_workers
active = []
cut_off = Time.now.to_i - 2000
puts "Cut off #{cut_off}"
@workers.each do |k, worker|
puts "worker: #{worker}"
last_seen = worker[:last_seen]
puts "last_seen #{last_seen}"
active << worker if last_seen > cut_off
end
active
end
def check_active
puts "------------------------------"
inactive = []
cut_off = Time.now.to_i - 15
puts "Cut off #{cut_off}"
@workers.each do |k, worker|
last_seen = worker[:last_seen]
puts "last_seen #{last_seen}. #{last_seen} > #{cut_off} .. #{last_seen > cut_off}"
worker[:active] = last_seen > cut_off
unless worker[:active]
inactive << worker
end
puts "------------------------------"
puts worker
puts "------------------------------"
end
inactive.each do |inactive_worker|
puts inactive_worker
address = inactive_worker[:status]["address"]
puts "Unsub #{address}"
@back_end_socket.disconnect(address)
end
end
loop do
poll_result = poller.poll
break if poll_result == -1
puts "POLL #{poll_result}"
readables = poller.readables
puts "readables #{poller.readables.size}"
puts "writables #{poller.writables.size}"
puts "workers #{@workers.size}"
continue if readables.empty?
in_flight = {}
readables.each do |readable|
case readable
when status_socket
puts "..."
msg = ""
status_socket.recv_string(msg)
status_message = JSON.parse(msg)
address = status_message["address"]
identity = status_message["identity"]
@workers[identity] = { last_seen: Time.now.to_i, status: status_message }
back_end_socket.connect(address)
puts "STATUS: #{msg}"
puts "in_flight: #{in_flight}"
check_active
when front_end_socket
check_active
workers = active_workers
puts "WORKERS #{workers}"
if workers.empty?
puts "no workers"
msg = []
front_end_socket.recv_strings(msg)
puts "Address #{msg.first} | #{msg}"
reply = [msg.first, "", { status: :failed }.to_json]
front_end_socket.send_strings(reply)
else
msg = []
front_end_socket.recv_strings(msg)
puts "Address #{msg.first} | #{msg}"
in_flight[msg.first] = msg
result = back_end_socket.send_strings(msg, 1000)
puts result
end
when back_end_socket
msg = []
back_end_socket.recv_strings(msg)
puts "HERER!!!! #{msg}"
front_end_socket.send_strings(msg)
end
end
end
# ZMQ::Device.create(front_end_socket, back_end_socket)
# #!/usr/bin/env ruby
# require "bundler/setup"
# $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
#
# require "pipeline"
#
# context = ZMQ::Context.new
# front_end_socket = context.socket(ZMQ::ROUTER)
# front_end_socket.bind('tcp://*:5566')
#
# back_end_socket = context.socket(ZMQ::DEALER)
# # back_end_socket = context.socket(ZMQ::ROUTER)
# @back_end_socket = back_end_socket
#
#
# status_socket = context.socket(ZMQ::SUB)
# status_socket.setsockopt(ZMQ::SUBSCRIBE, "")
# status_socket.bind('tcp://*:5555')
#
# poller = ZMQ::Poller.new
# poller.register(back_end_socket, ZMQ::POLLIN)
# poller.register(front_end_socket, ZMQ::POLLIN)
# poller.register(status_socket, ZMQ::POLLIN)
#
# @workers = {}
#
# def active_workers
# active = []
# cut_off = Time.now.to_i - 2000
# puts "Cut off #{cut_off}"
# @workers.each do |k, worker|
# puts "worker: #{worker}"
# last_seen = worker[:last_seen]
# puts "last_seen #{last_seen}"
# active << worker if last_seen > cut_off
# end
# active
# end
#
# def check_active
# puts "------------------------------"
# inactive = []
# cut_off = Time.now.to_i - 15
# puts "Cut off #{cut_off}"
# @workers.each do |k, worker|
# last_seen = worker[:last_seen]
# puts "last_seen #{last_seen}. #{last_seen} > #{cut_off} .. #{last_seen > cut_off}"
# worker[:active] = last_seen > cut_off
# unless worker[:active]
# inactive << worker
# end
# puts "------------------------------"
# puts worker
# puts "------------------------------"
# end
# inactive.each do |inactive_worker|
# puts inactive_worker
# address = inactive_worker[:status]["address"]
# puts "Unsub #{address}"
# @back_end_socket.disconnect(address)
# end
# end
#
# loop do
# poll_result = poller.poll
# break if poll_result == -1
#
# puts "POLL #{poll_result}"
#
# readables = poller.readables
#
# puts "readables #{poller.readables.size}"
# puts "writables #{poller.writables.size}"
# puts "workers #{@workers.size}"
#
# continue if readables.empty?
#
# in_flight = {}
#
# readables.each do |readable|
# case readable
# when status_socket
# puts "..."
# msg = ""
# status_socket.recv_string(msg)
# status_message = JSON.parse(msg)
# address = status_message["address"]
# identity = status_message["identity"]
# @workers[identity] = { last_seen: Time.now.to_i, status: status_message }
# back_end_socket.connect(address)
# puts "STATUS: #{msg}"
# puts "in_flight: #{in_flight}"
# check_active
# when front_end_socket
# check_active
# workers = active_workers
# puts "WORKERS #{workers}"
# if workers.empty?
# puts "no workers"
# msg = []
# front_end_socket.recv_strings(msg)
# puts "Address #{msg.first} | #{msg}"
# reply = [msg.first, "", { status: :failed }.to_json]
# front_end_socket.send_strings(reply)
# else
# msg = []
# front_end_socket.recv_strings(msg)
# puts "Address #{msg.first} | #{msg}"
# in_flight[msg.first] = msg
# result = back_end_socket.send_strings(msg, 1000)
# puts result
# end
# when back_end_socket
# msg = []
# back_end_socket.recv_strings(msg)
# puts "HERER!!!! #{msg}"
# front_end_socket.send_strings(msg)
# end
# end
# end
#
# # ZMQ::Device.create(front_end_socket, back_end_socket)

View File

@@ -5,141 +5,10 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "pipeline"
context = ZMQ::Context.new
front_end_socket = context.socket(ZMQ::ROUTER)
front_end_socket.bind('tcp://*:5566')
router = Pipeline::Rpc::Router.new(context)
back_end_socket = context.socket(ZMQ::PUSH)
@back_end_socket = back_end_socket
resp_socket = context.socket(ZMQ::SUB)
resp_socket.setsockopt(ZMQ::SUBSCRIBE, "")
resp_socket.bind('tcp://*:5556')
status_socket = context.socket(ZMQ::SUB)
status_socket.setsockopt(ZMQ::SUBSCRIBE, "")
status_socket.bind('tcp://*:5555')
poller = ZMQ::Poller.new
# poller.register(back_end_socket, ZMQ::POLLIN)
poller.register(front_end_socket, ZMQ::POLLIN)
poller.register(status_socket, ZMQ::POLLIN)
poller.register(resp_socket, ZMQ::POLLIN)
workers_poller = ZMQ::Poller.new
workers_poller.register(back_end_socket, ZMQ::POLLOUT)
@workers = {}
def active_workers
active = []
@workers.each do |k, worker|
active << worker if worker[:active]
end
active
Thread.new do
router.run_heartbeater
end
def check_active
puts "------------------------------"
inactive = []
cut_off = Time.now.to_i - 15
puts "Cut off #{cut_off}"
@workers.each do |k, worker|
last_seen = worker[:last_seen]
puts "last_seen #{last_seen}. #{last_seen} > #{cut_off} .. #{last_seen > cut_off}"
worker[:active] = last_seen > cut_off
unless worker[:active]
inactive << worker
end
puts "------------------------------"
puts worker
puts "------------------------------"
end
inactive.each do |inactive_worker|
puts inactive_worker
address = inactive_worker[:status]["address"]
puts "Unsub #{address}"
@back_end_socket.disconnect(address)
end
end
loop do
poll_result = poller.poll
break if poll_result == -1
puts "POLL #{poll_result}"
readables = poller.readables
puts "readables #{poller.readables.size}"
puts "writables #{poller.writables.size}"
puts "workers #{@workers.size}"
continue if readables.empty?
in_flight = {}
readables.each do |readable|
case readable
when resp_socket
puts "resp_socket"
msg = ""
resp_socket.recv_string(msg)
puts msg
puts "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
when status_socket
puts "..."
msg = ""
status_socket.recv_string(msg)
puts "STATUS MSG: #{msg} "
status_message = JSON.parse(msg)
type = status_message["msg_type"]
puts "STATUS MSG TYPE: #{status_message["msg_type"]} "
if type == "status"
address = status_message["address"]
identity = status_message["identity"]
@workers[identity] = { last_seen: Time.now.to_i, status: status_message }
back_end_socket.connect(address)
puts "in_flight: #{in_flight}"
check_active
else
puts "OTHER"
return_address = status_message["return_address"]
puts return_address
puts return_address.pack("c*")
reply = [return_address.pack("c*"), "", msg]
front_end_socket.send_strings(reply)
end
when front_end_socket
check_active
workers = active_workers
puts "WORKERS #{workers}"
if workers.empty?
puts "no workers"
msg = []
front_end_socket.recv_strings(msg)
puts "Address #{msg.first} | #{msg}"
reply = [msg.first, "", { status: :failed }.to_json]
front_end_socket.send_strings(reply)
else
poll_result = workers_poller.poll
puts "WORKERS POLL #{poll_result}"
msg = []
front_end_socket.recv_strings(msg)
puts "Address #{msg.first} | #{msg}"
in_flight[msg.first] = msg
puts "send1"
result = back_end_socket.send_strings(msg, ZMQ::DONTWAIT)
puts "send2"
puts result
end
when back_end_socket
msg = []
back_end_socket.recv_strings(msg)
puts "HERER!!!! #{msg}"
front_end_socket.send_strings(msg)
end
end
end
# ZMQ::Device.create(front_end_socket, back_end_socket)
router.run_eventloop

View File

@@ -1,39 +1,39 @@
require 'rubygems'
require 'ffi-rzmq'
context = ZMQ::Context.new 2
req = context.socket(ZMQ::REQ)
puts req.bind('ipc://routing.ipc')
sleep 2
Thread.new do
socket = context.socket(ZMQ::ROUTER)
puts socket.setsockopt(ZMQ::IDENTITY, "foobar")
puts socket.connect('ipc://routing.ipc')
sleep 2
loop do
puts "waiting"
socket.recv_string(message = '')
puts "Received [#{message}]"
socket.send_string("OK " + message)
end
end
10.times do |request|
ss = "Hello #{request}"
puts req.setsockopt(ZMQ::IDENTITY, "baz")
req.send_string("foobar", ZMQ::SNDMORE)
req.send_string("foobar", ZMQ::SNDMORE)
req.send_string("foobar", ZMQ::SNDMORE)
req.send_string("foobar", ZMQ::SNDMORE)
req.send_string("", ZMQ::SNDMORE)
req.send_string(ss)
puts "Sending string [#{ss}]"
req.recv_string(message = '')
puts "Received reply #{request}[#{message}]"
end
# require 'rubygems'
# require 'ffi-rzmq'
#
# context = ZMQ::Context.new 2
#
# req = context.socket(ZMQ::REQ)
# puts req.bind('ipc://routing.ipc')
#
# sleep 2
#
# Thread.new do
# socket = context.socket(ZMQ::ROUTER)
# puts socket.setsockopt(ZMQ::IDENTITY, "foobar")
# puts socket.connect('ipc://routing.ipc')
#
# sleep 2
#
# loop do
# puts "waiting"
# socket.recv_string(message = '')
# puts "Received [#{message}]"
# socket.send_string("OK " + message)
# end
#
# end
#
# 10.times do |request|
# ss = "Hello #{request}"
# puts req.setsockopt(ZMQ::IDENTITY, "baz")
# req.send_string("foobar", ZMQ::SNDMORE)
# req.send_string("foobar", ZMQ::SNDMORE)
# req.send_string("foobar", ZMQ::SNDMORE)
# req.send_string("foobar", ZMQ::SNDMORE)
# req.send_string("", ZMQ::SNDMORE)
# req.send_string(ss)
# puts "Sending string [#{ss}]"
# req.recv_string(message = '')
# puts "Received reply #{request}[#{message}]"
# end

View File

@@ -4,8 +4,8 @@ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
require "pipeline"
env_base = ARGV[0]
Pipeline.load_config(File.expand_path('../../config/pipeline.yml', __FILE__))
# Pipeline.release("ruby")
Pipeline.daemon
# Pipeline.build_analyzer "ruby"
# Pipeline.build_test_runner "ruby"
server = Pipeline::Rpc::Server.new(env_base)
server.listen

View File

@@ -23,11 +23,6 @@ module Pipeline
@config
end
def self.daemon
server = Pipeline::RpcServer.new
server.listen
end
def self.build_analyzer(track_slug)
repo = Pipeline::AnalyzerRepo.for_track(track_slug)
latest_tag = repo.tags.keys.last
@@ -80,7 +75,8 @@ module Pipeline
end
end
require "pipeline/rpc_server"
require "pipeline/rpc/router"
require "pipeline/rpc/server"
require "pipeline/analyzer_repo"
require "pipeline/container_repo"
require "pipeline/validation/check_invokable"

125
lib/pipeline/rpc/router.rb Normal file
View File

@@ -0,0 +1,125 @@
module Pipeline::Rpc
class Router
attr_reader :context, :front_end_socket, :back_end_socket,
:response_socket, :poller, :workers_poller
def initialize(context)
@context = context
@front_end_socket = context.socket(ZMQ::ROUTER)
@front_end_socket.bind('tcp://*:5566')
@back_end_socket = context.socket(ZMQ::PUSH)
@back_end_socket.setsockopt(ZMQ::SNDHWM, 1)
@back_end_socket.bind('tcp://*:5577')
@response_socket = context.socket(ZMQ::SUB)
@response_socket.setsockopt(ZMQ::SUBSCRIBE, "")
@response_socket.bind('tcp://*:5555')
@poller = ZMQ::Poller.new
@poller.register(@front_end_socket, ZMQ::POLLIN)
@poller.register(@response_socket, ZMQ::POLLIN)
@workers_poller = ZMQ::Poller.new
@workers_poller.register(@back_end_socket, ZMQ::POLLOUT)
@in_flight = {}
end
def run_heartbeater
puts "STARTING heartbeat_socket"
heartbeat_socket = context.socket(ZMQ::PUB)
heartbeat_socket.connect('tcp://127.0.0.1:5555')
sleep 2
loop do
heartbeat_socket.send_string({ msg_type: "heartbeat" }.to_json)
puts "ping heartbeat"
sleep 10
end
end
def run_eventloop
loop do
poll_result = poller.poll
break if poll_result == -1
readables = poller.readables
continue if readables.empty?
readables.each do |readable|
case readable
when response_socket
incoming_recv
when front_end_socket
handle_frontend_req
end
end
end
end
private
def incoming_recv
puts "..."
msg = ""
response_socket.recv_string(msg)
status_message = JSON.parse(msg)
type = status_message["msg_type"]
puts "STATUS MSG TYPE: #{status_message["msg_type"]} "
if type == "status"
# address = status_message["address"]
# identity = status_message["identity"]
# @workers[identity] = { last_seen: Time.now.to_i, status: status_message }
# # back_end_socket.connect(address)
# check_active
elsif type == "response"
# puts "RESP"
return_address = status_message["return_address"]
# puts return_address
# puts return_address.pack("c*")
reply = [return_address.pack("c*"), "", msg]
front_end_socket.send_strings(reply, ZMQ::DONTWAIT)
elsif type == "heartbeat"
puts "heartbeat msg"
puts "in_flight: #{@in_flight}"
timed_out = []
now = Time.now.to_i
@in_flight.each do |k, v|
expiry = v[:timeout]
timed_out << k if expiry < now
end
timed_out.each do |addr|
reply = [addr, "", { status: :timeout }.to_json]
front_end_socket.send_strings(reply)
@in_flight.delete(addr)
end
else
puts "OTHER"
end
end
def handle_frontend_req
msg = []
front_end_socket.recv_strings(msg)
puts ">>>> #{msg}"
if (msg[2] == "describe_analysers")
analyzer_spec = {
"ruby" => "master"
}
reply = [msg.first, "", analyzer_spec.to_json]
front_end_socket.send_strings(reply)
return
end
poll_result = workers_poller.poll(500)
writable = poll_result != -1 && workers_poller.writables.size > 0
if !writable
reply = [msg.first, "", { status: :failed }.to_json]
front_end_socket.send_strings(reply)
else
@in_flight[msg.first] = {msg: msg, timeout: Time.now.to_i + 5}
result = back_end_socket.send_strings(msg, ZMQ::DONTWAIT)
end
end
end
end

View File

@@ -0,0 +1,90 @@
class Pipeline::Rpc::Server
attr_reader :context, :incoming, :outgoing, :environment
def initialize(env_base)
@context = ZMQ::Context.new(1)
@incoming = context.socket(ZMQ::PULL)
@outgoing = context.socket(ZMQ::PUB)
@outgoing.connect("tcp://localhost:5555")
@environment = Pipeline::Runtime::RuntimeEnvironment.new(env_base)
end
def setup
@setup = context.socket(ZMQ::REQ)
@setup.setsockopt(ZMQ::LINGER, 0)
@setup.connect("tcp://localhost:5566")
@setup.send_string("describe_analysers")
msg = ""
@setup.recv_string(msg)
analyzer_spec = JSON.parse(msg)
puts analyzer_spec
environment.prepare
analyzer_spec.each do |language_slug, version|
if environment.released?(language_slug)
puts "Already installed #{language_slug}"
else
puts "Installed #{language_slug}"
environment.release_analyzer(language_slug)
end
end
end
def listen
setup
incoming.connect("tcp://localhost:5577")
loop do
msg = []
incoming.recv_strings(msg)
puts "Received request. Data: #{msg.inspect}"
return_address = msg[0].unpack('c*')
puts return_address
request = msg[2]
if request.start_with? "analyze_"
_, arg = request.split("_", 2)
track, exercise_slug, solution_slug, location = arg.split("|")
result = analyze(track, exercise_slug, solution_slug, location)
result["return_address"] = return_address
result['msg_type'] = 'response'
outgoing.send_string(result.to_json)
else
puts "HERE ELSE: #{request}"
end
end
end
def analyze(language_slug, exercise_slug, solution_slug, location)
analysis_run = environment.new_analysis(language_slug, exercise_slug, solution_slug)
analysis_run.prepare_iteration do |iteration_folder|
location_uri = URI(location)
bucket = location_uri.host
path = location_uri.path[1..]
s3 = Aws::S3::Client.new(region: 'eu-west-1')
params = {
bucket: bucket,
prefix: "#{path}/",
}
resp = s3.list_objects(params)
resp.contents.each do |item|
key = item[:key]
filename = File.basename(key)
s3.get_object({
bucket: bucket,
key: key,
response_target: "#{iteration_folder}/#{filename}"
})
end
end
begin
analysis_run.analyze!
rescue => e
puts e
ensure
puts "DONE"
end
end
end

View File

@@ -1,93 +1,100 @@
class Pipeline::RpcServer
attr_reader :context, :socket, :identity
def initialize
@context = ZMQ::Context.new(1)
@socket = context.socket(ZMQ::PULL)
@outgoing = context.socket(ZMQ::PUB)
@outgoing.connect("tcp://localhost:5555")
@identity = SecureRandom.uuid
end
def listen
hostname = Socket.gethostname
# socket.setsockopt(ZMQ::IDENTITY, identity)
# socket.setsockopt(ZMQ::ROUTING_ID, identity)
# socket.connect("tcp://localhost:5577")
port = 5555
bind_result = -1
until bind_result != -1 || port > 5600
port += 1
# @identity = "#{port}"
bind_result = socket.bind("tcp://*:#{port}")
end
address = "tcp://#{hostname}:#{port}"
Thread.new do
puts "STARTING"
emitter = context.socket(ZMQ::PUB)
emitter.connect("tcp://localhost:5555")
sleep 2
loop do
emitter.send_string({ msg_type: "status", address: address, identity: identity}.to_json)
puts "Sent"
sleep 10
end
end
loop do
msg = []
socket.recv_strings(msg)
puts "Received request. Data: #{msg.inspect}"
return_address = msg[0].unpack('c*')
puts return_address
request = msg[2]
if request.start_with? "build-analyzer_"
_, track = request.split("_")
result = Pipeline.build_analyzer(track)
socket.send_string(result.to_json)
elsif request.start_with? "build-test-runner_"
_, track = request.split("_")
result = Pipeline.build_test_runner(track)
socket.send_string(result.to_json)
elsif request.start_with? "release-analyzer_"
_, arg = request.split("_")
result = Pipeline.release(arg)
socket.send_string(result.to_json)
elsif request.start_with? "analyze_"
_, arg = request.split("_", 2)
track, exercise_slug, solution_slug, location = arg.split("|")
result = Pipeline.analyze!(track, exercise_slug, solution_slug) do |iteration_folder|
location_uri = URI(location)
bucket = location_uri.host
path = location_uri.path[1..]
s3 = Aws::S3::Client.new(region: 'eu-west-1')
params = {
bucket: bucket,
prefix: "#{path}/",
}
resp = s3.list_objects(params)
resp.contents.each do |item|
key = item[:key]
filename = File.basename(key)
s3.get_object({
bucket: bucket,
key: key,
response_target: "#{iteration_folder}/#{filename}"
})
end
end
puts "DONE"
# socket.send_string(result.to_json)
result["return_address"] = return_address
@outgoing.send_string(result.to_json)
else
puts "HERE ELSE: #{request}"
# @outgoing.send_string("done")
end
end
# socket.send_string(msg)
end
end
# class Pipeline::Rpc::Server
#
# attr_reader :context, :incoming, :outgoing, :environment
#
# def initialize(env_base)
# @context = ZMQ::Context.new(1)
# @incoming = context.socket(ZMQ::PULL)
# @outgoing = context.socket(ZMQ::PUB)
# @outgoing.connect("tcp://localhost:5555")
# @environment = Pipeline::Runtime::RuntimeEnvironment.new(env_base)
# end
#
# def setup
# @setup = context.socket(ZMQ::REQ)
# @setup.setsockopt(ZMQ::LINGER, 0)
# @setup.connect("tcp://localhost:5566")
# @setup.send_string("describe_analysers")
# msg = ""
# @setup.recv_string(msg)
# analyzer_spec = JSON.parse(msg)
# puts analyzer_spec
#
# environment.prepare
#
# analyzer_spec.each do |language_slug, version|
# if environment.released?(language_slug)
# puts "Already installed #{language_slug}"
# else
# puts "Installed #{language_slug}"
# environment.release_analyzer(language_slug)
# end
# end
# end
#
# def listen
# setup
# incoming.connect("tcp://localhost:5577")
#
# loop do
# msg = []
# incoming.recv_strings(msg)
# puts "Received request. Data: #{msg.inspect}"
# return_address = msg[0].unpack('c*')
# puts return_address
# request = msg[2]
# if request.start_with? "analyze_"
# _, arg = request.split("_", 2)
# track, exercise_slug, solution_slug, location = arg.split("|")
# result = analyze(track, exercise_slug, solution_slug) do |iteration_folder|
# location_uri = URI(location)
# bucket = location_uri.host
# path = location_uri.path[1..]
# s3 = Aws::S3::Client.new(region: 'eu-west-1')
# params = {
# bucket: bucket,
# prefix: "#{path}/",
# }
# resp = s3.list_objects(params)
# resp.contents.each do |item|
# key = item[:key]
# filename = File.basename(key)
# s3.get_object({
# bucket: bucket,
# key: key,
# response_target: "#{iteration_folder}/#{filename}"
# })
# end
# end
# result["return_address"] = return_address
# result['msg_type'] = 'response'
# outgoing.send_string(result.to_json)
# else
# puts "HERE ELSE: #{request}"
# end
# end
# end
#
# def analyze(language_slug, exercise_slug, solution_slug)
# analysis_run = environment.new_analysis(language_slug, exercise_slug, solution_slug)
# analysis_run.prepare_iteration do |iteration_folder|
# yield(iteration_folder)
# end
# begin
# analysis_run.analyze!
# rescue => e
# puts e
# ensure
# # puts "---"
# # puts analysis_run.stdout
# # puts "==="
# # puts analysis_run.stderr
# # puts "---"
# # puts analysis_run.success?
# # puts analysis_run.exit_status
# # puts analysis_run.result
# puts "DONE"
# end
# end
#
# end

View File

@@ -11,6 +11,12 @@ module Pipeline::Runtime
FileUtils.mkdir_p env_base
end
def released?(track_slug)
track_dir = "#{env_base}/#{track_slug}"
current_dir = "#{track_dir}/current"
File.exist? current_dir
end
def release_analyzer(track_slug)
registry_endpoint = Pipeline.config["registry_endpoint"]
@@ -59,6 +65,7 @@ module Pipeline::Runtime
end
def new_analysis(track_slug, exercise_slug, solution_slug)
puts "AnalysisRun: #{track_slug} #{exercise_slug} #{solution_slug}"
track_dir = "#{env_base}/#{track_slug}"
AnalysisRun.new(track_dir, exercise_slug, solution_slug)
end