Class: Parse::LiveQuery::Subscription

Inherits:
Object
  • Object
show all
Defined in:
lib/parse/live_query/subscription.rb

Overview

Represents an active subscription to a LiveQuery. Manages event callbacks and subscription lifecycle.

Examples:

subscription = Song.subscribe(where: { artist: "Beatles" })

# Register callbacks using on() method
subscription.on(:create) { |song| puts "New song!" }
subscription.on(:update) { |song, original| puts "Updated!" }

# Or use shorthand methods
subscription.on_create { |song| puts "New song!" }
subscription.on_update { |song, original| puts "Updated!" }
subscription.on_delete { |song| puts "Deleted!" }
subscription.on_enter { |song, original| puts "Entered query!" }
subscription.on_leave { |song, original| puts "Left query!" }

# Error handling
subscription.on_error { |error| puts "Error: #{error.message}" }

# Connection events
subscription.on_subscribe { puts "Subscribed!" }
subscription.on_unsubscribe { puts "Unsubscribed!" }

# Cleanup
subscription.unsubscribe

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client:, class_name:, query: {}, fields: nil, session_token: nil) ⇒ Subscription

Create a new subscription

Parameters:

  • client (Parse::LiveQuery::Client)

    the LiveQuery client

  • class_name (String)

    Parse class name

  • query (Hash) (defaults to: {})

    query constraints (where clause)

  • fields (Array<String>, nil) (defaults to: nil)

    specific fields to watch

  • session_token (String, nil) (defaults to: nil)

    session token for authentication



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/parse/live_query/subscription.rb', line 77

def initialize(client:, class_name:, query: {}, fields: nil, session_token: nil)
  @monitor = Monitor.new
  @client = client
  @class_name = class_name
  @query = query
  @fields = fields
  @session_token = session_token
  @request_id = generate_request_id
  @state = :pending
  @callbacks = Hash.new { |h, k| h[k] = [] }

  Logging.debug("Subscription created",
                request_id: @request_id,
                class_name: @class_name,
                query_keys: @query.keys)
end

Instance Attribute Details

#class_nameString (readonly)

Returns Parse class name being subscribed to.

Returns:

  • (String)

    Parse class name being subscribed to



57
58
59
# File 'lib/parse/live_query/subscription.rb', line 57

def class_name
  @class_name
end

#clientParse::LiveQuery::Client (readonly)

Returns the LiveQuery client.

Returns:



63
64
65
# File 'lib/parse/live_query/subscription.rb', line 63

def client
  @client
end

#fieldsArray<String> (readonly)

Returns fields to watch for changes (nil = all fields).

Returns:

  • (Array<String>)

    fields to watch for changes (nil = all fields)



66
67
68
# File 'lib/parse/live_query/subscription.rb', line 66

def fields
  @fields
end

#queryHash (readonly)

Returns the query constraints (where clause).

Returns:

  • (Hash)

    the query constraints (where clause)



60
61
62
# File 'lib/parse/live_query/subscription.rb', line 60

def query
  @query
end

#request_idInteger (readonly)

Returns unique request ID for this subscription.

Returns:

  • (Integer)

    unique request ID for this subscription



54
55
56
# File 'lib/parse/live_query/subscription.rb', line 54

def request_id
  @request_id
end

#session_tokenString? (readonly)

Returns session token for ACL-aware subscriptions.

Returns:

  • (String, nil)

    session token for ACL-aware subscriptions



69
70
71
# File 'lib/parse/live_query/subscription.rb', line 69

def session_token
  @session_token
end

Instance Method Details

#confirm!Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Mark subscription as confirmed by server



242
243
244
245
246
247
248
# File 'lib/parse/live_query/subscription.rb', line 242

def confirm!
  @monitor.synchronize { @state = :subscribed }
  Logging.info("Subscription confirmed",
               request_id: @request_id,
               class_name: @class_name)
  emit(:subscribe)
end

#error?Boolean

Returns true if in error state.

Returns:

  • (Boolean)

    true if in error state



199
200
201
# File 'lib/parse/live_query/subscription.rb', line 199

def error?
  state == :error
end

#fail!(error) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Mark subscription as failed with error

Parameters:



253
254
255
256
257
258
259
260
# File 'lib/parse/live_query/subscription.rb', line 253

def fail!(error)
  @monitor.synchronize { @state = :error }
  error = SubscriptionError.new(error) if error.is_a?(String)
  Logging.error("Subscription failed",
                request_id: @request_id,
                error: error)
  emit(:error, error)
end

#handle_event(event) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Handle an incoming event from the server

Parameters:



233
234
235
236
237
238
# File 'lib/parse/live_query/subscription.rb', line 233

def handle_event(event)
  Logging.debug("Handling event",
                request_id: @request_id,
                event_type: event.type)
  emit(event.type, event.object, event.original)
end

#on(event_type) {|object, original| ... } ⇒ self

Register a callback for a specific event type

Parameters:

  • event_type (Symbol)

    :create, :update, :delete, :enter, :leave, :error, :subscribe, :unsubscribe

Yields:

  • (object, original)

    block to call when event occurs

