Class: HotCell::Cell
- Inherits:
-
Object
- Object
- HotCell::Cell
- Defined in:
- lib/hot_cell/cell.rb
Overview
One registered cell: where its sockets are, how long this application will wait, and which of its own exception classes to raise for each side of the permanent split.
Both socket paths are derived from one directory, so the volume mounts are mechanical rather than something to remember and the two sockets cannot end up apart.
Instance Attribute Summary collapse
-
#control_timeout ⇒ Object
readonly
Returns the value of attribute control_timeout.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#permanent ⇒ Object
readonly
Returns the value of attribute permanent.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
-
#transient ⇒ Object
readonly
Returns the value of attribute transient.
-
#transport ⇒ Object
readonly
Returns the value of attribute transport.
Instance Method Summary collapse
- #control_socket ⇒ Object
-
#describe ⇒ Object
Static, and called once at boot.
-
#directory ⇒ Object
Resolved on every call rather than at registration, which is what makes turning a path on a configuration change instead of a release.
-
#enabled? ⇒ Boolean
Unset means this path is off, and the caller runs in process exactly as it did before.
- #exception_for(failure) ⇒ Object
-
#initialize(name, dir: nil, timeout: 30, control_timeout: 5, permanent: PermanentFailure, transient: TransientFailure, on_contract_skew: nil, transport: Transport::Socket.new) ⇒ Cell
constructor
timeoutcovers work, so it is sized to clear the cell'sanswer_withinand a saturated cell reports its own verdict rather than a transport failure. - #metrics ⇒ Object
-
#report_contract_skew(error) ⇒ Object
Contract skew needs its own reporting hook because applications rescue broadly around representations, so "raise" is indistinguishable from "placeholder" and the skew is otherwise invisible.
- #work_socket ⇒ Object
Constructor Details
#initialize(name, dir: nil, timeout: 30, control_timeout: 5, permanent: PermanentFailure, transient: TransientFailure, on_contract_skew: nil, transport: Transport::Socket.new) ⇒ Cell
timeout covers work, so it is sized to clear the cell's answer_within and a saturated cell reports
its own verdict rather than a transport failure. control_timeout covers describe and metrics,
which the supervisor answers inline with no fork or queue — so it is short on purpose. Sharing one
number would give the call whose job is to say "this cell is down" the patience of a video transcode.
Both bound the answer rather than the whole call: connecting is not covered. Transport::Socket says why that is left alone.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/hot_cell/cell.rb', line 19 def initialize(name, dir: nil, timeout: 30, control_timeout: 5, permanent: PermanentFailure, transient: TransientFailure, on_contract_skew: nil, transport: Transport::Socket.new) @name = name.to_s @dir = dir @timeout = timeout @control_timeout = control_timeout @permanent = permanent @transient = transient @on_contract_skew = on_contract_skew @transport = transport verify_classification! end |
Instance Attribute Details
#control_timeout ⇒ Object (readonly)
Returns the value of attribute control_timeout.
10 11 12 |
# File 'lib/hot_cell/cell.rb', line 10 def control_timeout @control_timeout end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
10 11 12 |
# File 'lib/hot_cell/cell.rb', line 10 def name @name end |
#permanent ⇒ Object (readonly)
Returns the value of attribute permanent.
10 11 12 |
# File 'lib/hot_cell/cell.rb', line 10 def permanent @permanent end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
10 11 12 |
# File 'lib/hot_cell/cell.rb', line 10 def timeout @timeout end |
#transient ⇒ Object (readonly)
Returns the value of attribute transient.
10 11 12 |
# File 'lib/hot_cell/cell.rb', line 10 def transient @transient end |
#transport ⇒ Object (readonly)
Returns the value of attribute transport.
10 11 12 |
# File 'lib/hot_cell/cell.rb', line 10 def transport @transport end |
Instance Method Details
#control_socket ⇒ Object
52 53 54 |
# File 'lib/hot_cell/cell.rb', line 52 def control_socket File.join directory, "control.sock" end |
#describe ⇒ Object
Static, and called once at boot. The cheapest way to catch a client pointed at a cell that does not
carry the operation it wants, which is otherwise an unsupported on the first real request.
Boot must not fail when a cell does not answer. A cell that is down at app boot is a degraded deployment rather than a broken one, and an application that refuses to start because its thumbnail cell is restarting is worse than one that serves placeholders. So this warns and carries on.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/hot_cell/cell.rb', line 74 def describe return nil unless enabled? response = control(DESCRIBE) unless response.ok? HotCell.logger.warn "hotcell #{name}: #{unreachable_because response.failure}" return nil end warn_about_timeout response.result warn_about_missing_operations response.result warn_about_group_skew response.result response.result end |
#directory ⇒ Object
Resolved on every call rather than at registration, which is what makes turning a path on a configuration change instead of a release. A directory consulted once in HotCell.register would make every flip a deploy, and reverting one too.
37 38 39 40 41 |
# File 'lib/hot_cell/cell.rb', line 37 def directory return @dir.call if @dir.respond_to?(:call) @dir || (HotCell.root && File.join(HotCell.root, name)) end |
#enabled? ⇒ Boolean
Unset means this path is off, and the caller runs in process exactly as it did before.
44 45 46 |
# File 'lib/hot_cell/cell.rb', line 44 def enabled? !directory.nil? end |
#exception_for(failure) ⇒ Object
56 57 58 |
# File 'lib/hot_cell/cell.rb', line 56 def exception_for(failure) failure.permanent? ? permanent : transient end |
#metrics ⇒ Object
89 90 91 |
# File 'lib/hot_cell/cell.rb', line 89 def metrics enabled? ? control(METRICS) : nil end |
#report_contract_skew(error) ⇒ Object
Contract skew needs its own reporting hook because applications rescue broadly around representations, so "raise" is indistinguishable from "placeholder" and the skew is otherwise invisible. An application running several clients against several independently-booted cells needs to know which one skewed.
64 65 66 |
# File 'lib/hot_cell/cell.rb', line 64 def report_contract_skew(error) @on_contract_skew&.call error, self end |
#work_socket ⇒ Object
48 49 50 |
# File 'lib/hot_cell/cell.rb', line 48 def work_socket File.join directory, "work.sock" end |