Class: HotCell::Descriptor
- Inherits:
-
Object
- Object
- HotCell::Descriptor
- Defined in:
- lib/hot_cell/descriptors.rb
Overview
A descriptor, not a path. The cold side opens the file and passes the open descriptor, so no path a hot side chooses is ever opened by the cold side, and no path the cold side chose is ever visible to a tool.
These verify rather than merely tag, and both sides verify. An access mode is fixed at open and cannot be narrowed afterward, so a cell handed a read-write descriptor as an input cannot correct it — it can only decline the request.
Constant Summary collapse
- MODES =
{ Fcntl::O_RDONLY => "read-only", Fcntl::O_WRONLY => "write-only", Fcntl::O_RDWR => "read-write", }.freeze
Instance Attribute Summary collapse
-
#io ⇒ Object
readonly
Returns the value of attribute io.
Instance Method Summary collapse
- #close ⇒ Object
-
#fd_path ⇒ Object
The path that reads or writes this descriptor in place, without a copy onto scratch.
-
#initialize(io, scratch: nil) ⇒ Descriptor
constructor
A new instance of Descriptor.
-
#staged? ⇒ Boolean
Whether this descriptor has been given a filename on the worker's own scratch.
- #to_io ⇒ Object
Constructor Details
#initialize(io, scratch: nil) ⇒ Descriptor
Returns a new instance of Descriptor.
22 23 24 25 26 27 28 |
# File 'lib/hot_cell/descriptors.rb', line 22 def initialize(io, scratch: nil) @io = io @scratch = scratch verify_regular_file! verify_access_mode! verify_position! end |
Instance Attribute Details
#io ⇒ Object (readonly)
Returns the value of attribute io.
20 21 22 |
# File 'lib/hot_cell/descriptors.rb', line 20 def io @io end |
Instance Method Details
#close ⇒ Object
46 47 48 |
# File 'lib/hot_cell/descriptors.rb', line 46 def close io.close unless io.closed? end |
#fd_path ⇒ Object
The path that reads or writes this descriptor in place, without a copy onto scratch. /dev/fd/N
names the open file behind fd N: the worker itself may open it (libvips does), and a spawned tool
sees it too when the worker hands the fd across the exec at the same number — see Operation#run_tool.
This is what keeps a multi-gigabyte input off a small tmpfs: the descriptor is the caller's own file,
readable at any size, where staging it would be a write and RLIMIT_FSIZE bounds writes. Reopening
/dev/fd/N gives a fresh file description at offset zero, so a read here does not disturb the
descriptor the supervisor still holds.
42 43 44 |
# File 'lib/hot_cell/descriptors.rb', line 42 def fd_path "/dev/fd/#{io.fileno}" end |
#staged? ⇒ Boolean
Whether this descriptor has been given a filename on the worker's own scratch.
51 52 53 |
# File 'lib/hot_cell/descriptors.rb', line 51 def staged? !@path.nil? end |
#to_io ⇒ Object
30 31 32 |
# File 'lib/hot_cell/descriptors.rb', line 30 def to_io io end |