From 7e17bd6e2d5fcf8f575c461ff051f96f67359da6 Mon Sep 17 00:00:00 2001 From: VetheonGames Date: Thu, 6 Jul 2023 09:08:39 -0600 Subject: [PATCH] Replaced Ring Buffer with Array queue in AlertQueueManager class In the AlertQueueManager class of the NETRAVE project, we made a significant change to improve code simplicity, efficiency, and maintainability. We replaced the previously used Ring Buffer with a standard Array queue for managing the queue of alerts. This change simplifies the code structure and improves the efficiency of queue management. As a result of this change, the Ring Buffer file, which is no longer needed, was also removed from the project. I would also like to thank Havenwood, Lapizistik, Sampersand, and Crimson from the Ruby discord in helping me determine the best data structure to use and helping me generally expand my deeper knowledge of Ruby --- lib/utils/alert_queue_manager.rb | 34 ++++++++++++++------------- lib/utils/ring_buffer.rb | 40 -------------------------------- 2 files changed, 18 insertions(+), 56 deletions(-) delete mode 100644 lib/utils/ring_buffer.rb diff --git a/lib/utils/alert_queue_manager.rb b/lib/utils/alert_queue_manager.rb index a3e2caf..6af23a3 100644 --- a/lib/utils/alert_queue_manager.rb +++ b/lib/utils/alert_queue_manager.rb @@ -1,45 +1,47 @@ # frozen_string_literal: true -require_relative 'ring_buffer' -# Class for managing the queues for alerts +require_relative 'alert' +require_relative 'logg_man' + +# Class for managing the queue of alerts. This class also manages a little bit of concurrency +# We use mutex for sync so we don't break Curses, as Curses isn't thread safe class AlertQueueManager SHUTDOWN_SIGNAL = 'shutdown' - def initialize(logger, size = 2 * 1024 * 1024) # rubocop:disable Metrics/MethodLength + def initialize(logger) # rubocop:disable Metrics/MethodLength @loggman = logger - @queue = RingBuffer.new(@loggman, size) + @alert_queue = [] @shutdown = false - - # Start a thread that continuously checks the queue and displays alerts @worker_thread = Thread.new do loop do - break if @shutdown && @queue.empty? - - if @queue.empty? + if @alert_queue.empty? sleep(0.1) # Sleep for 100 milliseconds next end - alert = @queue.pop # This will block until there's an alert in the queue - next if alert.nil? - + alert = pop_alert break if alert.message == SHUTDOWN_SIGNAL alert.display sleep(4.5) - alert.clear end end end def enqueue_alert(alert) - return if @shutdown + @alert_queue << alert + end - @queue.push(alert) + def pop_alert + @alert_queue.shift end def shutdown - @shutdown = true enqueue_alert(Alert.new(SHUTDOWN_SIGNAL, :info)) + @shutdown = true + end + + def join_worker + @worker_thread.join if @shutdown end end diff --git a/lib/utils/ring_buffer.rb b/lib/utils/ring_buffer.rb deleted file mode 100644 index f8725a4..0000000 --- a/lib/utils/ring_buffer.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -# Since the Standard Ruby library doesn't come with a Ring Buffer implementation, we need to make our own. -# this class creates a simple and rudementary implementation of a Ring Buffer for us to use. -class RingBuffer - def initialize(logger, size) - @loggman = logger - @size = size - @buffer = Array.new(size) - @start = 0 - @end = 0 - end - - def push(element) - @loggman.log_warn('Attempted to push to a full buffer. Overwriting old data.') if full? - - @buffer[@end] = element - @end = (@end + 1) % @size - @start = (@start + 1) % @size if @end == @start - end - - def pop - if empty? - @loggman.log_warn('Attempted to pop from an empty buffer. Returning nil.') - return nil - end - - element = @buffer[@start] - @start = (@start + 1) % @size - element - end - - def empty? - @start == @end - end - - def full? - (@end + 1) % @size == @start - end -end