diff --git a/Gemfile b/Gemfile index f30c9c4..5913643 100644 --- a/Gemfile +++ b/Gemfile @@ -2,3 +2,5 @@ source 'https://rubygems.org' # Specify your gem's dependencies in filequeue.gemspec gemspec + +gem 'filelock' diff --git a/Gemfile.lock b/Gemfile.lock index fc3999b..c9afbec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,7 @@ GEM remote: https://rubygems.org/ specs: diff-lcs (1.2.5) + filelock (1.1.1) rake (10.4.2) rspec (3.4.0) rspec-core (~> 3.4.0) @@ -26,9 +27,10 @@ PLATFORMS ruby DEPENDENCIES + filelock filequeue! rake rspec (~> 3.3) BUNDLED WITH - 1.10.6 + 1.16.1 diff --git a/README.md b/README.md index 304ecdd..38f80c9 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,47 @@ +# FileQueue [![Build Status](https://travis-ci.org/pezra/filequeue.svg)](https://travis-ci.org/pezra/filequeue) - -## FileQueue [![Build Status](https://travis-ci.org/pezra/filequeue.svg)](https://travis-ci.org/pezra/filequeue) -...is a simple file based queue written in Ruby that uses the Ruby `File` class in standard library to push and pop items into a queue. It's not web scale but is nice for lightweight async queuing apps. - -Originally written by [daddz](http://www.github.com/daddz) and found in [this gist](https://gist.github.com/352509). Thanks, daddz! +A simple file based queue written in Ruby that uses the battle-tested [`Filelock`](https://github.com/sheerun/filelock) gem to push and pop items into a queue. It's not web scale but is nice for lightweight async queuing apps. ## Install - gem install filequeue +```ruby +gem install filequeue +``` ## Usage - queue = FileQueue.new 'queue_party.txt' - - queue.push "an item" - => true - - queue.pop - => "an item" - +```ruby +queue = FileQueue.new 'queue_party.txt' + +queue.push "an item" +# => true + +queue.pop +# => "an item" +``` + See `spec/filequeue_spec.rb` for more usage details -## Continuous Integration +## Docs + +`FileQueue` has the following class methods: + +* `push` (alias `<<`) +* `pop` +* `length` +* `empty?` +* `clear` + +## Dependencies + +Locking is delegated to the excellent [`Filelock`](https://github.com/sheerun/filelock) gem. +All of the `Filelock`'s [caveats](https://github.com/sheerun/filelock#faq) apply. + +## Limitations + +* NFS is [not supported](https://github.com/sheerun/filelock#faq) + +## Authorship -[![Build Status](http://travis-ci.org/maxogden/filequeue.png)](http://travis-ci.org/maxogden/filequeue) +* Origially written by [daddz](http://www.github.com/daddz) and found in [this gist](https://gist.github.com/352509). +* Ported to a Rubygem by [@pezra](https://github.com/pezra). diff --git a/lib/filequeue.rb b/lib/filequeue.rb index 70715e6..2e72b47 100644 --- a/lib/filequeue.rb +++ b/lib/filequeue.rb @@ -1,4 +1,5 @@ require 'timeout' +require 'filelock' class FileQueue attr_accessor :file_name, :delimiter @@ -52,25 +53,21 @@ def clear def safe_open(mode) File.open(@file_name, mode) do |file| - lock file + + lock file do yield file + end + end end # Locks the queue file for exclusive access. # - # Raises `FileLockError` if unable to acquire a lock. - # - # Return is undefined. + # Raises `Filelock::WaitTimeout` if unable to acquire a lock. + # Default timeout is 1 day def lock(file) - tries = 1000 - until tries == 0 || lock_acquired = file.flock(File::LOCK_NB|File::LOCK_EX) - tries -= 1 - Thread.pass + Filelock file do + yield file end - - (raise FileLockError, "Queue file appears to be permanently lockecd") unless lock_acquired end - - FileLockError = Class.new(Timeout::Error) end