Skip to content

Instantly share code, notes, and snippets.

@mgruberman
Forked from erikh/transaction_protocol.rb
Created March 4, 2010 06:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgruberman/321447 to your computer and use it in GitHub Desktop.
Save mgruberman/321447 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'eventmachine'
require 'delegate'
module TransactionProtocol
class Writer < EM::Queue
class << self
@files = []
attr_accessor :files
end
attr_reader :filename
DEFAULT_INTERVAL_SEC = 60
def initialize(filename_in, interval=DEFAULT_INTERVAL_SEC)
# Normalize the filename to account for string-differences that actually refer to the same file.
# TODO: worry about symlinks, hardlinks, and files being moved or replaced from under us
filename = File.expand_path( filename_in )
raise "File is already associated with a transaction" if self.class.files.include?(filename)
self.class.files.push(filename)
@filename = filename
# TODO: aren't PeriodicTimer's part of the crusty parts of EventMachine? Consult the main C++ runloop
# comments for notes on this or whatever it was that's actually worrisome.
@timer = EM::PeriodicTimer.new(interval) do
self.flush
end
end
def flush
return if self.empty?
# TODO: Marshal.new? Not in my 1.8.6-p111 documentation.
m = Marshal.new(@filename)
m.push(self.pop) until self.empty?
m.write
end
def close
self.flush
@timer.cancel
self.class.files.delete(@filename)
end
end
# Not sure this is a good pattern - shadowing another class by being earlier in the name resolution search path?
class Marshal < DelegateClass(Array)
def initialize(filename)
@obj = ::Marshal.load(filename)
raise "Not an array" unless @obj.kind_of?(Array)
super(@obj)
end
def reload
@obj = ::Marshal.load(filename)
end
def write
::Marshal.dump(filename)
end
def push elt
# TODO: write this method
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment