Class: Cloudflare::DurableObjectState

Inherits:
Object
  • Object
show all
Defined in:
lib/homura/runtime/durable_object.rb

Overview


DurableObjectState — wraps the ‘state` object passed to the DO’s fetch(). Only exposes ‘.storage` because that is the one piece of state DO code touches >99% of the time. Future additions (blockConcurrencyWhile, waitUntil, etc.) can come here.


Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(js_state) ⇒ DurableObjectState

Returns a new instance of DurableObjectState.



441
442
443
444
# File 'lib/homura/runtime/durable_object.rb', line 441

def initialize(js_state)
  @js_state = js_state
  @storage = DurableObjectStorage.new(`#{js_state} && #{js_state}.storage`)
end

Instance Attribute Details

#js_stateObject (readonly)

Returns the value of attribute js_state.



439
440
441
# File 'lib/homura/runtime/durable_object.rb', line 439

def js_state
  @js_state
end

#storageObject (readonly)

Returns the value of attribute storage.



439
440
441
# File 'lib/homura/runtime/durable_object.rb', line 439

def storage
  @storage
end

Instance Method Details

#accept_web_socket(js_ws, tags: nil) ⇒ Object

Accept an incoming WebSocket for the Hibernation API. The DO instance transparently survives ‘webSocketMessage` / `webSocketClose` callbacks even if the isolate goes idle in between — the runtime wakes the DO, invokes the callback, and lets it hibernate again. Without `acceptWebSocket`, the DO must stay alive for the lifetime of the socket (billed per-invocation second).

‘tags` is an optional Array of string tags attached to the socket so callers can later filter `get_web_sockets(tag: …)`.



470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'lib/homura/runtime/durable_object.rb', line 470

def accept_web_socket(js_ws, tags: nil)
  js_state = @js_state
  if tags && !tags.empty?
    js_tags = `([])`
    tags.each do |t|
      ts = t.to_s
      `#{js_tags}.push(#{ts})`
    end
    `#{js_state}.acceptWebSocket(#{js_ws}, #{js_tags})`
  else
    `#{js_state}.acceptWebSocket(#{js_ws})`
  end
  nil
end

#block_concurrency_while(promise) ⇒ Object

Wrap a Promise in state.blockConcurrencyWhile(…) so that no other fetch to this DO can run until the promise resolves. Rare but critical for consistent read-modify-write against storage.



455
456
457
458
# File 'lib/homura/runtime/durable_object.rb', line 455

def block_concurrency_while(promise)
  js_state = @js_state
  `(#{js_state} && #{js_state}.blockConcurrencyWhile ? #{js_state}.blockConcurrencyWhile(async function(){ return await #{promise}; }) : #{promise})`
end

#idObject

Unique id of this DO instance as a hex String.



447
448
449
450
# File 'lib/homura/runtime/durable_object.rb', line 447

def id
  js_state = @js_state
  `(#{js_state} && #{js_state}.id && typeof #{js_state}.id.toString === 'function' ? #{js_state}.id.toString() : '')`
end

#web_sockets(tag: nil) ⇒ Object

List every WebSocket the runtime has attached to this DO via ‘acceptWebSocket`. Optional `tag:` filter forwards to `getWebSockets(tag)`.



488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'lib/homura/runtime/durable_object.rb', line 488

def web_sockets(tag: nil)
  js_state = @js_state
  js_arr =
    if tag
      ts = tag.to_s
      `(#{js_state}.getWebSockets ? #{js_state}.getWebSockets(#{ts}) : [])`
    else
      `(#{js_state}.getWebSockets ? #{js_state}.getWebSockets() : [])`
    end
  out = []
  len = `#{js_arr}.length`
  i = 0
  while i < len
    out << `#{js_arr}[#{i}]`
    i += 1
  end
  out
end