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
This commit is contained in:
parent
e50eac31b2
commit
7e17bd6e2d
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user