Initial commit
This commit is contained in:
95
lib/peatio/bench/order_processing/amqp.rb
Normal file
95
lib/peatio/bench/order_processing/amqp.rb
Normal file
@@ -0,0 +1,95 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Bench
|
||||
module OrderProcessing
|
||||
class AMQP < TradeExecution::AMQP
|
||||
def run!
|
||||
# TODO: Check if OrderProcessing daemon is running before start (use queue_info[:consumers]).
|
||||
super
|
||||
Kernel.puts "Init wait orders queue..."
|
||||
@orders_for_cancel_number = init_wait_orders_queue!.size # TODO: If zero? raise Error.
|
||||
|
||||
Kernel.puts "Start wait orders publish..."
|
||||
@cancel_publish_started_at = @order_processing_started_at = Time.now
|
||||
publish_cancel_messages
|
||||
@cancel_publish_finished_at = Time.now
|
||||
|
||||
Kernel.puts "Messages are published to RabbitMQ."
|
||||
Kernel.puts "Waiting for order processing by order processor..."
|
||||
wait_for_order_processing
|
||||
@order_processing_finished_at = Time.now
|
||||
end
|
||||
|
||||
def publish_cancel_messages
|
||||
Array.new(@config[:threads]) do
|
||||
Thread.new do
|
||||
loop do
|
||||
break if @wait_orders_queue.blank?
|
||||
order = @wait_orders_queue.pop
|
||||
AMQP::Queue.enqueue(:matching, action: 'cancel', order: order.to_matching_attributes)
|
||||
rescue StandardError => e
|
||||
Kernel.puts e
|
||||
@errors << e
|
||||
end
|
||||
end
|
||||
end.map(&:join)
|
||||
end
|
||||
|
||||
def wait_for_order_processing
|
||||
last_log_time = Time.at(0)
|
||||
queue_status_file = File.open(queue_status_file_path('order-processing'), 'a')
|
||||
|
||||
loop do
|
||||
queue_status = order_processing_queue_status
|
||||
# NOTE: If no orders where cancelled idle_since would not change.
|
||||
break if queue_status[:messages].zero? &&
|
||||
queue_status[:idle_since].present? &&
|
||||
Time.parse("#{queue_status[:idle_since]} UTC") >= @order_processing_started_at
|
||||
|
||||
if last_log_time + 5 < Time.now
|
||||
queue_status_file.puts(YAML.dump([queue_status.merge(timestamp: Time.now.iso8601).deep_stringify_keys]))
|
||||
last_log_time = Time.now
|
||||
end
|
||||
|
||||
sleep 0.5
|
||||
end
|
||||
end
|
||||
|
||||
def result
|
||||
@result ||=
|
||||
begin
|
||||
cancel_publish_ops = @orders_for_cancel_number / (@cancel_publish_finished_at - @cancel_publish_started_at)
|
||||
order_processing_ops = @orders_for_cancel_number / (@order_processing_finished_at - @order_processing_started_at)
|
||||
|
||||
super.merge(
|
||||
cancel_publish: {
|
||||
started_at: @cancel_publish_started_at.iso8601(6),
|
||||
finished_at: @cancel_publish_finished_at.iso8601(6),
|
||||
operations: @orders_for_cancel_number,
|
||||
ops: cancel_publish_ops
|
||||
},
|
||||
order_processing: {
|
||||
started_at: @order_processing_started_at.iso8601(6),
|
||||
finished_at: @order_processing_finished_at.iso8601(6),
|
||||
operations: @orders_for_cancel_number,
|
||||
ops: order_processing_ops
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def init_wait_orders_queue!
|
||||
orders = Order.where(state: Order::WAIT).shuffle
|
||||
@wait_orders_queue =
|
||||
orders.each_with_object(Queue.new) do |o, queue|
|
||||
queue << o
|
||||
end
|
||||
end
|
||||
|
||||
def order_processing_queue_status
|
||||
@rmq_http_client.list_queues.find { |q| q[:name] == AMQP::Config.binding_queue(:order_processor).first }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
82
lib/peatio/bench/order_processing/direct.rb
Normal file
82
lib/peatio/bench/order_processing/direct.rb
Normal file
@@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# TODO: Add Bench::Error and better errors processing.
|
||||
# TODO: Add Bench::Report and extract all metrics to it.
|
||||
module Bench
|
||||
module OrderProcessing
|
||||
class Direct
|
||||
include Helpers
|
||||
|
||||
def initialize(config)
|
||||
@config = config
|
||||
|
||||
@injector = Injectors.initialize_injector(@config[:orders])
|
||||
@currencies = Currency.where(id: @config[:currencies].split(',').map(&:squish).reject(&:blank?))
|
||||
@order_processor = Workers::AMQP::OrderProcessor.new
|
||||
# TODO: Print errors in the end of benchmark and include them into report.
|
||||
@errors = []
|
||||
end
|
||||
|
||||
def run!
|
||||
Kernel.puts "Creating members ..."
|
||||
@members = Factories.create_list(:member, @config[:traders])
|
||||
|
||||
Kernel.puts "Depositing funds ..."
|
||||
@members.map(&method(:become_billionaire))
|
||||
|
||||
Kernel.puts "Generating orders by injector and saving them in db..."
|
||||
# TODO: Add orders generation progress bar.
|
||||
@injector.generate!(@members)
|
||||
|
||||
@orders_number = @injector.size
|
||||
|
||||
@processing_started_at = Time.now
|
||||
|
||||
process_orders
|
||||
|
||||
@processing_finished_at = Time.now
|
||||
end
|
||||
|
||||
def process_orders
|
||||
loop do
|
||||
order = @injector.pop
|
||||
break unless order
|
||||
|
||||
@order_processor.process({action: 'cancel', order: order.to_matching_attributes}.deep_stringify_keys!)
|
||||
rescue StandardError => e
|
||||
Kernel.puts e
|
||||
@errors << e
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: Add more useful metrics to result.
|
||||
def result
|
||||
@result ||=
|
||||
begin
|
||||
processing_ops = @orders_number / (@processing_finished_at - @processing_started_at)
|
||||
|
||||
# TODO: Deal with calling iso8601(6) everywhere.
|
||||
{ config: @config,
|
||||
order_processing: {
|
||||
started_at: @processing_started_at.iso8601(6),
|
||||
finished_at: @processing_finished_at.iso8601(6),
|
||||
operations: @orders_number,
|
||||
ops: processing_ops
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def save_report
|
||||
report_path = Rails.root.join(@config[:report_path])
|
||||
FileUtils.mkpath(report_path)
|
||||
report_name = "#{self.class.parent.name.demodulize.downcase}-"\
|
||||
"#{self.class.name.humanize.demodulize}-#{@config[:orders][:injector]}-"\
|
||||
"#{@config[:orders][:number]}-#{@processing_started_at.iso8601}.yml"
|
||||
File.open(report_path.join(report_name), 'w') do |f|
|
||||
f.puts YAML.dump(result.deep_stringify_keys)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user