Class: SpoolPool::File

Inherits:
File
  • Object
show all
Defined in:
lib/spool_pool/file.rb

Overview

A class to deal with the writing of spool files. Currently uses Tempfile to do most of the heavy lifting.

Most of this file has been adapted from the Tempfile code in the Ruby 1.9.1 class library, written by yugui.

Constant Summary collapse

MAX_TRY =
10
FILE_PERMISSIONS =
0600
@@lock =
Mutex.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(basedir) ⇒ File

Creates a spool file of mode 0600 in the directory basedir, opens it with mode “w+”, and returns a SpoolPool::File object which represents the created spool file. A SpoolPool::File object can be treated just like a normal File object.



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/spool_pool/file.rb', line 82

def initialize( basedir )
  create_threadsafe_spoolname( basedir ) do |spoolname|
    @spoolfile = ::File.open( spoolname, 
                              ::File::RDWR | ::File::CREAT | ::File::EXCL, 
                              FILE_PERMISSIONS )
    @path = spoolname

    super(@spoolfile)
    # Now we have all the File/IO methods defined, you must not
    # carelessly put bare puts(), etc. after this.
  end
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



15
16
17
# File 'lib/spool_pool/file.rb', line 15

def path
  @path
end

Class Method Details

.open(*args) ⇒ Object

If no block is given, this is a synonym for new().

If a block is given, it will be passed the spool file as an argument, and the spool file will automatically be closed when the block terminates. The call returns the value of the block.



62
63
64
65
66
67
68
69
70
71
# File 'lib/spool_pool/file.rb', line 62

def self.open(*args)
  file = new(*args)
  return file unless block_given?

  begin
    yield(file)
  ensure
    file.close
  end
end

.safe_read(filename) {|data| ... } ⇒ Object

Returns the data read from the given filename, and deletes the file

before returning.

Yields the read data also to an optionally given block. If you give a block
to process your data and your code throws an exception, the file will not
be deleted and another processing of the data can be attempted in the 
future.

Yields:

  • (data)


26
27
28
29
30
31
# File 'lib/spool_pool/file.rb', line 26

def self.safe_read( filename )
  data = ::File.read( filename )
  yield data if block_given?
  ::File.unlink( filename )
  data
end

.write(basepath, data) ⇒ Object

Stores the given data in a unique file in the directory basepath. basepath can be either a file path as a String or a Pathname.

If the data can’t be written to the file (permissions, quota, I/O errors…), it will attempt to delete the file before throwing an exception.

Returns the path of the file storing the data.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/spool_pool/file.rb', line 42

def self.write( basepath, data ) 
  file = nil
  begin
    file = new( basepath.to_s )
    file.write data
  rescue
    file.unlink if file
    raise $!
  else
    file.path
  ensure
    file.close
  end
end

Instance Method Details

#closeObject

Closes the file.



103
104
105
106
# File 'lib/spool_pool/file.rb', line 103

def close
  @spoolfile.close if @spoolfile
  @spoolfile = nil
end

#openObject

Opens or reopens the file with mode “r+”.



96
97
98
99
100
# File 'lib/spool_pool/file.rb', line 96

def open
  @spoolfile.close if @spoolfile
  @spoolfile = ::File.open(@path, 'r+')
  __setobj__(@spoolfile)
end

#sizeObject Also known as: length

Returns the size of the file. As a side effect, the IO buffer is flushed before determining the size.



124
125
126
127
128
129
# File 'lib/spool_pool/file.rb', line 124

def size
  return 0 unless @spoolfile

  @spoolfile.flush
  @spoolfile.stat.size
end

Unlinks the file.



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/spool_pool/file.rb', line 109

def unlink
  # keep this order for thread safeness
  begin
    if ::File.exist?(@path)
      close unless closed?
      ::File.unlink(@path)
    end
    @path = nil
  rescue Errno::EACCES
    # may not be able to unlink on Windows; just ignore
  end
end