Class: HotCell::Descriptor

Inherits:
Object
  • Object
show all
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.

Direct Known Subclasses

Input, Output

Constant Summary collapse

MODES =
{
  Fcntl::O_RDONLY => "read-only",
  Fcntl::O_WRONLY => "write-only",
  Fcntl::O_RDWR   => "read-write",
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

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

#ioObject (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

#closeObject



46
47
48
# File 'lib/hot_cell/descriptors.rb', line 46

def close
  io.close unless io.closed?
end

#fd_pathObject

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.

Returns:

  • (Boolean)


51
52
53
# File 'lib/hot_cell/descriptors.rb', line 51

def staged?
  !@path.nil?
end

#to_ioObject



30
31
32
# File 'lib/hot_cell/descriptors.rb', line 30

def to_io
  io
end