Returns:

  • (self)


104
105
106
107
108
109
110
111
# File 'lib/parse/live_query/subscription.rb', line 104

def on(event_type, &block)
  return self unless block_given?

  @monitor.synchronize do
    @callbacks[event_type.to_sym] << block
  end
  self
end

#on_create {|Parse::Object| ... } ⇒ self

Register callback for create events

Yields:

Returns:

  • (self)


116
117
118
# File 'lib/parse/live_query/subscription.rb', line 116

def on_create(&block)
  on(:create, &block)
end

#on_delete {|Parse::Object| ... } ⇒ self

Register callback for delete events

Yields:

Returns:

  • (self)


130
131
132
# File 'lib/parse/live_query/subscription.rb', line 130

def on_delete(&block)
  on(:delete, &block)
end

#on_enter {|Parse::Object, Parse::Object| ... } ⇒ self

Register callback for enter events (object now matches query)

Yields:

Returns:

  • (self)


137
138
139
# File 'lib/parse/live_query/subscription.rb', line 137

def on_enter(&block)
  on(:enter, &block)
end

#on_error {|Exception| ... } ⇒ self

Register callback for errors

Yields:

  • (Exception)

    the error that occurred

Returns:

  • (self)


151
152
153
# File 'lib/parse/live_query/subscription.rb', line 151

def on_error(&block)
  on(:error, &block)
end

#on_leave {|Parse::Object, Parse::Object| ... } ⇒ self

Register callback for leave events (object no longer matches query)

Yields:

Returns:

  • (self)


144
145
146
# File 'lib/parse/live_query/subscription.rb', line 144

def on_leave(&block)
  on(:leave, &block)
end

#on_subscribe { ... } ⇒ self

Register callback for successful subscription

Yields:

  • called when subscription is confirmed

Returns:

  • (self)


158
159
160
# File 'lib/parse/live_query/subscription.rb', line 158

def on_subscribe(&block)
  on(:subscribe, &block)
end

#on_unsubscribe { ... } ⇒ self

Register callback for unsubscription

Yields:

  • called when unsubscribed

Returns:

  • (self)


165
166
167
# File 'lib/parse/live_query/subscription.rb', line 165

def on_unsubscribe(&block)
  on(:unsubscribe, &block)
end

#on_update {|Parse::Object, Parse::Object| ... } ⇒ self

Register callback for update events

Yields:

Returns:

  • (self)


123
124
125
# File 'lib/parse/live_query/subscription.rb', line 123

def on_update(&block)
  on(:update, &block)
end

#pending?Boolean

Returns true if pending subscription confirmation.

Returns:

  • (Boolean)

    true if pending subscription confirmation



189
190
191
# File 'lib/parse/live_query/subscription.rb', line 189

def pending?
  state == :pending
end

#stateSymbol

Current subscription state

Returns:

  • (Symbol)

    :pending, :subscribed, :unsubscribed, or :error



96
97
98
# File 'lib/parse/live_query/subscription.rb', line 96

def state
  @monitor.synchronize { @state }
end

#subscribed?Boolean

Returns true if currently subscribed.

Returns:

  • (Boolean)

    true if currently subscribed



184
185
186
# File 'lib/parse/live_query/subscription.rb', line 184

def subscribed?
  state == :subscribed
end

#to_hHash

Returns subscription info as hash.

Returns:

  • (Hash)

    subscription info as hash



263
264
265
266
267
268
269
270
271
272
273
# File 'lib/parse/live_query/subscription.rb', line 263

def to_h
  @monitor.synchronize do
    {
      request_id: request_id,
      class_name: class_name,
      query: query,
      state: @state,
      fields: fields,
    }
  end
end

#to_subscribe_messageHash

Build the subscription message to send to the server

Returns:



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/parse/live_query/subscription.rb', line 205

def to_subscribe_message
  msg = {
    op: "subscribe",
    requestId: request_id,
    query: {
      className: class_name,
      where: query,
    },
  }

  msg[:query][:fields] = fields if fields&.any?
  msg[:sessionToken] = session_token if session_token

  msg
end

#to_unsubscribe_messageHash

Build the unsubscribe message

Returns:



223
224
225
226
227
228
# File 'lib/parse/live_query/subscription.rb', line 223

def to_unsubscribe_message
  {
    op: "unsubscribe",
    requestId: request_id,
  }
end

#unsubscribeBoolean

Unsubscribe from this subscription

Returns:

  • (Boolean)

    true if unsubscribe message was sent



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/parse/live_query/subscription.rb', line 171

def unsubscribe
  @monitor.synchronize do
    return false if @state == :unsubscribed
    @state = :unsubscribed
  end

  Logging.debug("Unsubscribing", request_id: @request_id)
  client.unsubscribe(self)
  emit(:unsubscribe)
  true
end

#unsubscribed?Boolean

Returns true if unsubscribed.

Returns:

  • (Boolean)

    true if unsubscribed



194
195
196
# File 'lib/parse/live_query/subscription.rb', line 194

def unsubscribed?
  state == :unsubscribed
end