Module: Upkeep::Rails

Defined in:
lib/upkeep/rails.rb,
lib/upkeep/rails/replay.rb,
lib/upkeep/rails/install.rb,
lib/upkeep/rails/railtie.rb,
lib/upkeep/rails/testing.rb,
lib/upkeep/rails/delivery_job.rb,
lib/upkeep/rails/cable/channel.rb,
lib/upkeep/rails/configuration.rb,
lib/upkeep/rails/activation_token.rb,
lib/upkeep/rails/controller_runtime.rb,
lib/upkeep/rails/action_view_capture.rb,
lib/upkeep/rails/client_subscription.rb,
lib/upkeep/rails/cable/subscriber_identity.rb

Defined Under Namespace

Modules: ActionViewCapture, ActivationToken, Cable, ClientSubscription, ControllerRuntime, Install, Replay, Testing Classes: Configuration, ConfigurationError, DeliveryJob, Railtie

Constant Summary collapse

SUBSCRIPTION_IDENTITY =
"upkeep.subscription_identity"
REQUEST_CAPTURE =
"request_capture.upkeep"
DELIVERY_ENQUEUE =
"delivery_enqueue.upkeep"
DELIVERY_ENQUEUE_ERROR =
"delivery_enqueue_error.upkeep"
INTERNAL_DELIVERY_TABLES =
%w[
  upkeep_subscriptions
  upkeep_subscription_index_entries
].freeze

Class Method Summary collapse

Class Method Details

.configurationObject



30
31
32
# File 'lib/upkeep/rails.rb', line 30

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



34
35
36
# File 'lib/upkeep/rails.rb', line 34

def configure
  yield configuration
end

.deliver_changes!(changes = Runtime::ChangeLog.drain) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/upkeep/rails.rb', line 101

def deliver_changes!(changes = Runtime::ChangeLog.drain)
  changes = deliverable_changes(changes)
  return Delivery::Transport::DispatchReport.new([]) if changes.empty?

  dispatch_changes(changes)
rescue StandardError => error
  instrument_delivery_enqueue_error(changes, error)
  Delivery::Transport::DispatchReport.new([])
end

.deliver_changes_now!(changes = Runtime::ChangeLog.drain) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/upkeep/rails.rb', line 111

def deliver_changes_now!(changes = Runtime::ChangeLog.drain)
  changes = deliverable_changes(changes)
  return Delivery::Transport::DispatchReport.new([]) if changes.empty?

  batch = delivery_batch_for([changes])
  transport.deliver(batch)
end

.drain_delivery!Object



119
120
121
# File 'lib/upkeep/rails.rb', line 119

def drain_delivery!
  @delivery_dispatcher&.drain
end

.register_controller_subscription(controller, capture) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/upkeep/rails.rb', line 58

def register_controller_subscription(controller, capture)
  recorder = capture.recorder
  return unless subscription_response?(controller, capture)

  decision = Cable::SubscriberIdentity.decision_for(controller.request, recorder: recorder)
  unless recorder.reactive?
    instrument_subscription_identity(
      decision,
      registered: false,
      deopt_reason: "refused_boundary",
      refused_boundaries: recorder.refused_boundaries.map(&:reason)
    )
    return
  end

  identity = Cable::SubscriberIdentity.derive_from_request(
    controller.request,
    recorder: recorder,
    decision: decision
  )
  registration = subscription_registrar.register(
    identity: identity,
    decision: decision,
    recorder: recorder,
    signature: capture.signature,
    metadata: (decision).merge(
      path: controller.request.fullpath,
      stream_name: identity.stream_name
    )
  )
  instrument_subscription_identity(decision, registered: true, subscription: registration.subscription)

  registration
rescue Cable::UnidentifiedSubscriber => error
  instrument_subscription_identity(
    decision || Cable::SubscriberIdentity.decision_for(controller.request, recorder: recorder),
    registered: false,
    deopt_reason: "unidentified_identity",
    error: error.message
  )
  nil
end

.reset_runtime!Object



47
48
49
50
51
52
53
54
55
56
# File 'lib/upkeep/rails.rb', line 47

def reset_runtime!
  @delivery_dispatcher&.shutdown
  @delivery_dispatcher = nil
  @subscription_shape_cache&.reset
  @subscription_registrar = nil
  discard_subscription_store! if @subscriptions
  @subscriptions = build_subscription_store
  @subscriptions.reset
  @transport = Delivery::BroadcastTransport.new
end

.subscriptionsObject



38
39
40
41
# File 'lib/upkeep/rails.rb', line 38

def subscriptions
  discard_subscription_store! if @subscriptions && subscription_store_config_changed?
  @subscriptions ||= build_subscription_store
end

.transportObject



43
44
45
# File 'lib/upkeep/rails.rb', line 43

def transport
  @transport ||= Delivery::BroadcastTransport.new
end

.validate_configuration!(environment: rails_environment) ⇒ Object



123
124
125
126
127
128
# File 'lib/upkeep/rails.rb', line 123

def validate_configuration!(environment: rails_environment)
  return true unless configuration.enabled

  validate_subscription_store!(environment: environment)
  true
end