P
Pablo Lorenzzoni
Hello,
Recently I had to deal with external data sources that had to be =20
refresh every now and then. Instead of using an infinite loop inside a =20
thread for every object, I used Queue to create a "Refresh Machine". =20
Below is the code... my questions are: can it be improved? is there =20
another way to do the same?
Thanks
Pablo
require 'thread'
class RefreshMachine
attr_accessor :wait
def initialize(wait =3D false)
@wait =3D wait
@killall =3D false
@queue =3D Queue.new
@removed =3D Array.new
@thread =3D Thread.new do
loop do
( @removed.clear; @queue.clear; @killall =3D false ) if @killall
next if @queue.empty?
object, last_refresh, thread =3D @queue.deq
# Helps the garbage collection
thread =3D nil if (! thread.nil?) and (! thread.alive?)
# Three things can happen with a dequeued object
if (Time.now < (last_refresh + object.refresh)) or
(! thread.nil? and @wait)
# First: It's too early to refresh it or we still have
# a refresh thread running and have to 'wait', so we
# just put it back in the queue
@queue.enq [ object, last_refresh, thread ]
else
if @removed.include?(object)
# Second: We have a "remove request" for it, so we
# delete the request and avoid queueing it again
@removed.delete(object)
else
# Third: It's time to refresh it, so we
# call do_refresh and put it back in the queue
add(object)
end
end
end
end
end
def add(object)
@queue.enq [ object, Time.now, Thread.new { object.do_refresh } ]
end
def del(object)
@removed << object unless @removed.include?(object)
end
def killall
@killall =3D true
end
end # of class RefreshMachine
Recently I had to deal with external data sources that had to be =20
refresh every now and then. Instead of using an infinite loop inside a =20
thread for every object, I used Queue to create a "Refresh Machine". =20
Below is the code... my questions are: can it be improved? is there =20
another way to do the same?
Thanks
Pablo
require 'thread'
class RefreshMachine
attr_accessor :wait
def initialize(wait =3D false)
@wait =3D wait
@killall =3D false
@queue =3D Queue.new
@removed =3D Array.new
@thread =3D Thread.new do
loop do
( @removed.clear; @queue.clear; @killall =3D false ) if @killall
next if @queue.empty?
object, last_refresh, thread =3D @queue.deq
# Helps the garbage collection
thread =3D nil if (! thread.nil?) and (! thread.alive?)
# Three things can happen with a dequeued object
if (Time.now < (last_refresh + object.refresh)) or
(! thread.nil? and @wait)
# First: It's too early to refresh it or we still have
# a refresh thread running and have to 'wait', so we
# just put it back in the queue
@queue.enq [ object, last_refresh, thread ]
else
if @removed.include?(object)
# Second: We have a "remove request" for it, so we
# delete the request and avoid queueing it again
@removed.delete(object)
else
# Third: It's time to refresh it, so we
# call do_refresh and put it back in the queue
add(object)
end
end
end
end
end
def add(object)
@queue.enq [ object, Time.now, Thread.new { object.do_refresh } ]
end
def del(object)
@removed << object unless @removed.include?(object)
end
def killall
@killall =3D true
end
end # of class RefreshMachine